6.1 Prototype 模式

  通常,我们使用 new 方式来生成类的实例。
  new Something();
  像这样 new 的方式来生成实例时,是必须指定类名的。但是,有时也需要 “不指定类名的前提下生成实例” 的需求。
  (1) 对象种类繁多,无法将他们整合到一个类中时
  此时需要要编写多个类文件来处理。
  (2) 难以根据类生成实例时
  生成实例的过程太过复杂,很难根据类来生成实例。通常,在想生成一个和之前用户通过操作所创建出来的实例完全一样的实例时候,会事先将用户通过操作所创建出的实例保存起来,然后在需要时通过复制来生成新的实例。
  (3) 想解耦框架与生成的实例时
  想要让生成实例的框架不依赖于具体的类。这时,不能指定类名来生成实例,要事先 “注册” 一个 “原型” 实例,然后通过复制该实例来生成新的实例。
  这里,我们将了解不根据类来生成实例,而是根据实例来生成新实例的 Prototype 模式。Prototype 有 “原型” “模型” 的意思。在设计模式中是指根据实例原型、模型来生成新的实例。

6.2 示例程序

  作用:将字符串放入方框中显示出来或是加上下划线显示出来。
  Product 接口和 Manager 类属于 framework 包,负责复制实例。虽然 Manager 类会调用 createClone 方法,但是对于具体要复制哪个类一无所知。不过,只要是实现了 Product 接口的类,调用它的 createClone 方法就可以复制出新的实例。

Prototype 示例程序的类图

|| Product 接口

  Product 接口是复制功能的接口。该接口继承了 java.lang.Cloneable 接口。实现了该接口的类的实例可以调用 clone 方法来自动复制实例。
  use 方法是用于 “使用” 的方法,由子类实现。
  createClone 方法用于复制实例的方法。

/**
* 声明了 use 和 createClone 接口
*/
public interface Product extends Cloneable{void use(String s);Product createClone();
}
|| Manager 类

  Manager 类使用 Product 接口来实现复制实例。
  showcase 字段保留了 “名字” 和 “实例” 之间的对应关系。
  register 方法将接收到的 “名字” 和 “Product 接口” 注册到 showcase 中。
  注意,在 Manager 中并没有写明具体的类名,仅仅使用了 Product 这个接口名。这是非常重要的,因为一旦在类中使用到了别的类名,就意味着该类与其他类紧密地耦合在了一起。

/**
* 调用 createClone 方法复制实例的类
*/
public class Manager {private HashMap<String, Product> showCase = new HashMap<>();public void register(String name, Product product) {showCase.put(name, product);}public Product create(String name) {Product product = showCase.get(name);return product.createClone();}
}
|| MessageBox 类

  MessageBox 类实现了 Product 接口。decochar 字段中保存的是像装饰方框那样环绕着字符串的字符。use 方法会使用 decochar 保存的字符把要显示的字符串框起来。
  createClone 方法用于复制自己,内部所调用的 clone 方法是 Java 语言中定义的方法。在进行复制时,原来实例中的字段也会被复制到新的实例中。注意因为我们实现了 Cloneable 接口,否则在运行时会抛出 CloneNotSuppotedException 异常。

public class MessageBox implements Product {private char decochar;public MessageBox(char decochar) {this.decochar = decochar;}/*** ********** * Hello ** ********** @param s*/@Overridepublic void use(String s) {int length = s.toCharArray().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();}@Overridepublic Product createClone() {try {return (Product)clone();} catch (CloneNotSupportedException e) {System.out.println("不支持的 Clone 类型");}return null;}
}
|| UnderlinePen 类

  UnderlinePen 类的实现与 MessageBox 几乎完全相同。

public class UnderlinePen implements Product {private char ulchar;public UnderlinePen(char ulchar) {this.ulchar = ulchar;}/*** "Hello"*  ~~~~~* @param s*/@Overridepublic void use(String s) {int len = s.toCharArray().length;System.out.println("\"" + s + "\"");System.out.print(" ");for (int i = 0; i < len; i++) {System.out.print(ulchar);}System.out.println();}@Overridepublic Product createClone() {try {return (Product) clone();} catch (CloneNotSupportedException e) {System.out.println("不支持的 Clone 类型");}return null;}
}
|| Main 类

  Main 类首先生成了 Manager 的实例。然后,在实例中注册了 UnderlinePen 的实例以及 MessageBox 实例。

public class Main {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, world.");Product p2 = manager.create("warning box");p2.use("Hello, world.");Product p3 = manager.create("slash box");p3.use("Hello, world.");}
}

  输出:

"Hello, world."
~~~~~~~~~~~~~
*****************
* Hello, world. *
*****************
/
/ Hello, world. /
/

6.3 Prototype 模式中的登场角色

  • Prototype (原型)
      Product 角色负责定义用于复制现有实例来生成新实例的方法。在示例程序中,由 Product 接口扮演此角色。
  • ConcretePrototype(具体的原型)
      ConcretePrototype 角色负责实现复制现有实例并生成新实例的方法。在示例程序中,由 MessageBox 类和 UnderlinePen 类扮演此角色。
  • Client(使用者)
      Client 角色负责使用复制实例的方法生成新的实例。在示例程序中,由 Manager 类扮演此角色。

Prototype 模式的类图

6.4 拓展思路的要点

|| 类名是束缚吗

  面向对象编程的目标之一,即 “作为组件复用”。
  在代码中出现要使用的类的名字并非总是坏事。不过,一旦在代码中出现要使用的类的名,就无法与该类分离开来,也就无法实现复用。虽然可以通过替换源代码或是改变类名来解决这个问题,但以 Java 来说,重要的是当手边只有 class 文件时,该类能否被复用。即使没有 Java 文件也能复用该类才是关键。
  当多个类必须紧密结合时,代码中出现这些类的名字是没有问题的。但是如果那些需要被独立出来作为组件复用的类的名字出现在代码中,那就会出现问题。

Prototype (原型)模式相关推荐

  1. JavaScript 面向对象 (prototype 原型模式)

    一. JavaScript 设计思想 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览 ...

  2. Prototype原型模式(创建型模式)

    1.原型模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只有一 ...

  3. Prototype 原型模式

    一.意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.(Specify the kinds of objects to create using a prototypical in ...

  4. prototype原型模式

    /** * 原型模式 Prototype * 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象 */ 需求: public class Resume { /** * 要求:一个简历类,必须 ...

  5. C++设计模式-Prototype原型模式

    作用: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言相关,在C+ ...

  6. c语言 prototype_(创建型模式)Prototype——原型模式

    1.意图 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.核心思想 通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象. ...

  7. 面向对象设计模式纵横谈:Prototype 原型模式(笔记记录)

       有一段时间没写东西了,今天继续把没写完的设计模式写完,今天这堂课是创建型设计模式的最后一堂课,原型设计模式,它同样也是解决了对象在创建的过程中的解耦合的情况,面对变化使代码更稳定,更准确的说是使 ...

  8. 【设计模式】之 Prototype 原型模式

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.C ...

  9. 精读《设计模式 - Prototype 原型模式》

    Prototype(原型模式) Prototype(原型模式)属于创建型模式,既不是工厂也不是直接 New,而是以拷贝的方式创建对象. 意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的 ...

  10. 设计模式 - Prototype 原型模式

    微信搜索[三太子敖丙]关注这个贪财好色的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. 前言 在设计模 ...

最新文章

  1. 连接网络计算机密码错误,局域网电脑连接提示网络错误怎么解决
  2. [BZOJ1799][Ahoi2009]self 同类分布(数位dp)
  3. ns3 入门案例2:third.cc
  4. php thumb 生成缩略图
  5. python 画线置顶_绘制分支[置顶] python学习~递归函数
  6. 理解为什么要使用Ioc
  7. vue-cli 2.x 项目优化之:引入本地静态库文件
  8. android关机铃声代码,android系统添加关机铃声
  9. 权限设计-系统登录用户权限设计
  10. 使用idea在serviceImpl中配置radis
  11. html5+css3笔记整理
  12. java国际化程序_Java 国际化标准程序实现
  13. 解决:syntax error at line xxx: `<<‘ unmatched
  14. 将HQL语句转为sql语句
  15. 摘自《机器视觉技术》陈兵旗—机器视觉的功能与精度
  16. 转:中国人世界观的变化
  17. 二、MT8168 KeyPad驱动指南
  18. java基础-数组-案例练习-检测一个字符串是否为回文 回文字符串是指正着读和反着读该字符串都是相同拼写
  19. 佳能Canon PIXMA MG2550 打印机驱动
  20. Ansible 企业级自动化运维平台开发实战

热门文章

  1. 如何将VMWare Workstation 虚拟机文件导入到ESX Server——VMX 转成 OVF 格式
  2. 北邮2018计算机院考研复试机试上机题解+结果统计
  3. Wine QQ 安装
  4. 《雄安新区2022年大数据研究报告》发布啦
  5. PowerDesigner反向工程
  6. 医院信息化PACS系统源码(影像阅片、报告模板、三维重建)
  7. SecureCRT 屏幕行数
  8. sarscape5.6.2 结果在arcgis中制图(1简洁版)
  9. 2022T电梯修理考试试题及模拟考试
  10. C++数组(数组定义方式、数组名作用、数组地址)