原型設計模式

一、比較簡單的設計模式,在項目中使用的場景很是多java

  • 經過給出一個原型對象來指明全部建立的對象的類型,而後用複製這個原型對象的辦法建立出更多同類型的對象

二、原型模式有兩種表現形式:設計模式

(1)簡單形式this

(2)登記形式prototype

  • PrototypeManager 
public class PrototypeManager {
    /**
     * 用來記錄原型的編號和原型實例的對應關係
     */
    private static Map<String,Prototype> map = new HashMap<String,Prototype>();
    /**
     * 私有化構造方法,避免外部建立實例
     */
    private PrototypeManager(){}
    /**
     * 向原型管理器裏面添加或是修改某個原型註冊
     * @param prototypeId 原型編號
     * @param prototype    原型實例
     */
    public synchronized static void setPrototype(String prototypeId , Prototype prototype){
        map.put(prototypeId, prototype);
    }
    /**
     * 從原型管理器裏面刪除某個原型註冊
     * @param prototypeId 原型編號
     */
    public synchronized static void removePrototype(String prototypeId){
        map.remove(prototypeId);
    }
    /**
     * 獲取某個原型編號對應的原型實例
     * @param prototypeId    原型編號
     * @return    原型編號對應的原型實例
     * @throws Exception    若是原型編號對應的實例不存在,則拋出異常
     */
    public synchronized static Prototype getPrototype(String prototypeId) throws Exception{
        Prototype prototype = map.get(prototypeId);
        if(prototype == null){
            throw new Exception("您但願獲取的原型尚未註冊或已被銷燬");
        }
        return prototype;
    }
}
  • 客戶端代碼:
public class Client {
    public static void main(String[]args){
        try{
            Prototype p1 = new ConcretePrototype1();
            PrototypeManager.setPrototype("p1", p1);
            //獲取原型來建立對象
            Prototype p3 = PrototypeManager.getPrototype("p1").clone();
            p3.setName("張三");
            System.out.println("第一個實例:" + p3);
            //有人動態的切換了實現
            Prototype p2 = new ConcretePrototype2();
            PrototypeManager.setPrototype("p1", p2);
            //從新獲取原型來建立對象
            Prototype p4 = PrototypeManager.getPrototype("p1").clone();
            p4.setName("李四");
            System.out.println("第二個實例:" + p4);
            //有人註銷了這個原型
            PrototypeManager.removePrototype("p1");
            //再次獲取原型來建立對象
            Prototype p5 = PrototypeManager.getPrototype("p1").clone();
            p5.setName("王五");
            System.out.println("第三個實例:" + p5);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

三、兩種形式的比較設計

  • 若是須要建立的原型對象數目較少並且比較固定的話,能夠採起第一種形式
  • 若是要建立的原型對象數目不固定的話,能夠採起第二種形式

四、利用序列化實現深度克隆code

  • 把對象寫到流裏的過程是序列化(Serialization)過程
  • 把對象從流中讀出來的過程則叫反序列化(Deserialization)過程
  • 寫到流裏的是對象的一個拷貝,而原對象仍然存在於JVM裏面
public  Object deepClone() throws IOException, ClassNotFoundException{
        //將對象寫到流裏
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        //從流裏讀回來
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }

五、優勢:對象

  • 原型模式容許在運行時動態改變具體的實現類型
  • 克隆一個原型就相似於實例化一個類

六、缺點:blog

  • 每個類都必須配備一個克隆方法
  • 配備克隆方法須要對類的功能進行通盤考慮
  • 對於全新的類來講不是很難,而對於已經有的類不必定很容易
相關文章
相關標籤/搜索