prototype(原型)模式
图解设计模式读书笔记
-
问题引出
有时候我们需要“在不指定类名的前提下生成示例”,此时,我们就不能根据类来生成实例,而要根据现有实例来生成实例。
-
难以根据类来生成实例
若实例的生成过程太过复杂,比如用户在图形编辑器中使用鼠标制作出的图形实例,要想做出一模一样的十分困难,此时,我们就必须利用当前实例来生成一个相同的实例。
-
解耦框架与生成的实例
想让生成的实例不依赖于具体的类,此时,不指定类名来生成示例,而是事先生成一个“原型”实例,再通过复制该实例来生成新实例。
-
-
UML图
-
根据原型(Prototype)来规定需要的接口,通过具体原型(ConcretePrototype)继承原型接口来实现方法,使用者(Client)负责使用复制实例方法生成新的实例。
-
示例:
// Product.java public interface Product extends Cloneable{ void use(String s); Product createClone(); } // Manager.java public class Manager { private Map<String, Product> showcase = new HashMap<>(); public void register(String name, Product product) { showcase.put(name, product); } public Product create(String protoName) { Product p = showcase.get(protoName); return p.createClone(); } @Override public String toString() { return "Manager{" + "showcase=" + showcase + '}'; } } // MessageBox.java public class MessageBox implements Product { private char decochar; public MessageBox(char decochar) { this.decochar = decochar; } public void use(String s) { int length = s.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(""); } @Override public Product createClone() { Product product = null; try { product = (Product) clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return product; } @Override public String toString() { return "MessageBox{" + "decochar=" + decochar + '}'; } } // UnderlinePen.java public class UnderlinePen implements Product { private char ulchar; public UnderlinePen(char ulchar) { this.ulchar = ulchar; } public void use(String s) { int length = s.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; } @Override public String toString() { return "UnderlinePen{" + "ulchar=" + ulchar + '}'; } }
-
如果需要优化
UnderlinePen
和MessageBox
,将二者的createClone
提取到一个父类中。public class StringOperate implements Product { @Override public void use(String s) { } @Override public Product createClone() { Product product = null; try { product = (Product) clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return product; } }
让两个类继承此类即可。