Java技术_每天掌握一种设计模式(006)_使用场景及简单实例(创建型:原型模式)

简介:

1.模式描述

用原型实例指定创建对象的种类,并且通过拷贝来创建新的对象。

2.模式作用

可以一定程度上解耦,消费者和对象的构造过程隔离开,对象如何构造与消费者完全无关。

可以一定程度提升效率,复杂对象的构造往往需要较长的时间(中间可能会进行复杂运算或者数据库交互),clone消耗的资源一般情况下会少很多。
可以一定程度增加代码的封装性,避免复杂的构造过程。

等等。//TODO

3.适用场景

需要创建一个复杂的、构造耗时很多的对象,且已有一个同类对象的时候。

消费者不关心对象构造过程的时候。

等等。//TODO

例如:工作流实例的重建、复杂数据实体的复制

4.模式要素

该类要支持克隆。该类要实现Cloneable接口。

已有该类的一个实例该实例作为原型进行clone。
该类的克隆方法应为深克隆。该类中除了8中基本类型(以及他们的封装类)、String(其实是浅clone,但是了解一下String就会发现其实结果和深clone一致,这里我们认为就是深clone)之外的属性均需要进行深clone;或者采用流化clone方式进行深clone。

5.类图


6.模式实例代码

原型:

[java]  view plain  copy
  1. package com.demoFound.prototype;  
  2.   
  3. import java.io.ByteArrayInputStream;  
  4. import java.io.ByteArrayOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.ObjectInputStream;  
  7. import java.io.ObjectOutputStream;  
  8. import java.io.Serializable;  
  9. import java.util.List;  
  10.   
  11. /** 
  12.  * 原型模式_原型类 
  13.  *  
  14.  * @author popkidorc 
  15.  *  
  16.  */  
  17. public class MyPrototypeProcessInstance implements Serializable, Cloneable {  
  18.     // 只有实现了Clonealbe接口,虚拟机才会认为clone是可用的,不然会抛出CloneNotSupportedException  
  19.     // 实现Serializable是为了可以进行流化clone,该clone为深clone  
  20.     private static final long serialVersionUID = 1L;  
  21.   
  22.     private String processInstanceId;  
  23.   
  24.     private String processTitle;  
  25.   
  26.     private String processDefinitionId;  
  27.   
  28.     private String processStatus;  
  29.   
  30.     private List<MyPrototypeTaskInstance> taskInstances;  
  31.   
  32.     public String getProcessInstanceId() {  
  33.         return processInstanceId;  
  34.     }  
  35.   
  36.     public void setProcessInstanceId(String processInstanceId) {  
  37.         this.processInstanceId = processInstanceId;  
  38.     }  
  39.   
  40.     public String getProcessTitle() {  
  41.         return processTitle;  
  42.     }  
  43.   
  44.     public void setProcessTitle(String processTitle) {  
  45.         this.processTitle = processTitle;  
  46.     }  
  47.   
  48.     public String getProcessDefinitionId() {  
  49.         return processDefinitionId;  
  50.     }  
  51.   
  52.     public void setProcessDefinitionId(String processDefinitionId) {  
  53.         this.processDefinitionId = processDefinitionId;  
  54.     }  
  55.   
  56.     public String getProcessStatus() {  
  57.         return processStatus;  
  58.     }  
  59.   
  60.     public void setProcessStatus(String processStatus) {  
  61.         this.processStatus = processStatus;  
  62.     }  
  63.   
  64.     public List<MyPrototypeTaskInstance> getTaskInstances() {  
  65.         return taskInstances;  
  66.     }  
  67.   
  68.     public void setTaskInstances(List<MyPrototypeTaskInstance> taskInstances) {  
  69.         this.taskInstances = taskInstances;  
  70.     }  
  71.   
  72.     @Override  
  73.     public MyPrototypeProcessInstance clone() throws CloneNotSupportedException {  
  74.         // 浅clone,对taskInstances来说仍然是引用,2个对象使用一个taskInstances  
  75.         // return (MyPrototypeProcessInstance) super.clone();  
  76.   
  77.         // 深clone,传统方式  
  78.         // MyPrototypeProcessInstance myPrototypeProcessInstanceClone =  
  79.         // (MyPrototypeProcessInstance) super  
  80.         // .clone();  
  81.         // // 非8基本类型或者String,需要通过new,然后为其copy值的方式来clone  
  82.         // List<MyPrototypeTaskInstance> myPrototypeTaskInstancesClone = new  
  83.         // ArrayList<MyPrototypeTaskInstance>();  
  84.         // for (MyPrototypeTaskInstance myPrototypeTaskInstance : this  
  85.         // .getTaskInstances()) {  
  86.         // myPrototypeTaskInstancesClone.add(myPrototypeTaskInstance.clone());  
  87.         // }  
  88.         // myPrototypeProcessInstanceClone  
  89.         // .setTaskInstances(myPrototypeTaskInstancesClone);  
  90.         // return myPrototypeProcessInstanceClone;  
  91.   
  92.         // 深clone,流化方式,需要实现Serializable  
  93.         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
  94.         ObjectOutputStream objectOutputStream;  
  95.         try {  
  96.             objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);  
  97.             // 写入流  
  98.             objectOutputStream.writeObject(this);  
  99.   
  100.             ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(  
  101.                     byteArrayOutputStream.toByteArray());  
  102.             ObjectInputStream objectInputStream = new ObjectInputStream(  
  103.                     byteArrayInputStream);  
  104.             // 读出流  
  105.             return (MyPrototypeProcessInstance) objectInputStream.readObject();  
  106.         } catch (IOException e) {  
  107.             System.out.println("==IOException==");  
  108.         } catch (ClassNotFoundException e) {  
  109.             System.out.println("==ClassNotFoundException==");  
  110.         }  
  111.         return null;  
  112.     }  
  113. }  
[java]  view plain  copy
  1. package com.demoFound.prototype;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. /** 
  6.  * 原型模式_原型类的子类 
  7.  *  
  8.  * @author popkidorc 
  9.  *  
  10.  */  
  11. public class MyPrototypeTaskInstance implements Serializable, Cloneable {  
  12.   
  13.     private static final long serialVersionUID = 1L;  
  14.   
  15.     private String taskInstanceId;  
  16.   
  17.     private String taskInstanceUser;  
  18.   
  19.     public String getTaskInstanceId() {  
  20.         return taskInstanceId;  
  21.     }  
  22.   
  23.     public void setTaskInstanceId(String taskInstanceId) {  
  24.         this.taskInstanceId = taskInstanceId;  
  25.     }  
  26.   
  27.     public String getTaskInstanceUser() {  
  28.         return taskInstanceUser;  
  29.     }  
  30.   
  31.     public void setTaskInstanceUser(String taskInstanceUser) {  
  32.         this.taskInstanceUser = taskInstanceUser;  
  33.     }  
  34.   
  35.     @Override  
  36.     public MyPrototypeTaskInstance clone() throws CloneNotSupportedException {  
  37.         return (MyPrototypeTaskInstance) super.clone();  
  38.     }  
  39. }  


消费者:

[java]  view plain  copy
  1. package com.demoFound.prototype;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. /** 
  6.  * 原型模式_消费者类 
  7.  *  
  8.  * @author popkidorc 
  9.  *  
  10.  */  
  11. public class MyPrototypeMain {  
  12.   
  13.     private static MyPrototypeProcessInstance myPrototypeProcessInstance;  
  14.   
  15.     private static void initMyPrototypeProcessInstance() {  
  16.         // 构造一个MyPrototypeProcessInstance,并为其赋值  
  17.         myPrototypeProcessInstance = new MyPrototypeProcessInstance();  
  18.         myPrototypeProcessInstance.setProcessDefinitionId("PROC001");  
  19.         myPrototypeProcessInstance.setProcessInstanceId("PROCINST00001");  
  20.         myPrototypeProcessInstance.setProcessStatus("S0102");  
  21.         myPrototypeProcessInstance.setProcessTitle("流程实例测试");  
  22.         ArrayList<MyPrototypeTaskInstance> taskInstances = new ArrayList<MyPrototypeTaskInstance>();  
  23.         MyPrototypeTaskInstance myPrototypeTaskInstance1 = new MyPrototypeTaskInstance();  
  24.         myPrototypeTaskInstance1.setTaskInstanceId("TASK00001");  
  25.         myPrototypeTaskInstance1.setTaskInstanceUser("testUser001");  
  26.         taskInstances.add(myPrototypeTaskInstance1);  
  27.         // 这里就不用clone了,直接new  
  28.         MyPrototypeTaskInstance myPrototypeTaskInstance2 = new MyPrototypeTaskInstance();  
  29.         myPrototypeTaskInstance2.setTaskInstanceId("TASK00002");  
  30.         myPrototypeTaskInstance2.setTaskInstanceUser("testUser002");  
  31.         taskInstances.add(myPrototypeTaskInstance2);  
  32.         myPrototypeProcessInstance.setTaskInstances(taskInstances);  
  33.     }  
  34.   
  35.     public static void main(String[] args) {  
  36.         initMyPrototypeProcessInstance();  
  37.           
  38.         // 开始clone  
  39.         MyPrototypeProcessInstance myPrototypeProcessInstanceClone = null;  
  40.         try {  
  41.             myPrototypeProcessInstanceClone = myPrototypeProcessInstance  
  42.                     .clone();  
  43.             // 只有实例id、状态和task的user变化  
  44.             myPrototypeProcessInstanceClone  
  45.                     .setProcessInstanceId("PROCINST00002");  
  46.             myPrototypeProcessInstanceClone.setProcessStatus("S0101");  
  47.             myPrototypeProcessInstanceClone.getTaskInstances().get(0)  
  48.                     .setTaskInstanceUser("testUser003");  
  49.             myPrototypeProcessInstanceClone.getTaskInstances().get(1)  
  50.                     .setTaskInstanceUser("testUser004");  
  51.         } catch (CloneNotSupportedException e) {  
  52.             System.out.println("CloneNotSupportedException");  
  53.         }  
  54.         // 比对结果  
  55.         System.out.println("==myPrototypeProcessInstance=="  
  56.                 + myPrototypeProcessInstance.getProcessInstanceId());  
  57.         for (MyPrototypeTaskInstance myPrototypeTaskInstance : myPrototypeProcessInstance  
  58.                 .getTaskInstances()) {  
  59.             System.out.println("==myPrototypeProcessInstance=="  
  60.                     + myPrototypeTaskInstance.getTaskInstanceUser());  
  61.         }  
  62.   
  63.         System.out.println("==myPrototypeProcessInstanceClone=="  
  64.                 + myPrototypeProcessInstanceClone.getProcessInstanceId());  
  65.         // 若是浅clone可以看到taskInstances为一个内存,只是2个对象均引用了taskInstances;若是深clone,则会为2个对象的taskInstances分别分配内存  
  66.         for (MyPrototypeTaskInstance myPrototypeTaskInstance : myPrototypeProcessInstanceClone  
  67.                 .getTaskInstances()) {  
  68.             System.out.println("==myPrototypeProcessInstanceClone=="  
  69.                     + myPrototypeTaskInstance.getTaskInstanceUser());  
  70.         }  
  71.     }  
  72. }  


原文地址:http://blog.csdn.net/ooppookid/article/details/42914173

相关文章
|
1月前
|
设计模式 缓存 安全
【设计模式】单例模式:确保类只有一个实例
【设计模式】单例模式:确保类只有一个实例
20 0
|
1月前
|
设计模式 安全 Java
【设计模式】原型模式
【设计模式】原型模式
|
2月前
|
设计模式 Java 关系型数据库
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
38 1
|
3月前
|
设计模式 数据库连接 数据库
发挥设计模式单例模式的力量:从技术到社会的转变
发挥设计模式单例模式的力量:从技术到社会的转变
|
21天前
|
设计模式 安全 Java
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
23 0
|
4月前
|
安全 Java 调度
Java基础面试,String,StringBuffer,StringBuilder区别以及使用场景
* String是final修饰的,不可变,每次操作都会产生新的对象。 * StringBuffer和StringBuilder都是在原对象上进行操作 * StringBuffer是线程安全的,StringBuilder是线程不安全的。 * StringBuffer方法是被synchronized修饰的
|
7天前
|
设计模式 Java
小谈设计模式(10)—原型模式
小谈设计模式(10)—原型模式
|
1月前
|
设计模式 Java
设计模式之原型模式
设计模式之原型模式
|
3月前
|
设计模式 安全 Java
Java设计模式—单例模式的实现方式和使用场景
那么为什么要有单例模式呢?这是因为有的对象的创建和销毁开销比较大,比如数据库的连接对象。所以我们就可以使用单例模式来对这些对象进行复用,从而避免频繁创建对象而造成大量的资源开销。
54 1
|
3月前
|
设计模式 存储 JSON
Java设计模式-原型模式
原型模式也是创建对象的一种方式,它一般用在这样的场景:系统中存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂而且耗费资源。这个时候使用原型模式的克隆方式,能够节省不少时间。比如Java 类中提供的`Object clone()`就是原型模式的应用。
30 1
Java设计模式-原型模式