1. Prototype模式
通过clone来生成实例。正如描述的一样Prototype就是通过克隆一个对象来生成新的对象。我们可以想象我们自己一般在什么时候会使用克隆:当要复制一大段复杂的内容时;方便;当你以及创建了一个文档希望得到一个新的一模一样的文档时等。
所以我可以总结出Prototype模式的以下几个作用:
- 需要产生一个复杂的实例对象,如果新建,还需要处理一系列复杂属性改动才能达到要求,这样通过一个已有的实例去产生一个新的实例,会更加方便。
- 当你使用某种框架时,例如Spring,想让生成实例的框架不依赖于具体的类。
- …
通俗的说Prototype模式就是使用一个已有的实例通过clone来产生一个新的实例。
1.1 Prototype模式的类图
登场角色:
-
Prototype(原型)
定义了复制现有实例来生成新实例的方法 -
ConcretePrototype(具体的原型)
实现了Prototype角色中的克隆生成新实例的方法 -
Client(使用者)
使用了复制实例的方法以产生新的实例
1.2 实例程序
名字 | 说明 |
---|---|
Product | 声明了createClone接口 |
Manager | 调用createClone方法生成实例的类 |
MessageBox | Product的一个实现类 |
UnderlinePen | Product的一个实现类 |
Main | 测试类 |
在这儿不进一步考虑浅克隆和深克隆(将会在其他博文中具体讲解),仍然保持将设计与实现分开的思想。
uml类图
Product类
package xin.ajay.prototype.framework;
public interface Product extends Cloneable {
public abstract void use(String s);
public abstract Product createClone();
}
Manager类
package xin.ajay.prototype.framework;
import java.util.HashMap;
import java.util.Map;
public class Manager {
private Map<String,Product> products = new HashMap<>();
public void register(String name,Product proto){
products.put(name,proto);
}
public Product create(String name){
Product product = products.get(name);
return product.createClone();
}
}
MessageBox类
package xin.ajay.prototype.impl;
import xin.ajay.prototype.framework.Product;
public class MessageBox implements Product {
private char c;
public MessageBox(char c){
this.c = c;
}
@Override
public void use(String msg) {
int length = msg.getBytes().length;
for (int i = 0; i < length + 4; i++) {
System.out.print(c);
}
System.out.println();
System.out.println(c + " " + msg + " " + c);
for (int i = 0; i < length + 4; i++) {
System.out.print(c);
}
System.out.println();
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
UnderlinePen类
package xin.ajay.prototype.impl;
import xin.ajay.prototype.framework.Product;
public class UnderlinePen implements Product {
private char c;
public UnderlinePen(char c){
this.c = c ;
}
@Override
public void use(String s) {
System.out.println("\"" + s +"\"");
System.out.print(" ");
for (int i = 0; i < s.getBytes().length; i++) {
System.out.print(c);
}
System.out.println();
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
Main类
package xin.ajay.prototype.impl;
import xin.ajay.prototype.framework.Manager;
import xin.ajay.prototype.framework.Product;
public class Main {
public static void main(String[] args) {
Manager manager = new Manager();
manager.register("Strong mesaage", new UnderlinePen('‾'));
manager.register("warning box",new MessageBox('*'));
manager.register("slash box", new MessageBox('/'));
Product strong_mesaage = manager.create("Strong mesaage");
Product warning_box = manager.create("warning box");
Product slash_box = manager.create("slash box");
strong_mesaage.use("hello");
warning_box.use("hello");
slash_box.use("hello");
}
}
鸣谢:
GoF《设计模式》和结城浩的《图解设计模式》