原型设计模式(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

原文地址:https://www.cnblogs.com/dgwblog/p/9102737.html