返回

2.外观模式

当我们能够利用简单的行为来操控一个复杂的系统时,当下所使用的接口,就是以外观模式来定义的高级接口。

外观模式

当我们能够利用简单的行为来操控一个复杂的系统时,当下所使用的接口,就是以外观模式来定义的高级接口。

以微波炉为例,微波炉内部包含了电源供应系统、微波加热系统、冷却系统、外装防护等。当我们想要使用微波炉加热食物时,直接操控微波炉上的操控面板即可,而不用去调整内部的电源、加热、冷却系统这些繁琐的内部系统。

所以,外观模式的重点在于,它能将系统内部的互动细节隐藏起来,并提供一个方便的接口。之后客户端只需要通过这个接口,就可以操作一个复杂系统并让他们顺利的运行。

外观模式的说明

整合子系统并提供一个高级的界面让客户端使用。

参与者的说明如下:

  • client(客户端、用户)

    从原本需要操作多个子系统的情况,改为只需要面对一个整合后的界面。

  • subSystem(子系统)

    原本会由不同的客户端(非同一系统相关)来操作,改为只会由内部系统之间交互使用。

  • Facade(统一对外的界面)

    • 整合所有子系统的接口及功能,并提供高级界面(或接口)共客户端使用。
    • 接受客户端段的消息后,将消息传递给负责的子系统。

主程序设计

游戏实现时,先将几个游戏系统写在一个直接使用他们的类中,但对着游戏系统越加越多,会发现这些游戏系统的层序代码占据了整个类。这些游戏系统的初始化设置和流程串接,与使用它们的类完全没有关系,此时就需要将它们移出,并以一个类重新组织。

参与者说明如下:

  • GameEventSystem、CampSystem……:分别为游戏的子系统,每个子系统负责各自应该实现的功能并提供接口。
  • PBaseDefenseGame:包含了和游戏相关的子系统对象,并提供了界面让客户端使用。
  • BattleState:战斗状态类。

具体实现

public class PBaseDefenseGame
{
	...
	// 遊戲系統
	private GameEventSystem m_GameEventSystem = null;	 // 遊戲事件系統
	private CampSystem m_CampSystem	 = null; 			 // 兵營系統
	private StageSystem m_StageSystem = null; 			 // 關卡系統
	private CharacterSystem m_CharacterSystem = null; 	 // 角色管理系統
	private APSystem m_ApSystem = null; 				 // 行動力系統
	private AchievementSystem m_AchievementSystem = null;// 成就系統
    ...
        
	public void Initinal()
	{
		// 場景狀態控制
		m_bGameOver = false;
		// 遊戲系統
		m_GameEventSystem = new GameEventSystem(this);	// 遊戲事件系統
		m_CampSystem = new CampSystem(this);			// 兵營系統
		m_StageSystem = new StageSystem(this);			// 關卡系統
		m_CharacterSystem = new CharacterSystem(this); 	// 角色管理系統
		m_ApSystem = new APSystem(this);				// 行動力系統
		m_AchievementSystem = new AchievementSystem(this); // 成就系統
    	...
    }
    
    public void Update()
	{
		// 遊戲系統更新
		m_GameEventSystem.Update();
		m_CampSystem.Update();
		m_StageSystem.Update();
		m_CharacterSystem.Update();
		m_ApSystem.Update();
		m_AchievementSystem.Update();
	}
}
public class BattleState : ISceneState
{
	// 開始
	public override void StateBegin()
	{
		PBaseDefenseGame.Instance.Initinal();
	}

	// 結束
	public override void StateEnd()
	{
		PBaseDefenseGame.Instance.Release();
	}
			
	// 更新
	public override void StateUpdate()
	{	
		// 遊戲邏輯
		PBaseDefenseGame.Instance.Update();
		// Render由Unity負責

		// 遊戲是否結束
		if( PBaseDefenseGame.Instance.ThisGameIsOver())
			m_Controller.SetState(new MainMenuState(m_Controller), "MainMenuScene" );
	}
}

外观模式的优点

  • 使用外观模式可将Client单一化,让该类只负责功能执行及状态切换,不用负责串接各个游戏系统的初始化和调用功能。
  • 使用外观模式使得Client减少了不必要的类引用及功能整合,因此增加了Client类被复用的机会。
  • 节省时间
  • 易于分工开发,开发者只需要了解对方负责系统的 Facade 接口类,不必深入了解其中的运行方式。
  • 增加系统的安全性,隔离客户端对子系统的接触,除了能减少耦合度之外,安全性也是重点之一。

外观模式的应用

  • 网络引擎:网络通信是一项复杂的工作,通常包含连线管理系统、信息时间系统、网络数据风暴管理系统等,所以一般会用外观模式将上述子系统整合为一个系统。
  • 数据库引擎:再游戏服务器的实现中,可以将与“关系数据库”相关的操作,以一种较为高级的接口隔离,这个接口可以将数据库系统中所需的连线、数据表修改、新增、删除、更新、查询等操作加以封装,让不是很了解关系数据库原理的设计人员也能使用。