ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Prototype
    Modeling/DesignPattern 2020. 2. 26. 00:41

    1. Overview

    We have a complex object that is costly to create. To create more instances of such class, we use an existing instance as our prototype. Prototype will allow us to make copies of the existing objects and save us from having to recreate objects from scratch.

    2. Description

    2.1 Implementation

    • Prototype class must implement Cloneable interface
    • Prototype Class should override the clone method and return a copy of itself
    • The method should declare CloneNotSupportedException in throws clause to give subclasses chance to decide on whether to support cloning
    • Clone method implementation should consider the deep and shallow copy and choose whichever is applicable

    2.2 Consideration

    2.2.1 Implementation

    • Pay attention to the deep copy and shallow copy of references. Immutable fields on clones save the trouble of deep copy
    • Make sure to reset the mutable state of an object before returning the prototype. It's a good idea to implement this in method to allow subclasses to initialize themselves
    • clone() method is protected in Object class and must be overridden to be public to be callable from outside the class
    • Cloneable is a "marker" interface, an indication that the class supports cloning

    2.2.2 Design

    • Porotypes are useful when you have large objects where the majority of the state is unchanged between instances and you can identify that state.
    • A prototype registry is a class wherein you can register various prototypes that other code can access to clone out instances. This solves the issue of getting access to the initial instance.
    • Prototypes are useful when working with Composite and Decorator patterns

    2.3 Pitfalls

    • Usability depends upon the number of properties in the state that are immutable or can be shallow copied. An object where the state is compromised of large number of mutable objects is complicated to clone
    • In Java, the default clone operation will only perform the shallow copy so if you need a deep copy you've to implement it.
    • Subclasses may not be to support clone and so the code becomes complicated as you have to code for situations where implementation may not support clone.

    3. Usage

    • Object.clone()

    4. Comparison with Singleton

    Prototype Singleton
    We return a copy of an instance We return same instance every time
    Some or even all of the state of instances created with prototypes can be different Since it's the same object that is returned sate is always the same

    5. Example

    abstract class GameUnit implements Cloneable {
        private Point3D position;
        public GameUnit() {
            position = Point3D.ZERO;
        }
        @Override
        public GameUnit clone() throws CloneNotSupportedException {
            GameUnit unit = (GameUnit)super.clone();
            unit.initialize();
            return unit;
        }
        protected void initialize() {
            this.position = Point3D.ZERO;
            reset();
        }
        protected abstract void reset();
        public GameUnit(float x, float y, float z) {
            position = new Point3D(x, y, z);
        }
        public void move(Point3D direction, float distance) {
            Point3D finalMove = direction.normalize();
            finalMove = finalMove.multiply(distance);
            position = position.add(finalMove);
        }
        public Point3D getPosition() {
            return position;
        }
    }
    class General extends GameUnit{
        private String state = "idle";
        public void boostMorale() {
            this.state = "MoralBoost";
        }
        @Override
        public String toString() {
            return "General "+state+" @ "+getPosition();
        }
        @Override
        public GameUnit clone() throws CloneNotSupportedException {
            throw new CloneNotSupportedException("Ganerals are unique");
        }
        @Override
        protected void reset() {
            throw new UnsupportedOperationException("Reset not supported");
        }
    }
    class Swordsman extends GameUnit {
        private String state = "idle";
        public void attack() {
            this.state = "attacking";
        }
        @Override
        public String toString() {
            return "Swordsman "+state+" @ "+getPosition();
        }
        @Override
        protected void reset() {
            state = "idle";
        }
    }
    
    public class Client {
        public static void main(String[] args) throws CloneNotSupportedException {
            Swordsman s1 = new Swordsman();
            s1.move(new Point3D(-10,0,0), 20);
            s1.attack();
    
            Swordsman s2 = (Swordsman)s1.clone();
            System.out.println(s1);
            System.out.println("Cloned swordsman"+s2);
    
        }
    }

    6. Reference

     

    'Modeling > DesignPattern' 카테고리의 다른 글

    State  (0) 2020.02.26
    Strategy  (0) 2020.02.26
    Facade  (0) 2020.02.24
    Observer  (0) 2020.02.24
    Builder  (0) 2020.02.24

    댓글

Designed by Tistory.