设计模式学习笔记(2)

原创 2004年08月27日 15:49:00

目录

6.Prototype

7.Builder

8.Astract factory

9.factory method

6.Prototype
说明:实现对象的深拷贝(也可以是浅拷贝)。深拷贝是指生成对象的实体拷贝,而浅拷贝只返回对象的引用。
在C#中提供了ICloneable接口,它只有一个Clone()方法(这和JAVA类似),我们利用它来实现Prototype模式。
浅拷贝的实现:system namespace下提供了MemberwiseClone()方法实现浅拷贝,在Clone()中调用它即可。
深拷贝的实现:手动实现,看下面的实例。
实例:
//----浅拷贝--------
using System; 
namespace Prototype_Shallow{ 
   //因为我们在FCL里面已经有这样的接口所以我们就不定义新的Prototype了 
   public class ConcretePrototype1 : ICloneable{ 
   private int m_ID; 
   public int ID{ 
   get{ 
   return this.m_ID; 
   } 
   }
  
   public ConcretePrototype1(int id){ 
   this.m_ID = id; 
   } 
   
   public object Clone(){ 
   return this.MemberwiseClone(); 
   } 
  } 
   

   public class ConcretePrototype2 : ICloneable{ 
   private int m_ID; 
   public int ID 
   { 
   get 
   { 
   return this.m_ID; 
   } 
  }
  
   public ConcretePrototype2(int id){ 
   this.m_ID = id; 
  }
  
   public object Clone(){ 
   return this.MemberwiseClone(); 
   } 
   }
}
//下面是调用部分
ConcretePrototype1 p1 = new ConcretePrototype1(1);
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();

 

//----深拷贝-----------
namespace Prototype_Deep{
  
   using System.Collections;
  
   public class ConcretePrototype : ICloneable
  
   {
  
   private int m_ID;
  
   public int ID
  
   {
  
   get
  
   {
  
   return this.m_ID;
  
   }
  
   }
  
  
  
   private ArrayList m_arrayList = new ArrayList();
  
  
  
   public ConcretePrototype(int id)
  
   {
  
   this.m_ID = id;
  
   this.m_arrayList.Add("FirstObject");
  
   this.m_arrayList.Add("SecondObject");
  
   // ...
  
   }
  
  
  
   public object Clone()
  
   {
  
   ConcretePrototype c = new ConcretePrototype(this.ID);
  
   c.m_arrayList = new ArrayList();
  
   c.m_arrayList.Add("FirstObject");
  
   c.m_arrayList.Add("SecondObject");
  
   return c;
  
   }
  
  
  
   public ConcretePrototype DeepClone(){
  
   return (ConcretePrototype)this.Clone();
  
   }
  
   }
  
  }

  //下面是调用部分
 
   ConcretePrototype p = new ConcretePrototype(1);
  
   ConcretePrototype c = p.DeepClone();
  
   this.richTextBox1.AppendText(p.ToString()+":"+p.ID.ToString()+"/n");
  
   this.richTextBox1.AppendText(c.ToString()+":"+c.ID.ToString()+"/n");
  
   c.m_arrayList[0] = "Changed";
  
   for(int i = 0;i<=1;i++){
  
   this.richTextBox1.AppendText(c.m_arrayList[i].ToString());
  
   }
  
   this.richTextBox1.AppendText("/n");
  
   for(int i = 0;i<=1;i++){
  
   this.richTextBox1.AppendText(p.m_arrayList[i].ToString());
  
   }


7.builder
说明:builder是非常好理解的,就是把复杂的对象分成若干个简单对象来实现,就好像生产汽车一样,是由各个零件组装成的。我觉得如果每个子对象不会彼此依赖,用这种模式会非常好,可以灵活的拼装出新的复杂类。
实例:
  using System; 
  namespace Builder_Me{ 
   using System.Collections; 
   // specifies an abstract interface for creating parts of a Product object. 
   //为创建对象的一个部分指定一个接口 
   public interface Builder{ 
   void BuildPartA(); 
   void BuildPartB(); 
   Product GetResult(); 
   } 
   
   // constructs and assembles parts of the product by impementing the Builder interface. 
   // defines and keeps track of the representation it creates. 
   // provides an interface for retrieving the product. 
   public class ConcreteBuilder1 : Builder{ 
   private Product m_Product; 
   public void BuildPartA(){ 
   this.m_Product = new Product(); 
   this.m_Product.AddParts("1","PartA"); 
   }
  
   public void BuildPartB(){ 
   this.m_Product.AddParts("2","PartB"); 
   }
  
  
   public Product GetResult(){ 
   return this.m_Product; 
   } 
   }
  
  
   public class ConcreteBuilder2 : Builder{ 
   private Product m_Product; 
   public void BuildPartA(){ 
   //必须先调用该方法否则不能实例化对象 
   this.m_Product = new Product(); 
   this.m_Product.AddParts("3","Part1"); 
  } 

   public void BuildPartB(){ 
   this.m_Product.AddParts("4","Part2"); 
  } 
   
   public Product GetResult(){ 
   return this.m_Product; 
   } 
   } 
   
   // construct an object using the Builder interface. 
   public class Director{ 
   public void Construct(Builder builder){ 
   //顺序不能变 
   builder.BuildPartA(); 
   builder.BuildPartB(); 
   } 
   } 

   
   // represents the complex object under construction.ConcreteBuilder builds 
   // the product's internal representation and defines the process by which it's 
   // assembled. 
   // includes classes that define the constituent parts,including interfaces for 
   // assembling the parts into the final result. 
   //要创建复杂的对象该对象我们用Hashtable组合表示。 
   public class Product{ 
   Hashtable m_Parts = new Hashtable(); 
   public void AddParts(string partKey,string partValue){ 
   this.m_Parts.Add(partKey,partValue); 
   } 

   public string ShowSelfParts(){ 
   string strResult = string.Empty; 
   int i = 1; 
   foreach(string strTmp in this.m_Parts.Values){ 
   strResult +="Part"+i.ToString()+":/t"+strTmp+"/n"; 
   i++; 
  } 
  return strResult; 
   } 
   } 
  }
  
  客户端的代码片断如下: 
  Director director = new Director(); 
   Builder builder1 = new ConcreteBuilder1(); 
   Builder builder2 = new ConcreteBuilder2(); 
   director.Construct( builder1 ); 
   Product p1 = builder1.GetResult(); 
   this.richTextBox1.AppendText(p1.ShowSelfParts()); 
   
   director.Construct( builder2 ); 
   Product p2 = builder2.GetResult(); 
   this.richTextBox1.AppendText(p2.ShowSelfParts());

  
  
  8.Astract factory
  说明:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
  实例:
  using System;
   namespace AbstractFactory_Maze{
   using Maze;
   public interface AbstractFactory{ 
   MazeClass MakeMaze(); 
   Wall MakeWall(); 
   Room MakeRoom(int n); 
   Door MakeDoor(Room oneRoom,Room otherRoom); 
   } 
   
   public class MazeFactory : AbstractFactory{ 
   public MazeClass MakeMaze(){ 
   return new MazeClass(); 
   }
  
   public Wall MakeWall(){ 
   return new Wall(); 
   }
  
   public Room MakeRoom(int n){ 
   return new Room(n); 
   }
  
   public Door MakeDoor(Room oneRoom,Room otherRoom){ 
   return new Door(oneRoom,otherRoom); 
   } 
   } 
   
   // this is a client 
   public class MazeGame{ 
   public MazeClass MazeCreate(AbstractFactory factory){ 
   MazeClass aMaze = factory.MakeMaze(); 
   Room r1 = factory.MakeRoom(1); 
   Room r2 = factory.MakeRoom(2); 
   Door aDoor = factory.MakeDoor(r1,r2); 
   
   aMaze.AddRoom(r1); 
   aMaze.AddRoom(r2); 

   r1.SetSide(Direction.North,factory.MakeWall()); 
   r1.SetSide(Direction.East,aDoor); 
   r1.SetSide(Direction.South,factory.MakeWall()); 
   r1.SetSide(Direction.West,factory.MakeWall()); 
   
   r2.SetSide(Direction.North,factory.MakeWall()); 
   r2.SetSide(Direction.East,factory.MakeWall()); 
   r2.SetSide(Direction.South,factory.MakeWall()); 
   r2.SetSide(Direction.West,aDoor);

   return aMaze; 
   } 
   } 
  } 
   
namespace Maze{ 
   using System.Collections;

   public class MapSite{ 
   public virtual void Enter(){} 
   }
  

   public enum Direction {North,South,East,West}


   public class Room : MapSite{ 
   public string Print(){ 
   string result = ""; 
   for(int i = 0 ;i<=3;i++){ 
   switch(i){ 
   case (int)Direction.East:{ 
   result += "East is:"+this.GetSide(Direction.East)+"/t"; 
   break; 
   }
  
   case (int)Direction.North:{ 
   result += "North is:"+this.GetSide(Direction.North)+"/t"; 
   break; 
   }
  
   case (int)Direction.South:{ 
   result += "South is:"+this.GetSide(Direction.South)+"/t"; 
   break; 
   }
  
   case (int)Direction.West:{ 
   result += "West is:"+this.GetSide(Direction.West)+"/t"; 
   break; 
   } 
   } 
   } 
   return result; 
   }
  
 
   public Room(int n){ 
   this.m_roomNumber = n; 
   }
  
 
   public MapSite GetSide(Direction dir){ 
   return this.m_sides[(int)dir]; 
   }
  

   public void SetSide(Direction dir,MapSite mapSite){ 
   this.m_sides[(int)dir] = mapSite; 
   }
  
 
   public override void Enter(){} 
   private MapSite[] m_sides = new MapSite[4]; 
   int m_roomNumber; 
  }
  
 
   public class Wall : MapSite{ 
   public Wall(){} 
   public override void Enter(){} 
   }
  
 
   public class Door : MapSite{ 
   public Door(Room oneRoom,Room otherRoom){} 
   public override void Enter(){} 
   public Room oneRoom{ 
   get{return this.m_oneRoom;} 
   set{this.m_oneRoom = value;} 
   }
  
   private Room m_oneRoom; 
   public Room otherRoom{ 
   get{return this.m_otherRoom;} 
   set{this.m_otherRoom = value;} 
   }
  
   private Room m_otherRoom;
  
   private bool m_isOpen;
  
   public bool IsOpen{
  
   get{return this.m_isOpen;}
  
   set{this.m_isOpen = value;}
  
   }
  
   }
  
 
   public class MazeClass{
  
   public MazeClass(){}
  

   public string Print(){
  
   string result = "";
  
   for(int i = 0; i<=this.m_Maze.Count-1;i++){
  
   result +=this.RoomNumber(i).Print()+"/n";
  
   }
  
   return result;
  
   }
  
 
   public void AddRoom(Room room){
  
   m_Maze.Add(room);
  
   }
  

   public Room RoomNumber(int roomNumber){
  
   return (Room)this.m_Maze[roomNumber];
  
   }
  
  
   private ArrayList m_Maze = new ArrayList();
  
   }
  
  }
  
 
   private void Form1_Load(object sender, System.EventArgs e) {
  
   AbstractFactory factory = new MazeFactory();
  
   MazeGame game = new MazeGame();
  
   MazeClass aMaze = game.MazeCreate(factory);
  
   this.richTextBox1.AppendText(aMaze.Print());
 
   }
  
 
  以下为输出结果:
  
  North is:Maze.Wall South is:Maze.Wall East is:Maze.Door West is:Maze.Wall
  
  North is:Maze.Wall South is:Maze.Wall East is:Maze.Wall West is:Maze.Door


 9.factory method
 说明:工厂方法的目的很明确就是定义一个用来创建对象的接口,但是他不直接创建对象,而由他的子类来创建,这样一来就将创建对象的责任推迟到了该接口的子类中,创建什么类型的对象由子类来决定,而创建对象的时间由接口来定。
 实例:
  using System;
  
  using System.Collections;
  
  // 该命名空间中是一些运行实例德的环境包括Maze、Door等等
  
  namespace CommonObject{
  
  
  
   // 所有的迷宫构件的基类里面有一个方法用来显示当前构件的信息
  
   public class MapSite{
  
   public virtual string Enter(){
  
   return string.Empty;
  
   }
  
   }
  
  
  
   // 墙是组成迷宫的构件之一,这里是一个很一般的墙(没有炸弹)
  
   public class Wall : MapSite{
  
   public override string Enter(){
  
   return "This is a Wall.";
  
   }
  
   public Wall(){}
  
   }
  
  
  
   // 门也是迷宫的组成部分之一,这也是一个很普通的门(不能施魔法)
  
   public class Door : MapSite{
  
  
  
   public override string Enter(){
  
   return "This is a Door.";
  
   }
  
  
  
   // 门是在两个房子之间的构件所以构造函数包含两个房子
  
   // 说明是哪两个房子之间的门
  
   public Door(Room roomFrom,Room roomTo){
  
   this.m_Room1 = roomFrom;
  
   this.m_Room2 = roomTo;
  
   }
  
  
  
   // 让我们有机会可以从门进入另一个房子,将会得到
  
   // 另一个房子的引用
  
   public Room OtherSideFrom(Room roomFrom){
  
   if(this.m_Room1 == roomFrom)
  
   return this.m_Room2;
  
   else
  
   return this.m_Room1;
  
   }
  
  
  
   // 这是一些私有的变量
  
   private Room m_Room1;
  
   private Room m_Room2;
  
   // 描述门的状态默认所有的新门都是关的
  
   private bool m_IsOpen = false;
  
   // 提供一个公共访问的访问器
  
   public bool IsOpen{
  
   set{this.m_IsOpen = value;}
  
   get{return this.m_IsOpen;}
  
   }

   }
  
  
  
   // 房间是组成迷宫的基本单位
  
   public class Room : MapSite
  
   {
  
   // 枚举类型表示房子的面
  
   public enum Sides{
  
   North = 0,
  
   East,
  
   South,
  
   West
  
   }
  
  
  
   public override string Enter(){
  
   return "This is a Room.";
  
   }

   // 构造函数,为了可以区分房间我们给每一个房间加一个标示
  
   public Room(int roomNumber){
  
   this.m_roomNumber = roomNumber;
  
   }

  
   // 设置房子的面,房子有4个面组成,因为我们现在不知道每个面
  
   // 的具体类型(门?墙?)所以我们用MapSite类型。
  
   public void SetSide(Sides side,MapSite sideMap){
  
   this.m_side[(int)side] = sideMap;
  
   }

   // 得到指定的面,同样我们不知道得到的是哪一个面
  
   // 所以我们用MapSite返回结构
  
   public MapSite GetSide(Sides side){
  
   return this.m_side[(int)side];
  
   }

   // 一些私有成员 房号
  
   protected int m_roomNumber;
  
   // 房子有4个面
  
   protected const int m_Sides = 4;
  
   // 用一个1维的MapSite数组存储未知类型的面(墙或门)
  
   protected MapSite[] m_side = new MapSite[m_Sides];

   }

   // 带炸弹的房子
  
   public class BombedRoom : Room{
  
   public BombedRoom(int roomNumber) : base(roomNumber){}
  
   }

  
   // 带迷宫的房子
  
   public class EnchantedRoom : Room{
  
   public EnchantedRoom(int roomNumber,Spell spell) : base(roomNumber){}
  
   }

  
   // 这是一个特殊的墙--带炸弹的
  
   public class BombedWall : Wall{}
  
  
  
   // 这是一个可以施魔法的门
  
   public class EnchantedDoor : Door{
  
   public EnchantedDoor(Room roomFrom,Room roomTo) : base(roomFrom,roomTo){}
  
   }

   // 这就是我们的迷宫了
  
   public class Maze{
  
   private ArrayList m_Rooms = new ArrayList();
  
   public Room RoomNumber(int roomNumber){
  
   return (Room)this.m_Rooms[roomNumber];
  
   }
  
   public void AddRoom(Room room){
  
   this.m_Rooms.Add(room);
  
   }
  
   }

  
   // 魔法类
  
   public class Spell{}
  
  }
  
  接下来是工厂方法的实现:
  
  using System;
  
  using System.Collections;
  
  namespace FactoryMethod_Example
  
  {
  
  
  
   // 加入MazeContext
  
   using CommonObject;
  
  
  
   // 实现了一些工厂方法的Creator类
  
   public class MazeGame
  
   {
  
   // 要返回给Client的对象
  
   private Maze m_Maze = null;
  
  
  
   // 一个访问器用来得到maze
  
   public Maze Maze
  
   {
  
   get
  
   {
  
   if (this.m_Maze == null)
  
   this.m_Maze = CreateMaze();
  
   return this.m_Maze;
  
   }
  
   }
  
  
  
   // 构造器
  
   public MazeGame()
  
   {
  
   }
  
  
  
   // 以下就是一些工厂方法创建迷宫的每个个构件
  
   public virtual Maze MakeMaze()
  
   {
  
   return new Maze();
  
   }
  
  
  
   public virtual Room MakeRoom(int id)
  
   {
  
   return new Room(id);
  
   }
  
  
  
   public virtual Wall MakeWall()
  
   {
  
   return new Wall();
  
   }
  
  
  
   public virtual Door MakeDoor(Room room1, Room room2)
  
   {
  
   return new Door(room1, room2);
  
   }
  
  
  
   // 创建迷宫
  
   public Maze CreateMaze()
  
   {
  
   Maze maze = MakeMaze();
  
  
  
   // 创建门和房间
  
   Room room1 = MakeRoom(1);
  
   Room room2 = MakeRoom(2);
  
   Door theDoor = MakeDoor(room1, room2);
  
  
  
   // 将房间添加到迷宫里面
  
   maze.AddRoom(room1);
  
   maze.AddRoom(room2);
  
  
  
   // 设置room1的面
  
   room1.SetSide(Room.Sides.North, MakeWall());
  
   room1.SetSide(Room.Sides.East, theDoor);
  
   room1.SetSide(Room.Sides.South, MakeWall());
  
   room1.SetSide(Room.Sides.West, MakeWall());
  
  
  
   // 设置room2的面
  
   room2.SetSide(Room.Sides.North, MakeWall());
  
   room2.SetSide(Room.Sides.East, MakeWall());
  
   room2.SetSide(Room.Sides.South, MakeWall());
  
   room2.SetSide(Room.Sides.West, theDoor);

   return maze;
  
   }
  
   }

  
   // 创建带炸弹迷宫
  
   public class BombedMazeGame : MazeGame{
  
   public BombedMazeGame(){}
  
   public override Wall MakeWall(){
  
   return new BombedWall();
  
   }

   public override Room MakeRoom(int n){
  
   return new BombedRoom(n);
  
   }
  
   }

   // 创建带魔法的迷宫
  
   public class EnchantedMazeGame : MazeGame{

   private Spell m_spell;

   public EnchantedMazeGame(Spell spell){
  
   this.m_spell = spell;
  
   }
  
   public override Door MakeDoor(Room r1,Room r2){
  
   return new EnchantedDoor(r1,r2);
  
   }

   public override Room MakeRoom(int n){
  
   return new EnchantedRoom(n,this.m_spell);
  
   }

   }
  
  }
  

设计模式之工厂方法模式详解与应用(2)

-
  • 1970年01月01日 08:00

设计模式(c++)笔记 总结

一、设计模式分类:       按照目的来分,设计模式可以分为创建型模式、结构型模式和行为型模式。(分类如下表)       创建型模式用来处理对象的创建过程;      结构型模式用来...
  • my183100521
  • my183100521
  • 2013-10-25 15:55:49
  • 2056

设计模式学习笔记--Flyweight享元模式.docx

  • 2010年03月30日 13:19
  • 64KB
  • 下载

设计模式学习笔记--备忘录模式

一.简介 今天来学习一下设计模式中的备忘录模式。说到这个模式,也许不太熟悉,不过相信写代码的时候,写错了之后,Ctrl+Z的功能用得还是比较多的,比如Word,Photoshop等编辑软件中,撤销...
  • puppet_master
  • puppet_master
  • 2016-05-06 14:46:32
  • 900

《javascript设计模式与开发实践》阅读笔记(三)

this,call和apply2.1 thisthis指针的用法,相信在很多场合都看到过,这里也总结了几点: 作为对象的方法调用 作为普通函数调用 构造器调用 Function.prototype.c...
  • sinat_25127047
  • sinat_25127047
  • 2016-11-03 11:41:40
  • 472

《设计模式解析》第2版学习笔记

  • 2008年01月13日 15:01
  • 83KB
  • 下载

Head First 设计模式读书笔记

第一章 设计模式入门 Duck设计原则:把可能变化之处找出来,并独立。                           针对接口编程,实现多态。 把Duck的可能变化的行为独立出来,委托给行为类实...
  • fengyun703
  • fengyun703
  • 2016-05-12 12:07:41
  • 481

大话设计模式 读书笔记

大话设计模式 读书笔记 着重从c#代码角度分析 学习心得: 学设计模式,不需要是否能立刻理解和记忆,无需着力首先是UML图 再从设计模式到UML图 从UML图到代码 其次知道各种模式的应用场景即可...
  • jiangdmdr
  • jiangdmdr
  • 2017-03-01 18:50:25
  • 593

设计模式 -- 状态模式(State)

理解 状态模式一般运用在一个对象在某些条件下能触发一些不同的行为的情形。其实系统开发中到处都充斥着这些情形,初学者往往都是习惯性的用面向过程的思维方式解决问题,往往看到模块中if .. else .....
  • u010223072
  • u010223072
  • 2016-06-26 15:39:45
  • 2538

设计模式---可复用面向对象软件的基础 阅读笔记(一)

设计模式---可复用面向对象软件的基础 阅读笔记(一)            扯些淡:为什么会读这本书,有什么样的意义。目的是为了站在更高层次上去看编码,而且在做的也是产品,对于不想只做个简单的、无...
  • u013793732
  • u013793732
  • 2016-09-03 16:03:51
  • 574
收藏助手
不良信息举报
您举报文章:设计模式学习笔记(2)
举报原因:
原因补充:

(最多只允许输入30个字)