浅谈Java常见设计模式(三)

lgli

共 1150字,需浏览 3分钟

 · 2021-03-01



其实你爱我像谁

扮演什么角色我都会
快不快乐我无所谓
为了你开心我忘记了累不累



接上文的继续讲,今天需要在城市类中新增一些属性,一个城市不可能就是这么光秃秃的是吧,所以,首先在城市父类中增加了城市名称、城市人口等属性:


41042f50db3d18474a8cb23b8c0c3334.webp


接着,定义了一个教育类,教育类包含了一些基本的东西,比如学校数量、老师数量等:


57421292d61ae301a175e0322230ba4b.webp


紧接着,定义的ChongQingCityBase继承了城市父类,同时拥有Edu这个属性:


39a06d2a43deb15779b9dad60ea7c835.webp



这时候,简单测试下构建ChongQingCityBase对象出来:


86f9c862bc3212b9be6caac451fc700c.webp


这些都很简单,没有什么太大的问题。



那么接下来,有一个需求,假定这里初始化对象根据年月份构建对象,即这里可以创建“2020年1月的重庆”,然后需要创建一个“2020年2月的重庆”,这时候,一般来说,下面的代码就出来了:


abd9853f4003aab828fcf2751c7d8c96.webp


这里没有对属性做改变,是为了说明可能有些时候,有些数据,在月份之间变动不会那么大(比如学校数量),那么这个时候,如果可以直接复制出来一个1月的对象,然后直接修改一下有变化的属性,这样子,看起来,是不是可能好些?



于是基于这种复制的思想,就诞生了一种新的设计模式:原型模式



原型模式(Prototype Pattern):是指原型实例指定创建对象的种类,并通过拷贝这些原型对象创建新的对象。


调用者不需要知道任何创建细节,不调用构造方法。


原型模式适用场景:


1)、类初始化需要消耗比较多的资源

2)、调用构造方法创建对象,需要比较复杂的过程


基于此,先直接看下新的代码结构


首先定义一个接口Prototype


2b1372a80cad2dc0b141cb18742a826e.webp


接口定义了一个clone方法,然后让城市类实现这个接口,实现这个clone方法:


131f315389542588a4e6b9840cca8f68.webp


然后有一个客户端调用代码:


0b5ca5bbc7b7cd3b69e5d44186f7e4af.webp


这时候,对于创建2个月份的城市,直接就是这样了:


44ecddfb238d92a33553b6336f41667b.webp


这里,只调用了这个clone方法,即完成了新的对象的创建。


简单看下类图:


05b15383eefa7b43c1bffd2e89a15418.webp


这里一个接口Prototype,两个城市实现这个接口,同时实现clone方法。可以暴露一个客户端提供给别的方法调用,实现对象的拷贝创建。



从上面的代码,可以看到,在实现克隆方法的时候,这个Edu,也是通过新创建的对象,即被克隆的对象的引用对象也是被拷贝了一份,这时候,把这种克隆称为深克隆,与之对应的还有一个浅克隆


比如,如果是这样子,即是一个浅克隆:


f90395282a75e9f431af820c99097d8b.webp


这时候,再次运行上述的main方法。得到的就是:


d7d2d158408241722f678b9f6ba8e26a.webp


对于原型模式,JDK提供了实现Cloneable接口,实现clone方法,可快速克隆对象。


原型模式,因为比较简单,所以这里就先到这里了。


这里剩下一个比较简单的问题,对于原型模式的对象,如果是单例的,那么在使用原型模式的时候,重写了clone方法,则可能会破坏单例,这种情况下,应该如何解决呢?




关注公众号,回复“原型-单例”获取答案:



点个再看,谢谢噢!

浏览 14
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报