原型模式的定义:
原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。
浅克隆:复制对象中引用对象的引用地址,使用的是同一个引用,修改引用对象中的值会影响到所有克隆的对象。
浅克隆代码:
import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author HJD * @Description: * @date 2018/11/19 0019 10: 47 */ public class DepthPrototype implements Cloneable{ private String name; private List<String> list; private Date date; @Override protected DepthPrototype clone() throws CloneNotSupportedException { DepthPrototype depthPrototype = new DepthPrototype(); depthPrototype.setList(this.list); depthPrototype.setName(this.name); depthPrototype.setDate(this.date); return depthPrototype; } public DepthPrototype(){} public DepthPrototype(String name, List<String> list, Date date) { this.name = name; this.list = list; this.date = date; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } } |
深克隆:
import java.io.*; import java.util.List; /** * @author HJD * @Description: * @date 2018/11/18 0018 21: 30 */ public class Prototype implements Cloneable,Serializable{ private String name; private List<String> list; public Prototype(){ System.out.println("====================执行======================="); } @Override protected Prototype clone() throws CloneNotSupportedException { //序列化和反序列化实现深克隆 Prototype clonePrototype = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); byte[] bytes = bos.toByteArray(); ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); clonePrototype = (Prototype)ois.readObject(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return clonePrototype; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } } |
原型模式的优缺点:
优点:(1):当创建对象的实例较为复杂的时候,使用原型模式可以简化对象的创建过程,通过复制一个已有的实例可以提高实例的创建效率。
(2):扩展性好,由于原型模式提供了抽象原型类,在客户端针对抽象原型类进行编程,而将具体原型类写到配置文件中,增减或减少产品对原有系统都没有影响。
(3):原型模式提供了简化的创建结构,工厂方法模式常常需要有一个与产品类等级结构相同的工厂等级结构,而原型模式不需要这样,圆形模式中产品的复制是通过封装在类中的克隆方法实现的,无需专门的工厂类来创建产品。
(4):可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
缺点:(1):需要为每一个类配置一个克隆方法,而且该克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违反了开闭原则。
(2):在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重签到引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。
原型模式的适用环境:
1:创建新对象成本较大(例如初始化时间长,占用CPU多或占太多网络资源),新对象可以通过复制已有对象来获得,如果相似对象,则可以对其成员变量稍作修改。
2:系统要保存对象的状态,而对象的状态很小。
3:需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的组合状态,通过复制原型对象得到新实例可以比使用构造函数创建一个新实例更加方便。