【設計模式】—— 原型模式Prototype


  前言:【模式總覽】——————————by xingoo

  模式意圖

  由於有些時候,需要在運行時指定對象時哪個類的實例,此時用工廠模式就有些力不從心了。通過原型模式就可以通過拷貝函數clone一個原有的對象,給現在的對象使用,從而創建更多的同類型的對象。

  模式結構

  【簡單原型模式】用於原型的版本不多的時候

  【登記模式的原型模式】如果原型的實現很多種版本,那么通過一個登記管理類,可以方便的實現原型的管理。

  Prototype 原型接口,定義原型的結構。

  ConcretePrototype 原型的具體實現。

  Client 使用類,創建一個原型,創建一個引用,可以隨意指定要引用的實現類。

  PrototypeManager 原型的管理器,里面含有一個Map,用來保存原型的實例對象。

  使用場景

  1 當需要在運行時指定對象的實現類時。

  2 當一個類的實例只能有集中狀態的一種時。(這個沒怎么理解)

  代碼結構

  【簡單原型模式

 1 package com.xingoo.test;
 2 
 3 interface Prototype{
 4     public Object clone();
 5 }
 6 class ConcretePrototype1 implements Prototype{
 7     public Object clone() {
 8         Prototype prototype = new ConcretePrototype1();
 9         return prototype;
10     }
11 }
12 class ConcretePrototype2 implements Prototype{
13     public Object clone(){
14         Prototype prototype = new ConcretePrototype2();
15         return prototype;
16     }
17 }
18 public class Client{
19     public static void main(String[] args){
20         Prototype p1 = new ConcretePrototype1();
21         System.out.println("p1 "+p1);
22         
23         Prototype p2 = new ConcretePrototype2();
24         System.out.println("p2 "+p2);
25         
26         Prototype prototype = (Prototype)p1.clone();
27         System.out.println("prototype "+prototype);
28         prototype = (Prototype)p2.clone();
29         System.out.println("prototype "+prototype);
30     }
31 }

  運行結果

p1 com.xingoo.test.ConcretePrototype1@1fb8ee3
p2 com.xingoo.test.ConcretePrototype2@14318bb
prototype com.xingoo.test.ConcretePrototype1@ca0b6
prototype com.xingoo.test.ConcretePrototype2@10b30a7

  【登記模式的原型模式

  1 package com.xingoo.test1;
  2 
  3 import java.util.HashMap;
  4 import java.util.Map;
  5 /**
  6  * 原型的接口
  7  * @author xingoo
  8  */
  9 interface Prototype{
 10     public Prototype clone();
 11 }
 12 /**
 13  * 具體的實現類1
 14  * @author xingoo
 15  *
 16  */
 17 class ConcretePrototype1 implements Prototype{
 18     public Prototype clone() {
 19         Prototype prototype = new ConcretePrototype1();
 20         return prototype;
 21     }
 22 }
 23 /**
 24  * 具體的實現類2
 25  * @author xingoo
 26  *
 27  */
 28 class ConcretePrototype2 implements Prototype{
 29     public Prototype clone(){
 30         Prototype prototype = new ConcretePrototype2();
 31         return prototype;
 32     }
 33 }
 34 /**
 35  * 原型的管理器
 36  * @author xingoo
 37  *
 38  */
 39 class PrototypeManager{
 40     /**
 41      * 用於保存原型的實例
 42      */
 43     private static Map<String,Prototype> map = new HashMap<String,Prototype>();
 44     /**
 45      * 靜態方法創建構造函數,避免外部類調用
 46      */
 47     private PrototypeManager(){
 48     }
 49     /**
 50      * 添加原型
 51      * @param protoName 原型的名字
 52      * @param prototype 原型的實例
 53      */
 54     public synchronized static void setPrototype(String protoName,Prototype prototype){
 55         map.put(protoName, prototype);
 56     }
 57     /**
 58      * 獲得原型
 59      * @param protoName 原型的名字
 60      * @return 返回原型的實例
 61      * @throws Exception 如果找不到,則跑出找不到異常
 62      */
 63     public synchronized static Prototype getPrototype(String protoName) throws Exception{
 64         Prototype prototype = map.get(protoName);
 65         if(prototype == null){
 66             throw new Exception("no "+protoName+" in Manager");
 67         }
 68         return prototype;
 69     }
 70     /**
 71      * 從管理器中刪除原型的實例
 72      * @param protoName 原型的名字
 73      */
 74     public synchronized static void removedPrototype(String protoName){
 75         map.remove(protoName);
 76     }
 77 }
 78 /**
 79  * 原型的使用者
 80  * @author xingoo
 81  *
 82  */
 83 public class Client {
 84     public static void main(String[] args){
 85         try{
 86             /**
 87              * 創建一種原型的實現,放入管理器中
 88              */
 89             Prototype p1 = new ConcretePrototype1();
 90             System.out.println("p1 "+p1);
 91             PrototypeManager.setPrototype("MyPrototype", p1);
 92             
 93             Prototype prototype1 = PrototypeManager.getPrototype("MyPrototype").clone();
 94             System.out.println("prototype1 "+prototype1);
 95             /**
 96              * 切換成另一種原型的實現,修改管理器中的對象
 97              */
 98             Prototype p2 = new ConcretePrototype1();
 99             System.out.println("p2 "+p2);
100             PrototypeManager.setPrototype("p1", p2);
101             
102             Prototype prototype2 = PrototypeManager.getPrototype("MyPrototype").clone();
103             System.out.println("prototype2 "+prototype2);
104             /**
105              * 注銷該原型實現,對象使用后,觀察情況
106              */
107             PrototypeManager.removedPrototype("MyPrototype");
108             
109             Prototype prototype3 = PrototypeManager.getPrototype("MyPrototype").clone();
110             System.out.println("prototype3 "+prototype3);
111             
112         }catch(Exception e){
113             e.printStackTrace();
114         }
115     }
116 }

  運行結果

p1 com.xingoo.test1.ConcretePrototype1@116ab4e
prototype1 com.xingoo.test1.ConcretePrototype1@129f3b5
p2 com.xingoo.test1.ConcretePrototype1@13f3045
prototype2 com.xingoo.test1.ConcretePrototype1@17a29a1
java.lang.Exception: no MyPrototype in Manager
    at com.xingoo.test1.PrototypeManager.getPrototype(Client.java:66)
    at com.xingoo.test1.Client.main(Client.java:109)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM