Search code examples
javaclassobjectprototypeclone

Java - class objects used instead of prototyping?


I read that you can use class objects instead of using prototype with cloning. But I don't understand what it mean to use class objects instead of that? Can anyone give an example if someone understand what would mean to use class objects instead of prototype pattern?..


Solution

  • Starting with Java 5, java.lang.Class is generic on the type of itself. This permits the class to create its instances in a type-safe way.

    When you use a prototype with cloning, you do something like this:

    interface Calculator {
        void setA(int a);
        void setB(int b);
        int compute();
        Calculator copy();
    }
    class Adder implements Calculator {
        private int a,b;
        public void setA(int a) {this.a=a;}
        public void setB(int b) {this.b=b;}
        public int compute() {return a+b;}
        public Calculator copy() {
            Adder res = new Adder();
            res.a = a;
            res.b = b;
            return res;
        }
    }
    class Multiplier implements Calculator {
        private int a,b;
        public void setA(int a) {this.a=a;}
        public void setB(int b) {this.b=b;}
        public int compute() {return a*b;}
        public Calculator copy() {
            Multiplier res = new Multiplier();
            res.a = a;
            res.b = b;
            return res;
        }
    }
    class Test {
        static void computeWithPrototype(Calculator proto) {
             Calculator calc = proto.copy();
             calc.setA(123);
             calc.setB(321);
             System.out.println(calc.compute());
        }
        public static void main(String[] args) throws Exception {
            computeWithPrototype(new Adder());
            computeWithPrototype(new Multiplier());
        }
    }
    

    Demo of the above approach on ideone.

    You can re-write it with a Class<T> instead of a copy method, like this:

    interface Calculator {
        void setA(int a);
        void setB(int b);
        int compute();
    }
    class Adder implements Calculator {
        private int a,b;
        public void setA(int a) {this.a=a;}
        public void setB(int b) {this.b=b;}
        public int compute() {return a+b;}
    }
    class Multiplier implements Calculator {
        private int a,b;
        public void setA(int a) {this.a=a;}
        public void setB(int b) {this.b=b;}
        public int compute() {return a*b;}
    }
    class Test {
        static <T extends Calculator> void computeWithClass(Class<T> calcClass)
        throws Exception {
             Calculator calc = calcClass.newInstance();
             calc.setA(123);
             calc.setB(321);
             System.out.println(calc.compute());
        }
        public static void main(String[] args) throws Exception {
            computeWithClass(Adder.class);
            computeWithClass(Multiplier.class);
        }
    }
    

    Demo of the second approach on ideone.