在上一周的读书笔记中,我介绍了状态模式的概念与运用,在这一周的笔记中我要介绍另外一种模式——外观模式(Facede)。
前言
上一周讲解了状态模式,主要是游戏又很多不同的状态,这些状态(子系统)的相互转换,如果采用常规的一些分支语句方法,会使得效率变得十分低下,因此状态模式可以理解成是控制这些状态转换的开关。但是在游戏里面这些子系统(例如游戏事件系统、关卡系统、角色管理系统)内部是怎么样实现的呢?而且在游戏运行时候这些子系统之间必定会进行互相调用和输入玩家的参数以及运行结果。如果我们直接调用这些子系统的话,可能就会变得非常麻烦,我在此不进行赘述,直接贴一个常规代码。
public class BattleState
{
//角色系统
//战斗系统
//关卡系统
//........
public void InitGame()
{
//初始化角色系统
//初始化战斗系统
//初始化关卡系统
//..............
}
public void Update()
{
//更新角色系统
//更新战斗系统
//更新关卡系统
//............
}
//设置状态为战斗状态
}
我们一般可能都会这样写,因为战斗状态需要用到什么子系统,我们就直接去这样做,简答粗暴,但是这样写的后果也是非常严重的。
有两个非常严重的缺点:
1.违背了面向对象的七大原则之一的:单一职责原则,我们状态类仅仅是需要负责游戏在“战斗模式”下的功能执行以及进行状态切换,而不会负责游戏子系统的初始化,执行操作以及相关的整合工作。
2.从“可重用性”来看,这种设计方式不容易转换给其他的项目使用,因为战斗类绑定了其他太多的子系统,一动全部都要改。
从这两点来看,这种一般的设计方式使得代码耦合性太大,不便于修改和使用。那么这个时候就要请出我们的外观模式
外观模式
依然引用原书中的定义:“为子系统定义一组统一的接口,这个高级的接口会让子系统更容易被使用”。
可能这样看起来十分抽象,但本书又正好提供了一个非常贴切形象的比喻。
以驾驶汽车为例,汽车想要跑起来肯定需要人驾驶,但是人驾驶只是一个外部的操作过程,而内部的实现依然需要引擎系统、传动系统、悬吊系统、车身骨架系统、电装系统。但那么多老司机,他们难道都是机电工程师?他们都会使用这些内部设施吗?答案显然是否定的,他们是通过驾驶台上面的各种功能按钮。比如我要启动就可以按这个,要刹车就可以踩脚踏板。而这里的驾驶台,就可以理解成一个高级的接口,而司机就是客户端。
外观模式可以用下面的这个图来形容。
原本需要参与的角色都被高级接口所包装了,我们只需调用这个高级操作面板,进行操作就行。
那么在游戏中只需要使用外观模式实现游戏主程序,模拟代码如下:
namespace 外观模式
{
class A
{
public void funA()
{
Console.WriteLine("执行战斗系统功能");
}
}
class B
{
public void funB()
{
Console.WriteLine("执行背包系统功能");
}
}
class C
{
public void funC()
{
Console.WriteLine("执行商城系统功能");
}
}
class D
{
public void funD()
{
Console.WriteLine("执行游戏结束系统");
}
}
/// <summary>
/// 高级面板类
/// </summary>
class MainStateGame
{
private A a = null;
private B b = null;
private C c = null;
private D d = null;
/// <summary>
/// 初始化系统
/// </summary>
public void Init()
{
a = new A();
b = new B();
c = new C();
d = new D();
Console.WriteLine("初始化子系统");
}
public void Gameover()
{
d.funD();
}
public void BackPage()
{
b.funB();
}
public void FightSystem()
{
a.funA();
}
public void SellMall()
{
c.funC();
}
}
/// <summary>
/// 状态类
/// </summary>
class Program
{
static void Main(string[] args)
{
//打开控制面板
MainStateGame mainStateGame = new MainStateGame();
//初始化子系统
mainStateGame.Init();
//调用子系统功能
mainStateGame.BackPage();
mainStateGame.FightSystem();
mainStateGame.SellMall();
mainStateGame.Gameover();
Console.ReadKey();
}
}
}
如上就是本周的读书笔记