Prototype Pattern
2017/04/11
Quote
-
Prototype design pattern is used in scenarios where application needs to create a number of instances of a class, which has almost same state or differs very little.[2]
-
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.[1]
-
当创建给定类的实例很昂贵或很复杂时使用原型模式。—《Head First设计模式》
Participants
- Prototype : the prototype of actual object.
- Prototype registry : This is used as registry service to have all prototypes accessible using simple string parameters.
- Client : Client will be responsible for using registry service to access prototype instances.
Practice
定义一个细胞Prototype,split()
方法表示出分裂(clone)出一个新细胞。
interface Cell extends Cloneable {
Cell split() throws CloneNotSupportedException;
}
分别定义动物细胞和植物细胞
public class AnimalCell implements Cell {
@Override
public AnimalCell split() throws CloneNotSupportedException {
return (AnimalCell) super.clone();
}
}
public class PlantCell implements Cell {
@Override
public PlantCell split() throws CloneNotSupportedException {
return (PlantCell) super.clone();
}
}
写一个CellRegestry,可以根据不同的细胞类型返回对应的新细胞实例。(有种简单工厂的味道吧?)
public class CellRegestry {
public enum CellType {
ANIMAL, PLANT
}
private static Map<CellType, Cell> prototypes = new HashMap<>();
static {
prototypes.put(CellType.ANIMAL, new AnimalCell());
prototypes.put(CellType.PLANT, new PlantCell());
}
public static Cell getCell(CellType type) throws CloneNotSupportedException {
// 先根据type获取对应实例,然后clone之
return prototypes.get(type).split();
}
}
Client使用:
public class Client {
public static void main(String[] args) {
try {
AnimalCell cell1 = (AnimalCell) CellRegestry.getNewCell(CellType.ANIMAL);
PlantCell cell2 = (PlantCell) CellRegestry.getNewCell(CellType.PLANT);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
Attention
- Cloneable接口是个标记接口(tagging/marker interface),它没有方法。标记接口的唯一目的是可以用instanceof进行类型检查。
- 使用 Prototype Pattern 的其中一个原因是因为 clone 比 new 要快,但其实这已经过时了,参考[3]
- 可以使用工厂方法模式或者复制构造函数来替代该模式[4]。
- 需要注意
深拷贝
和浅拷贝
的问题。