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


另外原型模式涉及到了对象的深拷贝和浅拷贝。区别就在于:复制对象时,是否复制对象中的引用指向的内存。那篇文章里面有解释。

《图解设计模式》读书笔记3-2 Prototype模式的更多相关文章

  1. HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)

    装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...

  2. HeadFirst设计模式读书笔记--目录

    HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...

  3. Head First 设计模式读书笔记(1)-策略模式

    一.策略模式的定义 策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户. 二.使用策略模式的一个例子 2.1引出问题 某公司做了一套模拟鸭子的游戏:该游戏 ...

  4. JavaScript设计模式:读书笔记(未完)

    该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...

  5. C#设计模式学习笔记:(5)原型模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7640873.html,记录一下学习过程以备后续查用.  一.引言 很多人说原型设计模式会节省机器内存,他们说 ...

  6. 图解http读书笔记

    以前对HTTP协议一知半解,一直不清楚前端需要对于HTTP了解到什么程度,知道接触的东西多了,对于性能优化.服务端的配合和学习中也渐渐了解到了HTTP基础的重要性,看了一些大神对HTTP书籍的推荐,也 ...

  7. Java设计模式学习笔记(二) 简单工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...

  8. Java设计模式学习笔记(三) 工厂方法模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...

  9. Java设计模式学习笔记(四) 抽象工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...

  10. C#设计模式学习笔记:(23)解释器模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8242238.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第十一个模式-- ...

随机推荐

  1. IO流 -字符输入输出流,以及异常处理方法

    字符输入流 java.io.Reader: 字符输入流的顶层抽象父类 共性的成员方法: int read() 读取单个字符,并返回. int read(char[] cbuf) 将字符读入数组. ab ...

  2. C++调用C#类库函数

    最近做一个信息化三维仿真项目,基于第三方提供的虚拟引擎通过VC++2008做二次开发,其中涉及到与C#客户端的融合以及数据交互的问题, 主要是VC++需要调用C#客户端提供的类库内的接口获取C#客户端 ...

  3. dfs(找环)

    https://codeforces.com/problemset/problem/1249/B2 B2. Books Exchange (hard version) time limit per t ...

  4. js页面加载的几种方式的速度: window.onload、 $(window).load、 $(function(){})、 $(document).ready(function () {})、onload=‘asd()’

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  5. Python 中的作用域?

    Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定. 当 Python 遇到一个变量的话,它会按照这的顺序进行搜索:本地作用域(Local)--->当前作用域被嵌入的本地作用域( ...

  6. C#传特定的值,获得特定的数组排序

    一,在实际业务中,我们会有当我们传任何值进来时,我们要有特定的排序,,比如传进来的是"生物", "历史","化学", 但实际上我们需要的是& ...

  7. 03-CSS颜色、文本、字体、边框、背景

    # Css颜色,文本字体 ## css颜色表示法1.颜色名表示,比如:red 红色,gold 金色 2.16进制数值表示,比如:#ff0000 表示红色,这种可以简写成 #f00 3.RGB颜色: 红 ...

  8. 03scikit-learn非监督学习

    In [1]: from sklearn.decomposition import PCA from sklearn.datasets import load_iris pca = PCA(n_com ...

  9. css 表单头部固定

    原创 https://blog.csdn.net/q3585914/article/details/69946478 table表头和首列的表格固定-CSS实现的Table表头固定 原创 2017年0 ...

  10. Spring的AOP和IoC及隔离级别

    Spring的AOP和IoC Spring AOP:代理机制.Spring提供的自动代理机制 Spring的IoC来实组件之间的依赖关系注入, 使控制层与业务实现分离,即客户通过调用业务委托接口来调用 ...