当前位置 博文首页 > 文章内容

    设计模式(Java语言)- 原型模式

    作者:1663631723 栏目:IT新资讯 时间:2020-05-06 9:19:26

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



         原型模式(Prototype Pattern)也有人将原型模式称为克隆模式,是属于创造型设计模式,用于创建重复的对象,提供了一种创建对象的最佳方式。原型模式需要实现Cloneable接口,来实现对象的克隆。在实际的应用中,如果应用需要反复创建相同的对象时,并且创建这个对象需要花费大量时间或者需要访问权限,比如需要读取数据库,配置文件等,如果每次创建重复对象都需要读一次数据库,那么这种方式显然并不是高效的。这时可以考虑使用原型模式来解决,提高效率,此时只需要在创建原型对象时需要读取一次数据库或配置文件等,当后面需要需要创建这个对象时只需要从原型对象克隆一个出来即可。另外,原型模式也解决了构建复杂对象时繁琐的过程,原型模式不关心对象创建的细节,用户只需要调用克隆的方法就可以创建出一个一摸一样的对象,简化创建流程。

      既然原型模式也成为克隆模式,那么对象复制过程必然用到Java的克隆方法。所以你也需要了解什么是浅克隆和深克隆。

      浅克隆

      浅克隆复制的是对象基本类型的属性,对于引用类型的属性,浅克隆置复制该应用类型的地址,因为克隆对象的被克隆对象的应用类型属性是同一个内存地址,即为同一个对象,所以在修改其中一个对象的该属性时,另一个对象的改属性也会被修改,很容易将原型对象属性修改,这也是在使用原型模式时需要注意的地方。浅克隆在代码中的实现也比较简单,Java语言中本身就已经提供相关的接口和方法了,我们在使用时只需要继承Cloneable接口,重写clone方法即可实现对象的浅克隆。代码实现如下:


    fc43efaad82c1db3d8838c3529eea3be.png

    61510af03f8dcd5754fa7e5c10c8b669.png

      测试

    public class Test {

       public static void main(String[] args) throws CloneNotSupportedException {
           Sheep test = new Sheep("test","白色");
           System.out.println(test);
           Sheep clone = (Sheep) test.clone();
           clone.setColor("黑色");
           clone.setName("test01");
           System.out.println(test);
           System.out.println(clone);
       }

    }

      运行程序时控制台打印出了:

      Sheep{name='test', color=Color{color='白色'}}

      Sheep{name='test', color=Color{color='黑色'}}

      Sheep{name='test01', color=Color{color='黑色'}}

      很显然,test对象创建时是白色的,然后用这个对象进行克隆得到 clone 实例,然后将clone 对象的颜色修改成黑色,name修改成test01,最终两个对象的颜色都变成了黑色,印证了上面说的话,对于引用类型克隆的是对象的内存地址。可能会有人好奇,String也是引用类型,为什么克隆对象修改了name属性,原型对象却没有被修改了?这是因为String是final类型,克隆过程中自然会是两个不同的内存地址。

      深克隆

      深克隆和浅克隆的区别在于,深克隆时引用类型属性复制的是该属性的值,与原型对象的拥有不同的内存地址,即两个是不同的对象,他们任意一个改属性值都不会影响到彼此。深克隆的实现方式有两种,第一种,实现Cloneable接口,重写clone方法,与浅克隆不同的是多一步将引用类型的变量再调用一次改变量的clone方法。不推荐用这种方法实现深克隆,每次修改对象的变量时都需要修改一次clone方法,违反了ocp原则。第二种,利用Java序列化与发序列化来实现,推荐使用这种方式。

      代码实现:

    7203107935401f99afe01f950c74cb00.png

    687422666d86e887146e516de1bb9378.png

    a102b08a824b23d5d1f70a0dce8c2b51.png


        注意,如果使用Java的序列化与反序列化,则改对象需要实现Serializable接口,否则会抛序列化异常。

      总结

      1、原型模式有两种实现方式,第一种利用Object类中的clone方式,重写Cloneable的clone方法,浅克隆时直接调用Object类提供的clone方式即可。深克隆则需要再调用需要被克隆的对象的clone方法,当然该对象也必须实现Cloneable接口。第二种方式是利用Java的序列化和反序列化技术,这种方式也有一个缺点是所有需要序列化的变量都必须要实现Serializable接口。

      2、原型模式的优点:提高效率;屏蔽复杂的对象构建过程,简化代码。

      3、原型模式的缺点: 1)配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。2)必须实现 Cloneable 接口或Serializable接口。

      4、原型模式的应用场景:1)资源优化场景。2)对象初始化需要大量的资源,包括数据,硬件资源等。



    文章来源:博客园

    文章链接:https://www.cnblogs.com/rainple/p/12833684.html

    如有侵权,请联系删除