目录
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); }
} } 
|