目录
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);
}
}
}
本文地址:http://com.8s8s.com/it/it28072.htm