无废话C#设计模式之七:Adapter
本系列文章将向大家介绍一下C#的设计模式,此为第七篇文章,相信对大家会有所帮助的。废话不多说,继续来看。
意图
把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作。
场景
假设网络游戏的客户端程序分两部分。一部分是和服务端通讯的大厅部分,大厅部分提供的功能有道具购买、读取房间列表、创建房间以及启动游戏程序。另一部分就是游戏程序了,游戏程序和大厅程序虽然属于一个客户端,但是由不同的公司在进行开发。游戏大厅通过实现约定的接口和游戏程序进行通讯。
一开始的设计就是,大厅程序是基于接口方式调用游戏程序启动游戏场景方法的。在大厅程序开发接近完成的时候,公司决定和另外一家游戏公司合作,因此希望把大厅程序能适用另一个游戏。而这个新游戏的遵循的是另一套接口。是不是可以避免修改原先调用方法来启动场景呢?或许你会说,既然只有一个方法修改,那么修改一下也无妨,我们假设大厅程序和游戏程序之间有100个接口,其中的大部分都有修改呢?因为游戏程序接口的修改,大厅程序可能要修改不止 100个地方。这样接口的意义何在呢?
此时可以考虑使用Adapter模式来适配这种接口的不匹配情况。
示例代码
  using System; 
  using System.Collections.Generic; 
  using System.Text; 
  namespace AdapterExample 
  { 
  class Program 
  { 
  static void Main(string[] args) 
  { 
  Lobby lobby = new Lobby(); 
  lobby.CreateRoom("HalfPaper"); 
  lobby.StartGame(); 
  } 
  } 
  interface IGame 
  { 
  void StartScene(string sceneName); 
  void EnterPlayer(string playerName); 
  } 
  class Lobby 
  { 
  private string sceneName; 
  public void CreateRoom(string sceneName) 
  { 
  this.sceneName = sceneName; 
  } 
  public void StartGame() 
  { 
  IGame game = new GameAdapter(); 
  game.StartScene(sceneName); 
  game.EnterPlayer("yzhu"); 
  } 
  } 
  class Game 
  { 
  public void LoadScene(string sceneName, string token) 
  { 
  if (token == "Abcd1234") 
  Console.WriteLine("Loading " + sceneName + "..."); 
  else 
  Console.WriteLine("Invalid token!"); 
  } 
  public void EnterPlayer(int playerID) 
  { 
  Console.WriteLine("player:" + playerID + " entered"); 
  } 
  } 
  class GameAdapter : IGame 
  { 
  private Game game = new Game(); 
  public void StartScene(string sceneName) 
  { 
  game.LoadScene(sceneName, "Abcd1234"); 
  } 
  public void EnterPlayer(string playerName) 
  { 
  game.EnterPlayer(GetPlayerIDByPlayerName(playerName)); 
  } 
  private int GetPlayerIDByPlayerName(string playerName) 
  { 
  return 12345; 
  } 
  } 
  }
代码执行结果如下图:

代码说明
可以看到,原先的接口中,启动游戏场景只需要一个参数,就是游戏场景名,而进入新的玩家需要提供玩家ID(新游戏都使用玩家ID而不使用玩家账户名)。
IGame接口就是适配器模式中的目标角色,这是客户所期待的接口。也是针对老的游戏程序所遵循的接口。
Lobby类相当于调用方或者客户,它原先的代码可能是如下的:
Game game = new Game();
但是由于接口的改变,现在不能直接实例化游戏类,只能实例化适配器类型。虽然还是需要改动,但是这个改动是很小的,而且完全可以通过用动态加载程序集来消除这种改动。
GameAdapter类是适配器角色,它是适配器模式的核心,用于把源接口转变为目标接口。在这里,我们看到,它实现目标接
相关新闻>>
- 发表评论
 - 
				
 
- 最新评论 进入详细评论页>>
 



