《图解设计模式》读书笔记3-2 Prototype模式
Prototype(原型)模式的由来
创建一个实例,可以关键字new创建。但有时候,我们需要在不指定类名的前提下生成实例,比如:
需要处理的对象种类繁多,无法整合到一个类里面,如果分别作为一个类,类的数量又太多了。
很难通过代码生成实例:比如用户在画图工具中画出来的图形实例,如果用代码创建的话是非常困难的。我们可以先保存起来,需要时通过复制生成实例。
想解耦框架和生成的实例时:不指定类名来生成实例,而是事先注册一个原型实例,通过复制该实例来生成新实例。比如打印机,不需要知道具体的文档内容,到需要的时候复印就行了,复印多少次都没问题。
类图
代码
Product接口,继承Cloneable接口,实现Product接口的类都可以使用clone方法进行实例的复制。
use方法表示怎么使用,具体怎么用,由子类来实现。
createClone是用于复制实例的方法。
public interface Product extends Cloneable {
public abstract void use(String s);
public abstract Product createClone();
}
Manager类,需要生成对象的类可以调用Manager类的create方法复制实例
public 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();
}
}
具体要进行对象复制的类
public class MessageBox implements Product {
private char decochar;
public MessageBox(char decochar) {
this.decochar = decochar;
}
@Override
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("");
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product)clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
public class UnderlinePen implements Product {
private char ulchar;
public UnderlinePen(char ulchar) {
this.ulchar = ulchar;
}
@Override
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("");
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product)clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
如何使用
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");
Product p2 = manager.create("Warning box");
p2.use("hello");
Product p3 = manager.create("Slash box");
p3.use("hello");
}
//结果
"hello"
~~~~~
*********
* hello *
*********
/////////
/ hello /
/////////
角色
Prototype(原型)
此角色负责定义用现有实例复制新实例的方法。对应于本例中的Product接口。
ConcretePrototype(具体的原型)
负责实现原型的方法。对应于本例中的MessageBox和UnderlinePen
Client(使用者)
负责使用原型的方法复制生成新的实例。
模式的类图
我的理解
说实话,由于经验所限,我不太能体会的到这个模式的好处。
看看示例代码:代码实现的功能类似于一个文本编辑器,可以对文本进行下划线(UnderlinePen)和提示(MessageBox)两个操作。在一篇文章里面,可能有很多很多个下划线和提示操作。每一个都创建对象,创建过程简单还好,复杂的话那代码量就太恐怖了。所以搞一个原型对象,用到了就复制就行了。
这只是我能理解的其中一个好处,更多内容可以看看这篇文章https://www.cnblogs.com/chenssy/p/3313339.html
另外原型模式涉及到了对象的深拷贝和浅拷贝。区别就在于:复制对象时,是否复制对象中的引用指向的内存。那篇文章里面有解释。
最新文章
- windows下搭建scrapywindows 7 (64) + python 3.5 (64)
- MEF入门之不求甚解,但力求简单能讲明白(二)
- 初步了解JSONP
- Java之重载与覆盖
- Linux下MySQL不能远程访问
- java web基础2HTTP协议知识点总结
- cmd扩展路径
- 可以binidng属性的属性【项目】
- 关于新的man版本出现“无法解析 /usr/share/man/zh_CN/man1/ls.1.gz: 没有那个文件或目录“
- OGG 单表初始化操作步骤
- C#.NET学习笔记7--11---算术运算符,变量赋值,变量的交换,布尔表达式1,布尔表达式2
- 前端 MVC 变形记
- 译者序(Core Data 应用开发实践指南)
- HTML5 使用 JS 生成二维码,带头像
- AVPass技术分析:银行劫持类病毒鼻祖BankBot再度来袭,如何绕过谷歌play的杀毒引擎?
- CSS使用position:sticky 实现粘性布局
- [APIO 2009] Atm
- Excel如何固定表头,任意一行
- 2018/03/11 每日一个Linux命令 之 top
- Golang之实现一个负载均衡算法(随机,轮询)
热门文章
- [Git] 013 远程仓库篇 第零话 使用前的一些配置
- SUST_ACM_2019届暑期ACM集训热身赛题解
- dfs(枚举)
- <;meta>;标签中http-equiv属性的属性值X-UA-Compatible详解
- python实现一个简单的网络聊天程序
- C# String的几种比较方法对比(Compare,CompareTo, CompareOrdinal、Equals)
- 03scikit-learn非监督学习
- alert(1) to win 12
- alert(1) to win 8
- 外媒:Apple面临着印度iPhone的停用