创建型模式有五种:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。
本次内容是最后一种创建型模式—-原型模式(Prototype Pattern)。
1、概述
原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式本质是一种克隆对象的方法,其核心是重写Object中的clone方法,调用该方法可以在内存中进行对象拷贝。
原型模式可以理解为:一个对象的产生可以不由零起步,直接从一个已经具备一定雏形的对象克隆,然后再修改为生产需要的对象。
原型模式主要包含三个角色:
抽象原型类(Prototype):定义了一个抽象的克隆方法。
具体原型类(ConcretePrototyoe):实现抽象原型类(接口)定义的克隆方法,提供一个具体的克隆方法来复制自己。
客户端(Client):使用原型类的对象来实现具体的操作,即通过复制原型对象来创建新的对象。
2、优缺点
优点:
1、性能优良,Java自带的原型模式是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多。
2、可以使用深克隆方式保存对象的状态,使用原型模式将对象赋值一份并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
缺点:
1、需要为每一个类配置一个克隆方法。
2、克隆方法位于类的内部,当对已有类进行该操的时候,需要修改代码,违反了开闭原则。
3、在实现深克隆的时候需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深拷贝、浅拷贝需要运用得当。
3、实现方式
java实现
public class Test {
public static void main(String[] args) {
//创建原型对象
ConcretePrototype prototype = new ConcretePrototype();
prototype.setAge(18);
prototype.setName("Tom");
System.out.println(prototype);
//拷贝原型对象
ConcretePrototype cloneType = prototype.clone();
System.out.println(cloneType);
}
}
public interface IPrototype<T> {
T clone();
}
public class ConcretePrototype implements IPrototype {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public ConcretePrototype clone() {
ConcretePrototype concretePrototype = new ConcretePrototype();
concretePrototype.setAge(this.age);
concretePrototype.setName(this.name);
return concretePrototype;
}
@Override
public String toString() {
return "ConcretePrototype{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
在实际编码中,JDK已经帮我们实现了一个现成的API,我们只需要实现java的Cloneable接口即可。
python实现
from copy import copy, deepcopy
class Prototype:
def clone(self):
pass
def deep_clone(self):
pass
class Customer(Prototype):
def __init__(self):
self.name = ''
self.age = ''
self.address = ''
def set_name(self, name):
self.name = name
def set_age(self, age):
self.age = age
def set_address(self, address):
self.address = address
def display(self):
print("name:", self.name)
print("age:", self.age)
print("address:", self.address)
def clone(self):
return copy(self)
def deep_clone(self):
return deepcopy(self)
if __name__ == '__main__':
customer_1 = Customer()
customer_1.set_name("AAA")
customer_1.set_age("18")
customer_1.set_address("XM")
customer_2 = customer_1.clone()
customer_1.display()
print("------")
customer_2.display()
print("=============")
customer_2.set_name("BBB")
customer_2.set_address("FJ")
customer_1.display()
print("------")
customer_2.display()
print("=============")
customer_3 = customer_1.clone()
customer_3.set_name("CCC")
customer_3.set_age("7")
customer_1.display()
print("------")
customer_2.display()
print("------")
customer_3.display()
print("=============")
4、应用场景
1、性能优化场景
类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
2、安全访问场景
当某个对象对外可能是只读的,为了防止外部对这个只读对象的修改,通常可以通过返回一个对象拷贝的形式实现只读的限制。
3、一个对象多个修改者的场景
一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
设计模式是一种思想,在不同的场景合理的运可以提升整体的架构的质量。不要去生搬硬套,否则将会引起过渡设计,增加维护成本。