1. Java之原型模式(Prototype Pattern)

    原型模式属于对象的创建模式。通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。这就是选型模式的用意。

原型模式要求对象实现一个可以“克隆”自身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例。这样一来,通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过new来创建。

  原型模式有两种表现形式:(1)简单形式、(2)登记形式,这两种表现形式仅仅是原型模式的不同实现。

2. 原型模式(简单形式

(1)

这种形式涉及到三个角色:

  • 客户(Client)角色:客户类提出创建对象的请求。

  • 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。

  • 具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。

(2)源代码示例:

  抽象原型角色

  1. public interface Prototype{
  2. /**
  3. * 克隆自身的方法
  4. * @return 一个从自身克隆出来的对象
  5. */
  6. public Object clone();
  7. }

 具体原型角色----ConretePrototype1

  1. public class ConcretePrototype1 implements Prototype {
  2. public Prototype clone(){
  3. //最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
  4. Prototype prototype = new ConcretePrototype1();
  5. return prototype;
  6. }
  7. }

 具体原型角色----ConretePrototype2

  1. public class ConcretePrototype2 implements Prototype {
  2. public Prototype clone(){
  3. //最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
  4. Prototype prototype = new ConcretePrototype2();
  5. return prototype;
  6. }
  7. }

客户端角色

  1. public class Client {
  2. /**
  3. * 持有需要使用的原型接口对象
  4. */
  5. private Prototype prototype;
  6. /**
  7. * 构造方法,传入需要使用的原型接口对象
  8. */
  9. public Client(Prototype prototype){
  10. this.prototype = prototype;
  11. }
  12. public void operation(Prototype example){
  13. //需要创建原型接口的对象
  14. Prototype copyPrototype = prototype.clone();
  15. }
  16. }

3. 原型模式(登记形式)

(1)

作为原型模式的第二种形式,它多了一个原型管理器(PrototypeManager)角色,该角色的作用是:创建具体原型类的对象,并记录每一个被创建的对象。

(2)源代码示例:

抽象原型角色

  1. public interface Prototype{
  2. public Prototype clone();
  3. public String getName();
  4. public void setName(String name);
  5. }

具体原型角色---ConcretePrototype1

  1. public class ConcretePrototype1 implements Prototype {
  2. private String name;
  3. public Prototype clone(){
  4. ConcretePrototype1 prototype = new ConcretePrototype1();
  5. prototype.setName(this.name);
  6. return prototype;
  7. }
  8. public String toString(){
  9. return "Now in Prototype1 , name = " + this.name;
  10. }
  11. @Override
  12. public String getName() {
  13. return name;
  14. }
  15. @Override
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. }

具体原型角色---ConcretePrototype2

  1. public class ConcretePrototype2 implements Prototype {
  2. private String name;
  3. public Prototype clone(){
  4. ConcretePrototype2 prototype = new ConcretePrototype2();
  5. prototype.setName(this.name);
  6. return prototype;
  7. }
  8. public String toString(){
  9. return "Now in Prototype2 , name = " + this.name;
  10. }
  11. @Override
  12. public String getName() {
  13. return name;
  14. }
  15. @Override
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. }

原型管理器角色保持一个聚集,作为对所有原型对象的登记,这个角色提供必要的方法,供外界增加新的原型对象和取得已经登记过的原型对象。

  1. public class PrototypeManager {
  2. /**
  3. * 用来记录原型的编号和原型实例的对应关系
  4. */
  5. private static Map<String,Prototype> map = new HashMap<String,Prototype>();
  6. /**
  7. * 私有化构造方法,避免外部创建实例
  8. */
  9. private PrototypeManager(){}
  10. /**
  11. * 向原型管理器里面添加或是修改某个原型注册
  12. * @param prototypeId 原型编号
  13. * @param prototype 原型实例
  14. */
  15. public synchronized static void setPrototype(String prototypeId , Prototype prototype){
  16. map.put(prototypeId, prototype);
  17. }
  18. /**
  19. * 从原型管理器里面删除某个原型注册
  20. * @param prototypeId 原型编号
  21. */
  22. public synchronized static void removePrototype(String prototypeId){
  23. map.remove(prototypeId);
  24. }
  25. /**
  26. * 获取某个原型编号对应的原型实例
  27. * @param prototypeId 原型编号
  28. * @return 原型编号对应的原型实例
  29. * @throws Exception 如果原型编号对应的实例不存在,则抛出异常
  30. */
  31. public synchronized static Prototype getPrototype(String prototypeId) throws Exception{
  32. Prototype prototype = map.get(prototypeId);
  33. if(prototype == null){
  34. throw new Exception("您希望获取的原型还没有注册或已被销毁");
  35. }
  36. return prototype;
  37. }
  38. }

客户端角色

  1. public class Client {
  2. public static void main(String[]args){
  3. try{
  4. Prototype p1 = new ConcretePrototype1();
  5. PrototypeManager.setPrototype("p1", p1);
  6. //获取原型来创建对象
  7. Prototype p3 = PrototypeManager.getPrototype("p1").clone();
  8. p3.setName("张三");
  9. System.out.println("第一个实例:" + p3);
  10. //有人动态的切换了实现
  11. Prototype p2 = new ConcretePrototype2();
  12. PrototypeManager.setPrototype("p1", p2);
  13. //重新获取原型来创建对象
  14. Prototype p4 = PrototypeManager.getPrototype("p1").clone();
  15. p4.setName("李四");
  16. System.out.println("第二个实例:" + p4);
  17. //有人注销了这个原型
  18. PrototypeManager.removePrototype("p1");
  19. //再次获取原型来创建对象
  20. Prototype p5 = PrototypeManager.getPrototype("p1").clone();
  21. p5.setName("王五");
  22. System.out.println("第三个实例:" + p5);
  23. }catch(Exception e){
  24. e.printStackTrace();
  25. }
  26. }
  27. }

4. 两种形式的比较

  简单形式和登记形式的原型模式各有其长处和短处。

  如果需要创建的原型对象数目较少而且比较固定的话,可以采取第一种形式。在这种情况下,原型对象的引用可以由客户端自己保存。

  如果要创建的原型对象数目不固定的话,可以采取第二种形式。在这种情况下,客户端不保存对原型对象的引用,这个任务被交给管理员对象。在复制一个原型对象之前,客户端可以查看管理员对象是否已经有一个满足要求的原型对象。如果有,可以直接从管理员类取得这个对象引用;如果没有,客户端就需要自行复制此原型对象。

5. 原型设计模式主要使用场景:
(1)类初始化需要消耗非常多的资源
(2)通过new 产生一个对象需要非常繁琐的数据准备或者访问权限

Java设计模式05:常用设计模式之原型模式(创建型模式)的更多相关文章

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

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

  2. FactoryMethod工厂方法模式(创建型模式)

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

  3. Java 23种设计模式详尽分析与实例解析之一--创建型模式

    面向对象的设计原则 常用的面向对象设计原则包括7个,这些原则并不是独立存在的,它们相互依赖.互为补充. Java设计模式 创建型模式 简单工厂模式 模式动机: 考虑一个简单的软件应用场景,一个软件系统 ...

  4. 设计模式(五):PROTOTYPE原型模式 -- 创建型模式

    1.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.适用场景 原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对 ...

  5. 设计模式之美:Creational Patterns(创建型模式)

    创建型模式(Creational Patterns)抽象了对象实例化过程. 它们帮助一个系统独立于如何创建.组合和表示它的那些对象. 一个类创建型模式使用继承改变被实例化的类. 一个对象创建型模式将实 ...

  6. 设计模式(二): BUILDER生成器模式 -- 创建型模式

    1.定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 2.适用场景 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式 ...

  7. 工厂方法模式——创建型模式02

    1. 简单工厂模式     在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...

  8. C#面向对象设计模式纵横谈——6.Prototype 原型模式(创建型模式)

    动机(Motivation) 在软件系统中,经常面临着“某些结构复杂的对象”的创建工作.由于需求的变化,这些对象经常面临着剧烈的变化,但他们却拥有比较稳定一致的接口. 如何应对这种变化?如何向“客户程 ...

  9. C#设计模式--工厂模式(创建型模式)

    一.简单工厂模式(UML类图): 核心类代码: public class Calc { public double NumberA { get; set; } public double Number ...

  10. [C#]设计模式-建造者模式-创建型模式

    介绍完工厂模式,现在来看一下建造者模式.建造者模式就是将一系列对象组装为一个完整对象并且返回给用户,例如汽车,就是需要由各个部件来由工人建造成一个复杂的组合实体,这个复杂实体的构造过程就被外部化到一个 ...

随机推荐

  1. ASP.NET MVC轻教程 Step By Step 10——模型验证

    在使用表单获取用户输入的数据时,我们必须对数据进行有效性验证,因为来自网络的信息都是不可信的.同时也要给用户即时的反馈,避免让用户感到困惑.这就涉及到数据验证的范畴. 数据验证最直接的做法是在服务器端 ...

  2. Chaperon简介

    Chaperon是一个可以把有结构的Text转换成XML.它包括一个强大的LALR(1)解析器来解析Text和一个可以用来创建XML文档的Tree builder. http://chaperon.s ...

  3. 推荐用于格式化以及高亮显示SQL文的PHP类-SqlFormatter

    有时候做开发用到SQL文的时候,由于sql文太长,很难真正看清楚这个sql文的结构. 所以需要一个工具能够自动对SQL文进行排版,在网上有幸找到这个用php写的类能处理这个任务. 原文地址是http: ...

  4. Streams and .NET

    http://www.codeguru.com/csharp/csharp/cs_data/streaming/article.php/c4223/Streams-and-NET.htm In thi ...

  5. Xcode中使用GitHub详解

    为了熟悉git命令及将写的小Demo能够管理起来方便日后查询,所以选择使用GitHub. 现在我们来说说Xcode中如何使用GitHub--- 一.当然是要先有GitHub帐号并登录了(没有的注册一个 ...

  6. 安卓天天练练(四)drawable state 属性

    今天又作茧自缚(item 写成 itme ╮(╯▽╰)╭ elipse还自动闭合了标签,来回查查查看报错,为啥点击无效呢!) 真欠抽,怪不得上班地铁上被个sb踢到脚趾头(目测有可能是同家公司的..同站 ...

  7. Jinja2学习笔记暨官方文档的翻译

    http://blog.csdn.net/lgg201/article/details/4647471 呵呵, 刚刚看完Python模板引擎Jinja2的文档, 感觉很好, 觉得动态语言真是很好.  ...

  8. Android中关于List与Json转化问题

    比如 List<String>list=new ArrayList<String>(); list.add("test1"); list.add(" ...

  9. leetcode面试准备:Multiply Strings

    1 题目 Given two numbers represented as strings, return multiplication of the numbers as a string. Not ...

  10. 最大流算法---Edmond-Karp

    这个算法是基于FF方法,就是通过不断求残余网络的增广路来增广流量,直到找不到增广路为止.注意:每次找到增广路以后都要更新原网络.EK算法通过BFS寻找源S到汇T的一条最短路径,因此时间复杂度是O(VE ...