[设计模式](四):建造者模式(Builder)与原型模式(Prototype)[含Kotlin深克隆实例代码]
来源:互联网 发布:国外注册域名 备案 编辑:程序博客网 时间:2024/06/05 10:35
建造者模式(Builder)与原型模式(Prototype)都是一种创建型模式。
>建造者模式(Builder)
建造者模式与工厂模式中的抽象工厂有点类似,都是关心组产品的组合问题。而其区别之处在于,建造者模式关注的是最终产品的构建即组装过程(组原料->产品),工厂模式关注的是产品的构建即创建过程(组产品工厂->生产组产品)。举个小例子:
class House{//kotlin代码 lateinit var door:String lateinit var window:String lateinit var wall:String}interface HouserBuilderInterface{ fun setDoor() fun setWindow() fun setWall() fun build():House}class BigHouseBuilder:HouseBuilderInterface{ private var house:House = House() override fun setDoor(){ house.door="铁门" } override fun setWindow(){ house.window="豪华窗户" } override fun setWall(){ house.wall="豪华墙壁" } override fun build():House{ setDoor() setWall() setWindow() return house }}当我需要建造一个贫民窟时,只需要写一个PoorBuilder实现HouseBuilderInterface,就可以了,无需修改或记忆原有的复杂构建方法,符合OCP(开闭原则)。
建造者模式的优点是:
- 封闭了内部构建细节,符合DP原则;
- 对扩展开放,对修改封闭;
- 能稳定地构建复杂的对象。
>原型模式(Prototype)
原型模式是指,将某个类当成一个原型,利用克隆、复制等方法快速的构建这个对象。举个例子,孙悟空拔一撮毛,吹毛成分身,这些分身就是原型对象。
对于JVM,直接实现Cloneable接口中的clone方法即可。由于Cloneable接口中的clone默认为protected的,有时候需要将其改写为public方便调用。
另外,对于克隆,分为浅克隆和深克隆:
- 前者克隆是不完全的,不会克隆引用,这是由于clone中使用的是 = 操作符造成的(JAVA中 = 操作符对对象赋值做引用操作);
- 后者克隆是完全的。
class Prototype:Cloneable{//实现克隆接口 var a = 7 //这是一个属性 var h=BigHouseBuilder().build() //这是一个对象引用,具体代码见上 //重写克隆方法,默认浅克隆 public override fun clone(): Any { return super.clone() }}fun main(arg:Array<String>){ val p=Prototype() println(p.a) // 输出 7 println(p.h.wall) // 输出"豪华墙壁" val p2=p.clone()//由p克隆一个p2 p.a++ // 改变原型中的值 p.h.wall="这是原对象的墙" //改变原型中引用对象的属性值 if (p2 is Prototype) { println(p2.a) // 输出 7 ,克隆成功 println(p2.h.wall)// 输出原型对象中对House的引用对象的wall值,输出"这是原对象的墙" ,克隆失败 }}那么要怎么做到深克隆呢?答:手动对对象引用进行一个new操作:(把上面代码中的clone方法重写成下面这个样子)
public override fun clone(): Any { val c=super.clone() if (c is Prototype)c.h = BigHouseBuilder().build()//手动new一个对象引用出来 return c }
然而,这样并不算完全的深克隆,因为如果此时House对象的值是变化过的,我这里只是build出来一个新的,仍然是默认值,显然不符合要求因此,可以考虑用序列化和反序列化的方法进行克隆:
public fun deepClone(): Any{ val bos = ByteArrayOutputStream() val oos = ObjectOutputStream(bos) oos.writeObject(this)//写出序列化后的对象 val bis = ByteArrayInputStream(bos.toByteArray()) val ois = ObjectInputStream(bis) return ois.readObject()//读入反序列化后的对象,并返回 }此时要记得,对Prototype和House都要进行序列化:
class House:Serializable{ val ID:Long = 1L}class Prototype:Cloneable,Serializable{ val ID:Long = 1L }
另外,为什么用clone而不是copy?经过测试,clone方法比copy方法的开销是copy的一半,但当原型中对象引用过多且做了深克隆时,clone的开销接近copy方法。
那么原型模式究竟有什么用呢?比如,做游戏设计时,做分身技能,用于快速地复制一些Monster;或是面对几个对象间差别不大,只有略微几个属性值不同时,单独构建一个工厂或是Builder显然冗余,此时用原型直接克隆出来稍微改改就非常合适。>>[设计模式]OOP设计模式·目录
阅读全文
1 0
- [设计模式](四):建造者模式(Builder)与原型模式(Prototype)[含Kotlin深克隆实例代码]
- 设计模式实例与代码:Prototype模式
- 设计模式之四 --- 建造(Builder)模式
- 设计模式之四 --- 建造(Builder)模式
- 设计模式之四 --- 建造(Builder)模式
- 设计模式之四 --- 建造(Builder)模式
- Builder 建造者模式 Prototype 原型模式 Singleton 单一模式 UML图
- 设计模式实例与代码:Builder模式
- 设计模式---建造者模式(Builder)模式
- 【怎样写代码】对象克隆 -- 原型模式(四):浅克隆与深克隆
- 设计模式之(四)--建造者模式(builder)
- JAVA设计模式四---Builder(建造者模式)
- JAVA设计模式四:---Builder(建造者模式)
- 设计模式(四)——建造者模式(Builder)
- JAVA--建造者模式(Builder)--设计模式四
- 设计模式系列(四)建造者模式Builder
- Kotlin 设计模式-建造者
- Net设计模式实例之建造者模式(Builder Pattern)
- python网络爬虫与信息采取之下载存储数据(一)-----下载储存媒体文件模板
- dubbo 优雅停机源码分析
- 第一章:1.2.2系统分类(二)
- spring boot实现定时任务
- RegexPattern
- [设计模式](四):建造者模式(Builder)与原型模式(Prototype)[含Kotlin深克隆实例代码]
- bool型判断一年是否是闰年
- python编程从入门到实践 10-6 加法运算
- jQuery中$(function() {});
- sql语句修改某个字段的部分内容
- easy-ui中表格中动态添加checkbox,和全选事件和判断选中事件
- ZigBee TI ZStack CC2530 2.2 ZigBee规范版本
- gradle加速下载jar包
- 解决浏览器记住密码输入框的问题