原型設計模式(prototype


# 什么是原型設計模式

> 這里與軟件工程中的原型開發模式有那么一點類似的地方,我們首先需要構建出一個原型,這個原型可以在現實開發中抽象出來的具體類型,但是這個類型與具體的類又不同,需要抽取公共的部分,通過構建管理器,實現創建不同需要的類型,

### 考慮使用原型設計模式的三種情況

 第一種情況是需要處理的對象太多,如果將它們分別作為一個類,必須要編寫很多個類文件難以根據類生成實例時

 第二種情況是生成實例的過程太過復雜,很難根據類來生成實例。例如,我們假設這里有一個實例,即表示用戶在圖形編輯器中使用鼠標制作出的圖形的實例。想在程序中創建這樣的實例是常困難的,通常,在想生成一個和之前用戶通過操作所創建出的實例完全一樣的實例的時候,我們會事先將用戶通過操作所創建出的實例保存起來,然后在需要時通過復制來生成新的實例想解藕框架與生成的實例時

 第三種情況是想要讓生成實例的框架不依賴於具體的類。這時,不能指定類名來生成實例,而要事先注冊一個原型實例,然后通過復制該實例來生成新的實例。

### 類接口表關系表

類名

描述

framework

 manager

調用createclone

framework

 product

 聲明use createclone

naN

 rectangle

 具體打印矩形

nan

triangle

具體打印三角形

 

 Prototype 是由product擔任的

 ConcreteProtopyte 實現賦值新實例的方法 由具體的你需要的角色來擔任

 Client 通過調用createclone 創建新的實例,由Manger類扮演這個角色

### uml

 

 

 use 在接口中是交給子類去實現的

 createclone 創建具體的對象

- code  framework

 

 1 package base.prototype.framework;
 2 
 3  
 4 
 5 /**
 6 
 7  * @program: DesignPatterns
 8 
 9  * @description: 聲明use, createclone具體復用
10 
11  * @author: Mr.Dai
12 
13  * @create: 2018-05-28 21:28
14 
15  **/
16 
17 public interface Product extends Cloneable {
18 
19  
20 
21      public abstract void use(int len);
22 
23      public abstract Product createClone();
24 
25 }

 

 

 1 import java.util.HashMap;
 2 
 3  
 4 
 5 /**
 6 
 7  * @program: DesignPatterns
 8 
 9  * @description: 產生具體的類,維護多重對象
10 
11  * @author: Mr.Dai
12 
13  * @create: 2018-05-28 21:31
14 
15  **/
16 
17 public class Manager {
18 
19     private HashMap<String,Product> warehouse=new HashMap<>();
20 
21  
22 
23     public void registers(String name,Product product){
24 
25         warehouse.put(name,product);
26 
27     }
28 
29  
30 
31     public Product createObj(String name){
32 
33         Product product = warehouse.get(name);
34 
35         return product.createClone();
36 
37     }
38 
39 }

 

- code domain 具體的實現的類

 

  1 /**
  2 
  3  * @program: DesignPatterns
  4 
  5  * @description: 打印矩形
  6 
  7  * @author: Mr.Dai
  8 
  9  * @create: 2018-05-28 21:38
 10 
 11  **/
 12 
 13 public class Rectangle implements Product {
 14 
 15  
 16 
 17     private char mark = '*';
 18 
 19  
 20 
 21     public Rectangle(char mark) {
 22 
 23         this.mark = mark;
 24 
 25     }
 26 
 27  
 28 
 29     public Rectangle() {
 30 
 31     }
 32 
 33  
 34 
 35     @Override
 36 
 37     public void use(int len) {
 38 
 39         for (int i = 0; i < len; i++) {
 40 
 41             if(i==0||i==len-1){
 42 
 43                 for (int k = 0; k < len; k++) System.out.print(mark);
 44 
 45             }else{
 46 
 47                 System.out.print('*');
 48 
 49                 for (int j = 0; j < len-2; j++) {
 50 
 51                     System.out.print(' ');
 52 
 53                 }
 54 
 55                 System.out.print('*');
 56 
 57             }
 58 
 59             System.out.println();
 60 
 61         }
 62 
 63     }
 64 
 65  
 66 
 67     @Override
 68 
 69     public Product createClone() {
 70 
 71         Product product = null;
 72 
 73         try {
 74 
 75             product = (Product) clone();
 76 
 77         } catch (CloneNotSupportedException e) {
 78 
 79             e.printStackTrace();
 80 
 81         }
 82 
 83         return product;
 84 
 85     }
 86 
 87 }
 88 
 89  
 90 
 91 import base.prototype.framework.Product;
 92 
 93  
 94 
 95 /**
 96 
 97  * @program: DesignPatterns
 98 
 99  * @description: 打印三角形
100 
101  * @author: Mr.Dai
102 
103  * @create: 2018-05-28 21:47
104 
105  **/
106 
107 public class Triangle implements Product {
108 
109  
110 
111     @Override
112 
113     public void use(int len) {
114 
115         for (int i = 0; i < len; i++) {
116 
117             for (int j = i; j < len; j++) {
118 
119                 System.out.print(' ');
120 
121             }
122 
123  
124 
125             for (int j = 0; j < 2*i + 1; j++) {
126 
127                 System.out.print('*');
128 
129             }
130 
131             System.out.println();
132 
133         }
134 
135     }
136 
137  
138 
139     @Override
140 
141     public Product createClone() {
142 
143         Product product=null;
144 
145         try {
146 
147             product=(Product)clone();
148 
149         }catch (CloneNotSupportedException e){
150 
151             e.printStackTrace();
152 
153         }
154 
155         return product;
156 
157     }
158 
159 }
160 
161  

 

-  結果

 

 

 

### 需要說明的是

> 面向對象的根本思想是作為組件復用:一旦出現的類名字就無法與該類區分開來,也就無法實現復用,如果不替換源代碼 以java來說,重要的是當只有class文件的時候還能不能被復用,即使沒有java文件也能夠復用才是關鍵,

>要注意在頂層product 接口聲明 集成的java.lang.cloneable。的接口是稱之為標記接口 只要這樣下面雇用的具體的類才能調用具體的clone方法才不會拋出異常,,說明了 實現了cloneable 接口的實例是可以進行調用clone方法進行復制的,返回是一個新的實例,(clone內部所進行的處理是分配與要復制的實例同樣大小的內存空間,是一盒字段復制 也很稱 淺拷貝;也就是說 如在類中存在 數組 那么拷貝 只會拷貝數組的引用,不會對數組進行正的復制。如果你需要一個新的引用那么你需要 重寫clone ,但是不要忘記 調用superclone

 

### 相關設計模式

  •  Flyweight

 prototype可以生成一個與當前實例相同的的實例,使用Flyweight 模式可以在不同的地方使用同一個實例。

  •  Memento

提供保存當前實例狀態,實現撤銷與快照功能

  •  Composite Decorator模式

如果需要動態創建復雜的結構的實例,可以用prototype作為clone

  •  Command

 復制Command模式中出現的額命令時,可以使用Prototype

 


免責聲明!

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



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