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

Java技术_每天掌握一种设计模式(001)_设计模式概念及分类

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

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

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

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

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


1.模式描述

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

2.模式作用

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

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

等等。//TODO

3.适用场景

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

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

等等。//TODO

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

4.模式要素

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

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

5.类图

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

6.模式实例代码

原型:

package com.demoFound.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.List;

/**
 * 原型模式_原型类
 * 
 * @author popkidorc
 * 
 */
public class MyPrototypeProcessInstance implements Serializable, Cloneable {
	// 只有实现了Clonealbe接口,虚拟机才会认为clone是可用的,不然会抛出CloneNotSupportedException
	// 实现Serializable是为了可以进行流化clone,该clone为深clone
	private static final long serialVersionUID = 1L;

	private String processInstanceId;

	private String processTitle;

	private String processDefinitionId;

	private String processStatus;

	private List taskInstances;

	public String getProcessInstanceId() {
		return processInstanceId;
	}

	public void setProcessInstanceId(String processInstanceId) {
		this.processInstanceId = processInstanceId;
	}

	public String getProcessTitle() {
		return processTitle;
	}

	public void setProcessTitle(String processTitle) {
		this.processTitle = processTitle;
	}

	public String getProcessDefinitionId() {
		return processDefinitionId;
	}

	public void setProcessDefinitionId(String processDefinitionId) {
		this.processDefinitionId = processDefinitionId;
	}

	public String getProcessStatus() {
		return processStatus;
	}

	public void setProcessStatus(String processStatus) {
		this.processStatus = processStatus;
	}

	public List getTaskInstances() {
		return taskInstances;
	}

	public void setTaskInstances(List taskInstances) {
		this.taskInstances = taskInstances;
	}

	@Override
	public MyPrototypeProcessInstance clone() throws CloneNotSupportedException {
		// 浅clone,对taskInstances来说仍然是引用,2个对象使用一个taskInstances
		// return (MyPrototypeProcessInstance) super.clone();

		// 深clone,传统方式
		// MyPrototypeProcessInstance myPrototypeProcessInstanceClone =
		// (MyPrototypeProcessInstance) super
		// .clone();
		// // 非8基本类型或者String,需要通过new,然后为其copy值的方式来clone
		// List myPrototypeTaskInstancesClone = new
		// ArrayList();
		// for (MyPrototypeTaskInstance myPrototypeTaskInstance : this
		// .getTaskInstances()) {
		// myPrototypeTaskInstancesClone.add(myPrototypeTaskInstance.clone());
		// }
		// myPrototypeProcessInstanceClone
		// .setTaskInstances(myPrototypeTaskInstancesClone);
		// return myPrototypeProcessInstanceClone;

		// 深clone,流化方式,需要实现Serializable
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		ObjectOutputStream objectOutputStream;
		try {
			objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
			// 写入流
			objectOutputStream.writeObject(this);

			ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
					byteArrayOutputStream.toByteArray());
			ObjectInputStream objectInputStream = new ObjectInputStream(
					byteArrayInputStream);
			// 读出流
			return (MyPrototypeProcessInstance) objectInputStream.readObject();
		} catch (IOException e) {
			System.out.println("==IOException==");
		} catch (ClassNotFoundException e) {
			System.out.println("==ClassNotFoundException==");
		}
		return null;
	}
}
package com.demoFound.prototype;

import java.io.Serializable;

/**
 * 原型模式_原型类的子类
 * 
 * @author popkidorc
 * 
 */
public class MyPrototypeTaskInstance implements Serializable, Cloneable {

	private static final long serialVersionUID = 1L;

	private String taskInstanceId;

	private String taskInstanceUser;

	public String getTaskInstanceId() {
		return taskInstanceId;
	}

	public void setTaskInstanceId(String taskInstanceId) {
		this.taskInstanceId = taskInstanceId;
	}

	public String getTaskInstanceUser() {
		return taskInstanceUser;
	}

	public void setTaskInstanceUser(String taskInstanceUser) {
		this.taskInstanceUser = taskInstanceUser;
	}

	@Override
	public MyPrototypeTaskInstance clone() throws CloneNotSupportedException {
		return (MyPrototypeTaskInstance) super.clone();
	}
}


消费者:

package com.demoFound.prototype;

import java.util.ArrayList;

/**
 * 原型模式_消费者类
 * 
 * @author popkidorc
 * 
 */
public class MyPrototypeMain {

	private static MyPrototypeProcessInstance myPrototypeProcessInstance;

	private static void initMyPrototypeProcessInstance() {
		// 构造一个MyPrototypeProcessInstance,并为其赋值
		myPrototypeProcessInstance = new MyPrototypeProcessInstance();
		myPrototypeProcessInstance.setProcessDefinitionId("PROC001");
		myPrototypeProcessInstance.setProcessInstanceId("PROCINST00001");
		myPrototypeProcessInstance.setProcessStatus("S0102");
		myPrototypeProcessInstance.setProcessTitle("流程实例测试");
		ArrayList taskInstances = new ArrayList();
		MyPrototypeTaskInstance myPrototypeTaskInstance1 = new MyPrototypeTaskInstance();
		myPrototypeTaskInstance1.setTaskInstanceId("TASK00001");
		myPrototypeTaskInstance1.setTaskInstanceUser("testUser001");
		taskInstances.add(myPrototypeTaskInstance1);
		// 这里就不用clone了,直接new
		MyPrototypeTaskInstance myPrototypeTaskInstance2 = new MyPrototypeTaskInstance();
		myPrototypeTaskInstance2.setTaskInstanceId("TASK00002");
		myPrototypeTaskInstance2.setTaskInstanceUser("testUser002");
		taskInstances.add(myPrototypeTaskInstance2);
		myPrototypeProcessInstance.setTaskInstances(taskInstances);
	}

	public static void main(String[] args) {
		initMyPrototypeProcessInstance();
		
		// 开始clone
		MyPrototypeProcessInstance myPrototypeProcessInstanceClone = null;
		try {
			myPrototypeProcessInstanceClone = myPrototypeProcessInstance
					.clone();
			// 只有实例id、状态和task的user变化
			myPrototypeProcessInstanceClone
					.setProcessInstanceId("PROCINST00002");
			myPrototypeProcessInstanceClone.setProcessStatus("S0101");
			myPrototypeProcessInstanceClone.getTaskInstances().get(0)
					.setTaskInstanceUser("testUser003");
			myPrototypeProcessInstanceClone.getTaskInstances().get(1)
					.setTaskInstanceUser("testUser004");
		} catch (CloneNotSupportedException e) {
			System.out.println("CloneNotSupportedException");
		}
		// 比对结果
		System.out.println("==myPrototypeProcessInstance=="
				+ myPrototypeProcessInstance.getProcessInstanceId());
		for (MyPrototypeTaskInstance myPrototypeTaskInstance : myPrototypeProcessInstance
				.getTaskInstances()) {
			System.out.println("==myPrototypeProcessInstance=="
					+ myPrototypeTaskInstance.getTaskInstanceUser());
		}

		System.out.println("==myPrototypeProcessInstanceClone=="
				+ myPrototypeProcessInstanceClone.getProcessInstanceId());
		// 若是浅clone可以看到taskInstances为一个内存,只是2个对象均引用了taskInstances;若是深clone,则会为2个对象的taskInstances分别分配内存
		for (MyPrototypeTaskInstance myPrototypeTaskInstance : myPrototypeProcessInstanceClone
				.getTaskInstances()) {
			System.out.println("==myPrototypeProcessInstanceClone=="
					+ myPrototypeTaskInstance.getTaskInstanceUser());
		}
	}
}


点击进入ooppookid的博客

你可能感兴趣的:(Java技术_每天掌握一种设计模式(006)_使用场景及简单实例(创建型:原型模式)...)