原型模式(通过复制生成实例)
用处
根据现有的实例生成新的实例
在以下情况下,我们不能根据类来实现实例,而根据现有的实例来生成新的实例
- 对象种类繁多,无法将他们整合到一个类中
- 难以根据类生成实例时
- 想解耦框架与生成的实例时
角色
- Prototype
该角色负责定义用于复制现有实例来生成新实例的方法。 - ConcretePrototype
该角色负责实现复制现有实例并生成新实例的方法 - Client
该角色负责使用复制实例的方法并生成新实例的方法
类图
可以看出原型模式还是非常简单的,只需要客户端通过原型接口调用具体原型的实现类中的createClone方法就即可。
举例
public class Main {
public static void main(String[] args) {
Manager manager = new Manager();
UnderlinePen upen = new UnderlinePen('~');
MessageBox mbox = new MessageBox('*');
MessageBox sbox = new MessageBox('/');
manager.register("strong message",upen);
manager.register("warning box",mbox);
manager.register("slash box",sbox);
Product p1 = manager.create("strong message");
p1.use("Hello world");
Product p2 = manager.create("warning box");
p2.use("Hello world");
Product p3 = manager.create("slash box");
p3.use("Hello world");
}
}
//Prototype角色
interface Product extends Cloneable{
void use(String use);
Product createClone();
}
class Manager{
private HashMap showcase = new HashMap();
public void register(String name,Product proto){
showcase.put(name,proto);
}
public Product create(String protoname){
Product p = (Product)showcase.get(protoname);
return p.createClone();
}
}
//concretePrototype角色
class MessageBox implements Product{
private char decochar;
public MessageBox(char decochar){
this.decochar = decochar;
}
public void use(String s){
int length = s.getBytes().length;
for(int i = 0 ; i < length + 4;i++){
System.out.print(decochar);
}
System.out.println("");
System.out.println(decochar+" "+s+" "+decochar);
for(int i = 0 ; i < length + 4 ;i++){
System.out.print(decochar);
}
System.out.println("");
}
public Product createClone(){
Product p = null;
try{
p = (Product)clone();
}catch (CloneNotSupportedException e){
e.printStackTrace();
}
return p;
}
}
//如需扩展只需要多加一个类
//ConcretePrototype角色
class UnderlinePen implements Product{
private char ulchar;
public UnderlinePen(char ulchar){
this.ulchar = ulchar;
}
public void use(String s){
int length = s.getBytes().length;
System.out.println("\""+s+"\"");
System.out.print(" ");
for(int i = 0 ; i < length ;i++){
System.out.print(ulchar);
}
System.out.println("");
}
public Product createClone(){
Product p = null;
try{
p = (Product)clone();
}catch (CloneNotSupportedException e){
e.printStackTrace();
}
return p;
}
}
Manager类的create函数中返回克隆对象,使用后发现该对象与原对象完全相同。
总结
- 符合开闭原则
- 用于克隆一个与原对象完全相同的对象
- clone方法是浅拷贝,如果需要克隆复杂对象,则需要使用深拷贝,用递归调用clone方法,或者序列化与反序列化实现