JAVA设计模式学习9——原型模式

2019-03-07 23:46|来源: 网络

原型模式(prototype)它是指通过给定一个原型对象来指明所要创建的对象类型,然后复制这个原型对象的办法创建出同类型的对象。原型模式也属于创建模式。

我们先来看一下原型模式的模型:

原型模型涉及到三个角色:

客户角色(client):客户端提出创建对象的请求;

抽象原型(prototype):这个往往由接口或者抽象类来担任,给出具体原型类的接口;

具体原型(Concrete prototype):实现抽象原型,是被复制的对象;

模拟代码如下:

  1. package prototype;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-7-18下午10:40:49

  6. *描述:抽象接口

  7. */  

  8. public interface Prototype extends Cloneable {

  9.    public Object clone();  

  10. }  

  1. package prototype;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-7-18下午10:41:39

  6. *描述:实现接口

  7. */  

  8. public class ConcretePrototype implements Prototype {

  9.    @Override  

  10.    public Object clone() {  

  11.        Prototype temp = null;  

  12.        try {  

  13.            temp = (Prototype) super.clone();  

  14.            return temp;  

  15.        } catch (CloneNotSupportedException e) {  

  16.            // TODO Auto-generated catch block  

  17.            e.printStackTrace();  

  18.        }  

  19.        return temp;  

  20.    }    

  21. }  

  1. package prototype;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-7-18下午10:41:14

  6. *描述:客户端

  7. */  

  8. public class Client {  

  9.    private Prototype prototype;  

  10.    /**

  11.     * @param args

  12.     */  

  13.    public static void main(String[] args) {  

  14.        Client c = new Client();  

  15.        c.prototype = c.getNewPrototype(new ConcretePrototype());

  16.    }  

  17.    /**

  18.     *

  19.     * @param prototype

  20.     * @return

  21.     */  

  22.    public Prototype getNewPrototype(Prototype prototype){  

  23.        return (Prototype) prototype.clone();  

  24.    }  

  25. }  


以上代码简单描述了原型模式的实现,说到这里估计很多人要跳了,因为说到原型模式不能不说的问题是java的深拷贝和浅拷贝,那下面我们就来讨论下深拷贝和浅拷贝。

浅拷贝:是指拷贝引用,实际内容并没有复制,改变后者等于改变前者。

深拷贝:拷贝出来的东西和被拷贝者完全独立,相互没有影响。


引用一哥们举的例子(博客地址忘记了)

有一个人叫张三,人们给他取个别命叫李四,不管张三还是李四都是一个人,张三胳膊疼,李四也是一个样的不爽。这个就是浅拷贝,只是个别名而已。

同样还是有一个人叫张三,通过人体克隆技术(如果法律允许)得到一个李四,这个李四和被克隆的张三完全是两个人,张三就是少个胳膊,李四也不会感到疼痛。这个就是深拷贝。

java语言提供Cloneable接口,在运行时通知虚拟机可以安全的在这个类上使用clone()方法,通过这个方法可以复制一个对象,但是Object并没有实现这个接口,所以在拷贝是必须实现此标识接口,否则会抛出CloneNotSupportedException。

但是clone()方法出来的默认都是浅拷贝,如果要深拷贝,那么可以考虑自己编写clone方法,但是深度很难控制,编写这个clone方法也不是最佳方案,还有个比较好的方案就是串行化来实现,代码如下:


  1. public Object deepClone(){  

  2.    ByteArrayOutputStream bos = new ByteArrayOutputStream();  

  3.    ObjectOutputStream oos = new ObjectOutputStream(bos);  

  4.    oos.writeObject(this);  

  5.    ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray())  

  6.    ObjectInputStream ois = new ObjectInputStream(bis);  

  7.    return ois.readObject();  

  8. }  

这样就可以实现深拷贝,前提是对象实现java.io.Serializable接口。

注意:除了基本数据类型外,其他对象默认拷贝都是浅拷贝,String类型是个例外,虽然是基本类型,但是也是浅拷贝,这个跟它实际在java内存存储情况有关。超出了设计模式讨论范围,大家可自行查看相关资料。


转自:http://alaric.iteye.com/blog/1909960

相关问答

更多
  • 其实我相信你做了3年的java一定了解你所说的设计模式和反射机制在程序早已用过了的把,只是自己平时没注意;设计模式主要是用项目管理,让人看起来通俗易懂.反射机制用到的地方呢也比较多,在用properties和JFreeChart等地方都用到.
  • java教程:关于Java设计模式关于原型模式(Prototype) IT信息技术http://www.52ij.com/jishu/ 首先需要弄清楚什么叫原型模式,或者说为什么要有原型模式,运用它会给我们带来什么或能解决什么问题?原型模式(Prototype)同抽象工厂模式同属于创建型模式,它主要关注于大量相同或相似对象的创建问题,应用原型模式就是先需要一个原对象,然后通过对原对象进行复制(克隆),来产生一个与原对象相同或相似的新对象。注意这里所说的对象相同不是指复制出来的副本对象与原对象是同一个对象,相 ...
  • 你是准备学习使用 还是说研究它的底层实现机制这些东西? 如果只是使用 可以暂时不了解这些 ,你也没有这么多精力来了解这么多 你先将框架中的东西用熟练 然后再去了解这些也不迟 spring 的 IOC aop hibernate的 延迟加载 缓存 ,mvc这些学习都需要学习 其实你学习不学习这几个框架都可以对设计模式进行学习 设计模式在日常的版本开发中好处很多 而且在面试的时候 考官也会问设计模式方面的知识
  • 原型模式本身就是用来解决系统中需要创建一个新对象,而要创建的对象和系统中已有对象存在诸多重复的属性和方法,如果再去new一个新的空对象,就需要对新的对象进行赋值初始化操作,这会增加不必要的工作量。 使用克隆的好处就是可以将已有对象的属性和方法直接复制给新的对象。
  • 装饰器模式可能是最直接使用的,并且是扩展具体对象功能和/或特性的好方法。 以下是一些阅读材料: Head First Design Patterns - CH3 pdf 仅供参考,夫妻必须拥有学习和参考设计模式,无论您选择何种语言: 1) 头部设计模式 2) 企业应用程序架构的模式 3) 设计模式:可重用面向对象软件的元素 和网站: 1) DoFactory 2) StackOverflow设计模式新手 还有其他一些,我将不得不挖掘它们。 The Decorator Pattern is probably ...
  • 没有内置任何内容可以为您执行深层克隆。 我相信你可以根据新的RTTI编写一个深层克隆,但我认为这是一个不重要的工作量。 如果您处理的是足够简单的类型,那么它可以正常工作,但是您很容易遇到严重的挑战。 例如,我的头顶上: 一些对象组需要按照特定的顺序创建。 不应该克隆某些类的某些成员,例如引用计数。 你如何识别RTTI? 你如何处理单身人士? 需要设置哪些外部参考? 假设你克隆了一个通常由工厂创建的对象。 如果该工厂对其创建的对象持有引用,那么背后可能会破坏您的设计。 你可以通过定义一个基本的Clone()方 ...
  • 当你有同样的东西,但使用不同的方法来实现它时,接口是很棒的。 用你的例子,假设我们有这样的东西...... public interface ILongRangeWeapon { void Fire(); } 现在,我们假设您有这些课程...... public class Rifle : ILongRangeWeapon { public void Fire() { // Pull the trigger } } public class Nuclear ...
  • 您可以执行与以前完全相同的操作,只需在doSomething方法中执行: doSomething: function () { var instance = this; $('.some-class').each(function () { $(this).click(instance.doClick); }); }, 这种方法与prototype无关,它只是如何使用嵌套函数管理上下文。 因此,当原型(方法)上的函数具有嵌套函数时,如果要在嵌套作用域中访问它 ...