`

设计模式-原型模式(Prototype)- 面馆里的菜单

阅读更多

   自己CSDN blog 上回收来的,以后都集中到这里了。

 

参考资料

《c#技术揭密》

《设计模式-可复用面向对象软件的基础》

《java与模式》

http://blog.csdn.net/beautyispower/  ,很不错的网友blog

 

 

       很多餐馆里面都有菜单,列举了他们提供哪些饭菜,哪种面食等,一般的兰州拉面馆里菜单是这样的

  • 牛肉拉面(大碗 )
  • 牛肉拉面(小碗)
  • 牛肉刀削面
  • 羊肉拉面
  • 羊肉刀削面

      你到了这里,你说我要吃手擀面,我要吃挂面,我要吃珍珠翡翠鲍鱼面,他恐怕没有,这些面就需要定制,上面说的牛肉拉面,牛肉刀削面等可以看作是原型,面馆可以看作是原型管理器。原型模式在创建对象不是直接创建的,也就是说,不是通过外部调用类的构造函数调用的,而是通过已存在的对象实例克隆出一个对象,这个克隆对象和他的源对象具有相同的属性和状态,也就是说面馆里的牛肉刀削面每一碗状态都是一样的。

 

克隆对象分为浅拷贝和深拷贝

      浅拷贝就是克隆的对象和它的源对象共享引用的对象,举个例子,可能不恰当,假设牛肉刀削面引用一个对象:Money,表示它值多少钱,这里说的对象 是说它是System.Object继承的(c#), 也就是说不同的浅拷贝对象,他们的价钱是一样的,当克隆对象的价钱变过之后,它所引用的对象的价钱也就随之改变了,比如面馆调低了牛肉刀削面的价格,由5块钱调到了4块钱,那么每碗面的价格都变到了四块钱。但对值类型而言,每个浅拷贝对象都有自己的拷贝,也就是说,当改变克隆对象的值类型时,它的源对象相应属性不会改变。

 

      深拷贝就是完全的拷贝

不仅值类型有自己的拷贝,连引用对象也有自己的一份拷贝,修改克隆对象的任何属性,也不会对源对象产生任何影响。

原型管理器,就是提供原型注册使用,当创建对象使,可以使用里面的对象进行克隆,当有新的实例对象时,也可以将他们加到原型管理器里。

 

      说的有点乱,程序员,还是用代码交流最好,下面的程序分别实现了原型克隆时浅拷贝和深拷贝。

 

//
//理解深拷贝和浅拷贝
//
//浅表副本创建与原始对象具有相同类型的新实例,然后复制原始对象的非静态字段。
//如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制该
//引用但不复制被引用的对象;这样,原始对象中的引用和复本中的引用指向同一个对象。
//相反,对象的深层副本复制对象中字段直接或间接引用的全部内容。
//
//例如,如果 X 是一个具有对对象 A 和对象 B 的引用的 Object,并且对象 A 还具
//有对对象 M 的引用,则 X 的浅表副本是对象 Y,而 Y 同样具有对对象 A 和对象 B
//的引用。相反,X 的深层副本是对象 Y,而对象 Y 具有对对象 C 和对象 D 的直接引
//用以及对对象 N 的间接引用,其中 C 是 A 的副本,D 是 B 的副本,而 N 是 M 的副本。

using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Data;

namespace Prototype
{
     /// <summary>
     /// Prototype类型实例
     /// </summary>
     class TestPrototypeApp
     {
          /// <summary>
          /// 应用程序的主入口点。
          /// </summary>
          [STAThread]
      static void Main(string[] args)
      {

           //定义原型管理器
           NoodleManager noodleManager=new NoodleManager();
   
           //客户要求下面三碗面
           Noodle beefNoodle=(Noodle)noodleManager["牛肉拉面"].Clone();

          // Noodle beefNoodle=(Noodle)noodleManager["牛肉拉面"].DeepClone();
           Noodle muttonNoodle=(Noodle)noodleManager["羊肉拉面"].Clone();
           Noodle beefCutNoodle=(Noodle)noodleManager["牛肉刀削面"].Clone();

           //修改克隆对象中的引用对象的属性,验证它是浅拷贝还是深拷贝
           beefNoodle.TbName=",哈哈哈!,克隆对象改名了,你改不改";

           //显示原始对象的NoodelName和TbName 
           Console.WriteLine(noodleManager["牛肉拉面"].NoodleName+noodleManager["牛肉拉面"].TbName+"\n");
           //显示克隆对象的NoodleName和TbName
           Console.WriteLine(beefNoodle.NoodleName+beefNoodle.TbName+"\n");

  
           //将新的产品加入原型管理器,以备以后克隆时使用,下面是定义了一种新的面条-羊肉刀削面,

           //并把它添加到面条管理器中,如果以后再有客户点这个面,直接克隆即可。
           noodleManager["羊肉刀削面"]=new CutNoodle("羊肉刀削面");

           //克隆一碗羊肉刀削面
           Noodle muttonCutNoodle=(Noodle)noodleManager["羊肉刀削面"].Clone();

           Console.WriteLine(noodleManager["羊肉刀削面"].NoodleName+"\n");
           Console.WriteLine(muttonCutNoodle.NoodleName+"\n");

           Console.ReadLine();
   
      }
 }

 

 

//抽象产品-面条
 //序列化属性,为深拷贝时使用,每个派生类都要加上此属性才能实现深拷贝
 [Serializable]
 public abstract class Noodle
 {
      //定义一个DataTable对象,主要是为了验证对比类中含有引用对象时的深拷贝和浅拷贝时的不同,

     //你也可以采用别的任何引用对象   
      protected DataTable dataTable=new DataTable();
      public string TbName
      {
           get{return dataTable.TableName;}
           set{dataTable.TableName=value;}
      }

      //字段
      protected string noodleName;
      //特性
      public string NoodleName
      {
           get{return noodleName;}
           set{noodleName=value;}
      }

          public abstract Noodle Make(string name);
          //浅克隆的接口
          public abstract Noodle Clone();
          //深克隆的接口
          public abstract Noodle DeepClone();
 }

 //具体产品,拉面
 
 [Serializable]
 public class  PullNoodle:Noodle
 {

     public PullNoodle(string name)
      {
           this.NoodleName=name;
           this.TbName=name+"table";
           Console.WriteLine("PullNoodle is made\n");
      }

      //实现浅拷贝
      public override Noodle Clone()
      {
           return (Noodle)this.MemberwiseClone();
      }

      //实现深拷贝,“淹咸菜”的过程,先将对象序列化到内存流,再反序列化,即可得到深克隆
      public override Noodle DeepClone()
      {
           //定义内存流
           MemoryStream ms=new MemoryStream();
           //定义二进制流
           IFormatter bf=new BinaryFormatter();
           //序列化
           bf.Serialize(ms,this);
           //重置指针到起始位置,以备反序列化
           ms.Position=0;
           //返回反序列化的深克隆对象
           return (Noodle)bf.Deserialize(ms);

      }


      public override Noodle Make(string name)
      {
           return new PullNoodle(name);
      }

 }

 //具体产品-刀削面
 [Serializable]
 public class CutNoodle:Noodle
 {
      public CutNoodle(string name)
      {
           this.NoodleName=name;
           this.TbName=name+"table";
           Console.WriteLine("CutNoodle is made\n");
      }

  //实现浅克隆
      public override Noodle Clone()
      {
           return (Noodle)this.MemberwiseClone();
      }

      public override Noodle Make(string name)
      {
           return new CutNoodle(name);
      }
  //实现深克隆
      public override Noodle DeepClone()
      {
           MemoryStream ms=new MemoryStream();
           IFormatter bf=new BinaryFormatter();
           bf.Serialize(ms,this);
           ms.Position=0;
           return (Noodle)bf.Deserialize(ms);

      }
 }

 //定义原型管理器,用于存储原型集合,这里采用的是HashTable
 
 class NoodleManager
 {
      //定义HashTable
      protected Hashtable noodleHt=new Hashtable();
      protected Noodle noodle;

      public NoodleManager()
      {

      //初始化时加入三种基本原型
       noodle=new PullNoodle("牛肉拉面");
       noodleHt.Add("牛肉拉面",noodle);
       noodle=new PullNoodle("羊肉拉面");
       noodleHt.Add("羊肉拉面",noodle);
       noodle=new CutNoodle("牛肉刀削面");
       noodleHt.Add("牛肉刀削面",noodle);

      }
      //索引器,用于添加,访问Noodle对象
      public Noodle this[string key]
      {
           get{ return (Noodle)noodleHt[key];}
           set{ noodleHt.Add(key,value);}
      }

 }


}
 
分享到:
评论

相关推荐

    JAVA-设计模式-创建型模式-原型模式

    JAVA-设计模式-创建型模式-原型模式

    ava常用设计模式-原型模式

    原型模式(Prototype Pattern)是一种创建型设计模式,允许通过复制现有对象来创建新对象,而不是通过实例化类来创建新对象。在需要创建大量相似对象时非常有用,它可以避免重复创建对象,从而提高性能,并且可以...

    iOS设计模式-原型设计模式

    本文将详细探讨"原型设计模式"(Prototype Design Pattern)及其在iOS中的应用。 原型设计模式是一种创建型设计模式,它通过复制已有对象来创建新对象,而不是通过构造函数或者工厂方法。这种模式主要用于减少创建...

    Java设计模式-原型模式详解

    Java 设计模式 - 原型模式详解 原型模式是 Java 设计模式之一,它用于创建对象时,指定创建对象的类型,并通过拷贝这些原型创建新的对象。该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原...

    C++设计模式-原型模式

    原型模式(Prototype Pattern)是软件设计模式中的一种创建型模式,它提供了一种复制已有对象而不必知道其具体类别的方法。在C++中,原型模式常常利用拷贝构造函数或赋值运算符来实现对象的克隆。这种模式在需要频繁...

    java设计模式-原型模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段...

    c++20设计模式-第4章-原型模式代码

    原型模式(Prototype Pattern)是其中一种行为设计模式,它允许我们通过复制现有对象来创建新对象,而不是通过传统方式实例化新对象。这一模式尤其适用于创建复杂或昂贵的对象,因为它提供了对象克隆的能力,从而...

    c++-设计模式之原型模式(Prototype Pattern)

    原型模式(Prototype Pattern)是一种创建型设计模式,允许通过复制现有对象来创建新对象,而不是通过类构造器。这种模式常用于需要频繁创建相似对象的场景,能够提高性能并减少内存使用。 原型模式的组成 原型接口...

    原型设计模式prototype

    **原型设计模式(Prototype Pattern)**是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而不是通过构造函数来实例化新对象。在面向对象编程中,当我们需要频繁地创建具有相同或相似属性的对象时,...

    getter-in-value-prototype.rar_prototype

    在提供的`getter-in-value-prototype.rar_prototype`文件中,我们可能看到一个测试案例,它演示了如何在对象的value prototype上定义getter。这通常涉及到以下步骤: 1. **创建对象的构造函数**:首先,我们需要...

    设计模式专题之(五)原型模式---设计模式原型模式示例代码(python--c++)

    原型模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在原型模式中,一个对象可以被克隆以创建新对象,而无需知道具体的创建细节。这种模式在需要重复创建相似对象时非常有用,避免了每次创建新对象时都...

    java设计模式---诙谐易懂版

    代理模式(Proxy Pattern)、单例模式(Singleton Pattern)、工厂方法模式...原型模式(Prototype Pattern)、中介者模式(Mediator Pattern)、解释器模式(Interpreter Pattern)、享元模式(Flyweight Pattern)、...

    设计模式 创建型模式 Prototype模式(原型)

    Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。...

    小D深入浅出设计模式+框架源码剖析实战

    ├─第一章 旭瑶-小滴...│ 5.1-创建型设计模式-Prototype原型设计模式实战《上》.mp4 │ 5.2-创建型设计模式-Prototype原型设计模式实战《下》.mp4 │ 6.1-接口之间的桥梁-适配器设计模式你知道多少.mp4 │ 6.4

    C#23种设计模式样例代码和UML图

    行为型模式(策略模式、 迭代器模式、原型模式、职责链模式、 模板方法、 命令模式、 解释器模式、 中介者模式、 访问者模式、 状态模式、 备忘录模式); 结构型模式(代理模式、桥接模式、适配器模式、外观模式、...

    IOS设计模式浅析之原型模式(Prototype)--copy - iOS知识库1

    iOS中的原型模式(Prototype)是一种设计模式,它允许我们通过复制已有对象来创建新的对象,而无需知道具体的创建过程。这种模式在某些情况下能够提高代码的可复用性和效率,特别是当创建新对象的步骤复杂时。 原型...

    设计模式之原型模式

    **原型模式(Prototype Pattern)**是一种创建型设计模式,它提供了一种创建对象的最佳方式,特别是在需要大量相似对象时,可以显著提高效率。在C#中,原型模式允许我们通过复制现有的对象来创建新对象,而不是通过...

    设计模式C++学习之原型模式(Prototype)

    本篇文章将深入探讨“原型模式(Prototype)”这一经典的设计模式,它是面向对象设计的一个重要概念,尤其在C++编程中有着广泛的应用。 原型模式是一种创建型设计模式,它的核心思想是通过复制已有对象来创建新对象,...

    JAVA设计模式-chm版

    这类模式关注对象的创建过程,包括单例模式(Singleton)、工厂模式(Factory)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)和原型模式(Prototype)。它们提供了创建对象的不同策略,使代码更加灵活...

    Java设计模式----通俗易懂版

    Java设计模式是软件工程中的一种重要思想,它总结了在解决特定问题时,程序员们反复使用的一些最佳实践和解决方案。这个资源"Java设计模式----通俗易懂版"显然是一个专门针对初学者或需要深入理解设计模式的开发者...

Global site tag (gtag.js) - Google Analytics