标签:使用 trim 工厂模式 相关 图片 csharp images 范围 alt
换种形式学设计模式,让自己更有兴趣的学设计模式 :)
本文使用了建造者模式创建不同的游戏地图,当然是用控制台模拟的假地图...
建造者模式,是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。
总的来说,建造者模式就是把一个个零部件添加到了一样产品上,最后创建出一个完整的产品,不同产品之间需要有共性,例如汽车都有轮子和引擎,可能引擎马力不同,轮子数量不同,用户只需要挑选成品产品而不需要知道造车子的细节。
用户通过客户端选择地图种类之后,系统自动为用户创建不同的游戏地图。
游戏地图包含两种:
地图包含的共通元素有:
通过分析可知:
通过以上的项目特点,我们可以看到建造者模式很符合本项目需求。??
此项目中的产品零件即为地图元素
地图元素抽象类:
/// <summary>
/// 地图元素抽象类
/// </summary>
abstract class IMapElement
{
//x坐标
public int _x;
//y坐标
public int _y;
public string _name;
public IMapElement(string name)
{
//模拟加载地图元素耗时,并且需要一定间隔让随机数产生不重复
Thread.Sleep(100);
Random random = new Random();
this._x = random.Next(0, 100);
this._y = random.Next(0, 100);
this._name = name;
}
//元素展示
public abstract void Dispaly();
}
具体地图元素类:包含怪兽、NPC、树、路
/// <summary>
/// 怪兽类
/// </summary>
class Monster : IMapElement
{
public double _blood;
public Monster(string name) : base(name)
{
this._blood =new Random().Next(0,100);
}
public override void Dispaly()
{
Console.WriteLine($"元素类型:怪兽;血量:{_blood};元素名称:{_name};元素坐标x:{_x},y:{_y};\r\n");
}
}
/// <summary>
/// NPC类
/// </summary>
class NPC : IMapElement
{
public string _job;
public NPC(string name, string job) : base(name)
{
this._job = job;
}
public override void Dispaly()
{
Console.WriteLine($"元素类型:NPC;职位:{_job};元素名称:{_name};元素坐标x:{_x},y:{_y};\r\n");
}
}
/// <summary>
/// 树类
/// </summary>
class Tree : IMapElement
{
public int _height;
public Tree(string name) : base(name)
{
this._height = new Random().Next(1,50);
}
public override void Dispaly()
{
Console.WriteLine($"元素类型:树;高度:{_height}m;元素名称:{_name};元素坐标x:{_x},y:{_y};\r\n");
}
}
/// <summary>
/// 路
/// </summary>
class Way : IMapElement
{
public int _length;
public Way(string name) : base(name)
{
this._length = new Random().Next(100,10000);
}
public override void Dispaly()
{
Console.WriteLine($"元素类型:路;长度:{_length}m;元素名称:{_name};元素坐标x:{_x},y:{_y};\r\n");
}
}
这些地图元素是地图的"零配件",地图元素的不同导致地图种类的不同。
此项目中具体的产品即为地图(Game Map)
游戏地图类:
/// <summary>
/// 游戏场景(具体的产品)
/// </summary>
class GameMap
{
//地图元素集合
public IList<IMapElement> MapElements = new List<IMapElement>();
/// <summary>
/// 添加地图元素
/// </summary>
/// <param name="MapElement"></param>
public void AddMapElements(IMapElement MapElement)
{
MapElements.Add(MapElement);
}
/// <summary>
/// 展示地图
/// </summary>
public void Show()
{
Console.WriteLine("——————————————————————地图显示————————————————————\r\n");
foreach (var element in MapElements)
{
element.Dispaly();
}
}
}
创建者接口为创建一个Product对象的各个部位指定抽象接口。
interface IGameMapBuilder
{
void BuilderTree();
void BuilderWay();
void BuilderMonster();
void BuilderNPC();
GameMap GetGameMap();
}
具体创建者是产品构建差异体现,具体实现如何构建产品。
本项目中的具体创建者有两个:
这两个创建者都继承抽象创建者IGameMapBuilder
ForestMapBuilder:
/// <summary>
/// 森林游戏场景具体建造者----特点:树多
/// </summary>
class ForestMapBuilder : IGameMapBuilder
{
private GameMap gameMap = new GameMap();
public void BuilderMonster()
{
Monster monster1 = new Monster("哥斯拉");
Monster monster2 = new Monster("异形");
Monster monster3 = new Monster("女朋友");
gameMap.AddMapElements(monster1);
gameMap.AddMapElements(monster2);
gameMap.AddMapElements(monster3);
}
public void BuilderNPC()
{
NPC npc1 = new NPC("NPC", "任务接取处");
gameMap.AddMapElements(npc1);
}
public void BuilderTree()
{
for (int i = 0; i < 15; i++)
{
gameMap.AddMapElements(new Tree($"树{i}"));
}
}
public void BuilderWay()
{
Way way = new Way("主路");
gameMap.AddMapElements(way);
}
public GameMap GetGameMap()
{
return gameMap;
}
}
MonsterMapBuilder:
/// <summary>
/// 怪物地图创建者 特点:怪物多
/// </summary>
class MonsterMapBuilder : IGameMapBuilder
{
private GameMap gameMap = new GameMap();
public void BuilderMonster()
{
for (int i = 0; i < 15; i++)
{
gameMap.AddMapElements(new Monster($"怪物{i}"));
}
}
public void BuilderNPC()
{
NPC npc1 = new NPC("任务npc", "任务接取处");
NPC npc2 = new NPC("商店npc", "购买物品");
gameMap.AddMapElements(npc1);
gameMap.AddMapElements(npc2);
}
public void BuilderTree()
{
for (int i = 0; i < 3; i++)
{
gameMap.AddMapElements(new Tree($"树{i}"));
}
}
public void BuilderWay()
{
Way way1 = new Way("主路");
Way way2 = new Way("史诗之路");
gameMap.AddMapElements(way1);
gameMap.AddMapElements(way2);
}
public GameMap GetGameMap()
{
return gameMap;
}
}
指挥者指定创建者创建,并且决定创建顺序
本项目中的创建者为GameMapDirect
class GameMapDirector
{
public void Construct(IGameMapBuilder builder)
{
Console.WriteLine("---------------正在加载树资源-----------------");
builder.BuilderTree();
Console.WriteLine("---------------正在加载怪物资源---------------");
builder.BuilderMonster();
Console.WriteLine("---------------正在加载道路资源---------------");
builder.BuilderWay();
Console.WriteLine("---------------正在加载NPC资源----------------");
builder.BuilderNPC();
Console.WriteLine("-----------------资源加载完毕-----------------");
}
}
Construct()
方法参数为创建者,方法内部指定了创建顺序。
static void Main(string[] args)
{
Console.WriteLine("请选择地图类型:1.怪兽地图 2.森林地图");
string result = Console.ReadLine().Trim();
IGameMapBuilder builder = null;
if (Convert.ToInt32(result) == 1)
{
Console.WriteLine("--------------正在加载怪兽地图--------------------");
builder = new MonsterMapBuilder();
}
else
{
Console.WriteLine("--------------正在加载森林地图--------------------");
builder = new ForestMapBuilder();
}
GameMapDirector director = new GameMapDirector();
//建造者指派builder去建造地图
director.Construct(builder);
//建造者建造好地图之后返回地图
GameMap gameMap = builder.GetGameMap();
//地图呈现
gameMap.Show();
Console.Read();
}
可以看到,玩家选择了怪兽地图,指挥者指定怪兽地图建造者建造地图,建造顺序按照指挥者方法内部顺序加载地图,最后呈现了一个怪物很多的地图:)
优点:
缺点:
? 看到第三点突然想到,本项目中的地图元素可以使用简单工厂实现或者工厂方法模式实现,简单工厂的话就用Switch xxxxx
,使用工厂方法模式的话就有TreeFactory
、MonsterFactory
....
? 如果再之后怪兽细分为各种怪兽:皮卡丘、小拉达、等等等...那么就可以用抽象工厂模式生产怪兽族。。。妙呀??
版权声明:本文为吴恺的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文地址:https://www.cnblogs.com/zaijianba/p/11584625.html
我的个人博客地址:www.wukailiving.cn
本文是个小菜鸡写的,对代码理解并不深刻,轻喷。
如有不足之处,欢迎指正!
标签:使用 trim 工厂模式 相关 图片 csharp images 范围 alt
原文地址:https://www.cnblogs.com/zaijianba/p/11584625.html