好了废话就不多说了,GOF说的比我清楚多了(其实我也是从他们那里学的J)。下面来实现我们的迷宫,代码如下:
首先实现我们的环境
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);
}
}
}
上面的代码在.NET IDE里测试通过,上面说过了在FCL里面又很多的工厂方法的实现,如果想要继续学习和理解可以看看MSDN的帮助。希望我写的这些可以帮助你更好的理解工厂方法模式。如果有什么不正确的地方希望指出可以发邮件到wu_jian830@hotmail.com里,我将虚心学习,希望我们可以共同进步。