原型模式
定义
原型模式(Prototype Pattern)
:用原型实例指定创建对象的种类,并且通过拷贝(克隆clone)这些原型创建新的对象。核心思想:通过克隆对象来隐藏对象的创建细节。
克隆的步骤
- 原型对象实现
Cloneable
接口 - 调用对象的
clone()
方法实现对象的克隆
UML图
基本实现代码
Prototype
:原型类
/**
* @create on 2020/8/23 16:16
* @description 原型类
* @author mrdonkey
*/
abstract class Prototype(var name: String, var list: ArrayList<String>) : Cloneable {
/**
* 提供克隆对象的方法
*/
abstract fun cloneObj(): Prototype
override fun toString(): String {
return "Prototype(name='$name',nameHashCode=${name.hashCode()}, list=$list , listHashCode=${list.hashCode()})"
}
}
ConcretePrototype1
:具体的原型类1
/**
* @create on 2020/8/23 16:17
* @description 具体原型类1
* @author mrdonkey
*/
class ConcretePrototype1(name: String, list: ArrayList<String>) : Prototype(name, list) {
override fun cloneObj(): Prototype {
return this.clone() as Prototype
}
}
Client
:客户端类
/**
* @create on 2020/8/23 16:17
* @description 客户端类
* @author mrdonkey
*/
class Client {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val obj = ConcretePrototype1("tom", arrayListOf("1", "2", "3"))
val cloneObj = obj.cloneObj()
//克隆对象修改name
println("----克隆对象修改name----")
cloneObj.name = "jeny"
println("obj-->$obj")
println("cloneObj-->$cloneObj")
//克隆对象更改list
println("----克隆对象更改list----")
cloneObj.list.add("4")
println("obj-->$obj")
println("cloneObj-->$cloneObj")
}
}
}
输出
----克隆对象修改name----
obj-->Prototype(name='tom',nameHashCode=115026, list=[1, 2, 3] , listHashCode=78481)
cloneObj-->Prototype(name='jeny',nameHashCode=3258438, list=[1, 2, 3] , listHashCode=78481)
----克隆对象更改list----
obj-->Prototype(name='tom',nameHashCode=115026, list=[1, 2, 3, 4] , listHashCode=2432963)
cloneObj-->Prototype(name='jeny',nameHashCode=3258438, list=[1, 2, 3, 4] , listHashCode=2432963)
浅复制与深复制
- 浅复制:被复制的对象的所有基本类型变量都含有与原来的对象相同的值,而所有的引用对象的引用都指向原来的对象。
- 深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
在上面的程序输出中:我们可以看到被克隆后的对象cloneObj
改变name
不会影响原来的对象的name
,但是改变了list
则导致原来的list也发生了改变,这是由于系统自带的clone
方法只实现浅复制;需要实现对象深复制,则得重写clone
方法,并在方法中手动创建一个新的list
赋值给cloneObj
实现引用类型对象的赋值。注:String
是一种特殊的引用类型,修改就会新建一个string
实例,通过输出可以看出修改前后的hashCode
不同 。
原型模式的优缺点
这里指系统自带的clone方法的优缺点
- 优点:隐藏了对象创建的细节。
- 缺点:深复制需要手动实现。