被说了很多遍的设计模式---原型模式
来源:互联网 发布:打扮家 知乎 编辑:程序博客网 时间:2024/05/01 15:08
[把你的理性思维慢慢变成条件反射]
本文,我们讲介绍原型模式,文章主题结构与上位一致。惯例,先来看看我们示例工程的环境:
操作系统:win7 x64
其他软件:eclipse mars,jdk7
-------------------------------------------------------------------------------------------------------------------------------------
经典问题:
对象复制,克隆。思路分析:
要点一:支持浅克隆。
要点二:支持深克隆。
示例工程:
错误写法:
创建Templet.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype;public class Window {public static void main(String[] args) {Templet a = new Templet("TempletA");a.setContext("AAAAA");a.setTime("010101");a.setCompany("CompanyA");Templet b = a;b.setName("TempletB");Templet c = a;c.setName("TempletC");a.display();b.display();c.display();System.out.println(a.hashCode());System.out.println(b.hashCode());System.out.println(c.hashCode());}}
错误原因:
首先,我们先观察上面main方法输出内容:
name:TempletC,context:AAAAA,time:010101,company:CompanyAname:TempletC,context:AAAAA,time:010101,company:CompanyAname:TempletC,context:AAAAA,time:010101,company:CompanyA171982551719825517198255ABC三个对象在内存当中的地址完全相同,即代表同一个对象。(这部分概念非常基础,请各位看官牢记)。
推荐写法(1):浅克隆(值类型)
创建Prototype.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.one;public abstract class Prototype {private String id;public Prototype(String id){this.id=id;}public String getId() {return id;}public void setId(String id) {this.id = id;}public abstract Prototype Clone();}创建ConcretePrototypeA文件,具体内容如下:
package com.csdn.ingo.gof_prototype.one;public class ConcretePrototypeA extends Prototype implements Cloneable {public ConcretePrototypeA(String id) {super(id);}@Overridepublic Prototype Clone() {return (Prototype) this.clone();}@Overridepublic Object clone() {ConcretePrototypeA cpa = null;try {cpa = (ConcretePrototypeA) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return cpa;}}创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.one;public class Window {public static void main(String[] args) {ConcretePrototypeA a = new ConcretePrototypeA("ingo");ConcretePrototypeA b = (ConcretePrototypeA)a.Clone();System.out.println(a.hashCode());System.out.println(b.hashCode());}}观察输出:
114919720761102
推荐写法(2):浅克隆(引用类型)
创建Collection.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.two;import com.csdn.ingo.gof_prototype.one.ConcretePrototypeA;public class Collection implements Cloneable {private String prop1;private String prop2;public String getProp1() {return prop1;}public void setProp1(String prop1) {this.prop1 = prop1;}public String getProp2() {return prop2;}public void setProp2(String prop2) {this.prop2 = prop2;}@Overridepublic Object clone() {Collection co = null;try {co = (Collection) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return co;}}创建ConcretePrototypeA.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.two;public class ConcretePrototypeA extends Prototype implements Cloneable {private Collection collection =new Collection();public Collection getCollection() {return collection;}public void setCollection(Collection collection) {this.collection = collection;}public ConcretePrototypeA(String id) {super(id);}@Overridepublic Prototype Clone() {return (Prototype) this.clone();}@Overridepublic Object clone() {ConcretePrototypeA ca = null;try {ca = (ConcretePrototypeA) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return ca;}}创建Prototype.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.two;public abstract class Prototype {private String id;public Prototype(String id){this.id=id;}public String getId() {return id;}public void setId(String id) {this.id = id;}public abstract Prototype Clone();}创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.two;public class Window {public static void main(String[] args) {ConcretePrototypeA a = new ConcretePrototypeA("ingo");ConcretePrototypeA b = (ConcretePrototypeA)a.Clone();Collection ca = a.getCollection();ca.setProp1("a1");ca.setProp2("a2");Collection cb = b.getCollection();cb.setProp1("b1");cb.setProp2("b2");System.out.println(a.hashCode());System.out.println(b.hashCode());System.out.println(a.getCollection().hashCode());System.out.println(b.getCollection().hashCode());}}观察输出:
1396421151050423116477031164770
推荐写法(3):深克隆(专用)
创建Colleation.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.three;import com.csdn.ingo.gof_prototype.two.ConcretePrototypeA;public class Collection implements Cloneable{private String date;private String company;public String getDate() {return date;}public void setDate(String date) {this.date = date;}public String getCompany() {return company;}public void setCompany(String company) {this.company = company;}@Overridepublic Object clone(){Collection ca = null;try {ca = (Collection) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return ca;}@Overridepublic String toString() {return "Collection [date=" + date + ", company=" + company + "]";}}创建Prototype.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.three;public class Prototype implements Cloneable {private String name;private Collection work;public Prototype(String name){this.name = name;work = new Collection();}private Prototype(Collection work){this.work = (Collection)work.clone();}public String getName() {return name;}public void setName(String name) {this.name = name;}public Collection getWork() {return work;}public void setWork(Collection work) {this.work = work;}public void setWke(String date,String company){work.setDate(date);work.setCompany(company);}@Overridepublic String toString() {return "Prototype [name=" + name + ", work=" + work.toString() + "]";}@Overridepublic Object clone(){Prototype ca = new Prototype(this.work);ca.setName(name);return ca;}}创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.three;public class Window {public static void main(String[] args) {Prototype a = new Prototype("ingo");System.out.println(a.hashCode());a.setWke("01", "aaa");Prototype b = (Prototype)a.clone();System.out.println(b.hashCode());b.setWke("02", "bbb");Prototype c = (Prototype)a.clone();System.out.println(c.hashCode());c.setWke("03", "ccc");System.out.println(a.toString());System.out.println(b.toString());System.out.println(c.toString());}}
推荐写法(4):深克隆(通用)
创建Collection.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.four;import java.io.Serializable;public class Collection implements Serializable {private static final long serialVersionUID = 1L;private String date;private String company;public String getDate() {return date;}public void setDate(String date) {this.date = date;}public String getCompany() {return company;}public void setCompany(String company) {this.company = company;}@Overridepublic Object clone() {Collection ca = null;try {ca = (Collection) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return ca;}@Overridepublic String toString() {return "Collection [date=" + date + ", company=" + company + "]";}}
创建Prototype.java文件,具体内容如下;
package com.csdn.ingo.gof_prototype.four;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;public class Prototype implements Serializable {private static final long serialVersionUID = 1L;private String name;private Collection work;public Prototype(String name) {this.name = name;work = new Collection();}public String getName() {return name;}public void setName(String name) {this.name = name;}public Collection getWork() {return work;}public void setWork(Collection work) {this.work = work;}public void setWke(String date, String company) {work.setDate(date);work.setCompany(company);}@Overridepublic String toString() {return "Prototype [name=" + name + ", work=" + work.toString() + "]";}public Prototype clone() {ByteArrayOutputStream bao = new ByteArrayOutputStream();ObjectOutputStream oos;try {oos = new ObjectOutputStream(bao);oos.writeObject(this);ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());ObjectInputStream ois;ois = new ObjectInputStream(bis);return (Prototype) ois.readObject();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}}创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_prototype.four;public class Window {public static void main(String[] args) {Prototype a = new Prototype("ingo");System.out.println(a.hashCode());a.setWke("01", "aaa");Prototype b = (Prototype)a.clone();System.out.println(b.hashCode());b.setWke("02", "bbb");Prototype c = (Prototype)a.clone();System.out.println(c.hashCode());c.setWke("03", "ccc");System.out.println(a.toString());System.out.println(b.toString());System.out.println(c.toString());}}<span style="font-family:Microsoft YaHei;font-size:14px;"></span>
问题:浅克隆与深克隆的区别?
浅克隆:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。换句话说:对象成员变量中的简单类型都被复制,而引用对象类型,只复制引用,仍然指向原有对象,该对象仍然只有一份。深克隆:被复制对象的所有变量都含有与原来的对象相同的值,所有的对其他对象的引用也复制一份引用的对象。换句话说:对象成员变量中的简单类型都被复制,而引用对象类型,不止复制引用,而是将引用对象也复制一份。
模式总结:
标准UML结构图:概念总结:
原型模式:用原型实例指定创建对象的种类,并且通过开配这些原型创建新的对象。
组成部分:Prototype(原型类),ConcretePrototype(具体子类)两部分组成。
注:本文仅以Java为例说明,其他语言的原型模式,请各位看官自行学习。
反思:
应用场景:
- 创建相似的对象。
- 在上面的基础之上,创建新对象的花费资源较多,耗时较长的场景。
- 对象变化较小,并需要长时间保存时,在系统内创建备份时。
- 对象中含有组合属性,并且对象数量较少,考虑执行效率时。
优点:
- 当对象较为复杂,通过原型模式可以简化创建过程,提高创建效率。
- 扩展性好。客户端直接与抽象类进行交互,提高了双方的灵活性,扩展性。
- 提供深克隆,浅克隆两种方式供其使用。
缺点:
- 必须要为每一个对象创建一个克隆方法,克隆对象的任何改变,将直接违反“开闭原则”。
- 深克隆的过程需要IO等多个复杂过程。需要及时处理异常情况。
- 深层嵌套的克隆难于管理及实现。
-------------------------------------------------------------------------------------------------------------------------------------
至此,被说了很多遍的设计模式---原型模式 结束
参考资料:
图书:《大话设计模式》
其他博文:http://blog.csdn.NET/lovelion/article/details/7563445
- 被说了很多遍的设计模式---原型模式
- 被说了很多遍的设计模式---策略模式
- 被说了很多遍的设计模式---装饰模式
- 被说了很多遍的设计模式---代理模式
- 被说了很多遍的设计模式---外观模式
- 被说了很多遍的设计模式---观察者模式
- 被说了很多遍的设计模式---状态模式
- 被说了很多遍的设计模式---适配器模式
- 被说了很多遍的设计模式---备忘录模式
- 被说了很多遍的设计模式---组合模式
- 被说了很多遍的设计模式---迭代器模式
- 被说了很多遍的设计模式---命令模式
- 被说了很多遍的设计模式---访问者模式
- 被说了很多遍的设计模式---简单工厂模式
- 被说了很多遍的设计模式---工厂方法模式
- 被说了很多遍的设计模式---模板方法模式
- 被说了很多遍的设计模式---建造者模式
- 被说了很多遍的设计模式---抽象工厂模式
- SVN服务器搭建和使用(三)
- Kafka源码深度解析-序列10 -Server入门-Zookeeper与集群管理原理
- Spring学习之SpringMVC框架快速搭建实现用户登录功能
- MYSQL数据库CMD命令笔记整理
- OC中的富文本
- 被说了很多遍的设计模式---原型模式
- go time 包操作数据库
- HBase 常用Shell命令
- JS初级给页面添加6000个按钮
- 路由器端口映射实现外网访问本地服务器
- 算法-第四版-练习1.3.11解答
- 让Xcode8支持iPhone4
- 《C++ Primer Plus》2.7编程练习
- android Handler机制源码详解