游戏开发中用到的设计模式——命令模式(一)

一,命令模式的定义

将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。解决了这种耦合的好处我认为主要有两点:1.更方便的对命令进行扩展(注意:这不是主要的优势,后面会提到)2.对多个命令的统一控制(这种控制包括但不限于:队列、撤销/恢复、记录日志等等)。在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。

Command模式可应用于

a)整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。

b)调用前后需要对调用参数进行某些处理。

c)调用前后需要进行某些额外处理,比如参数合法性验证,日志,缓存,记录历史操作等。

 

Command模式有如下效果:

a)将调用操作的对象和知道如何实现该操作的对象解耦。

b)Command是头等对象。他们可以像其他对象一样被操作和扩展。

c)你可将多个命令装配成一个符合命令。

d)增加新的Command很容易,因为这无需改变现有的类。

 

经典的命令模式包括4个角色:

Command:定义命令的统一接口

ConcreteCommand:Command接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。

Receiver:命令的实际执行者

Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。

经典的命令模式包括4个角色:

ICommand接口:定义命令的统一接口

ConcreteCommand具体的命令实现类:ICommand接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。

Receiver:命令的实际执行者

Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。

下面对上面四个角色的经典实现用代码来进行说明,这也是大部分文章对命令模式的运用方式。

   

   public interface ICommand

    {

        void Execute();

    }

 

 

   public class ConcreteCommandA : ICommand

   {

       private Receiver receiver = null;

 

       public ConcreteCommandA(Receiver receiver)

       {

           this.receiver = receiver;

       }

 

       public void Execute()

       {

           this.receiver.DoA();

       }

   }

 

 

   public class ConcreteCommandB : ICommand

   {

       private Receiver receiver = null;

 

       public ConcreteCommandB(Receiver receiver)

       {

           this.receiver = receiver;

       }

 

       public void Execute()

       {

           this.receiver.DoB();

       }

   }

 

   public class Receiver

   {

       public void DoA()

       {

           //DoSomething

       }

 

       public void DoB()

       {

           //DoSomething

       }

   }

 

   public class Invoker

   {

       private ICommand command = null;

 

       //设置命令

       public void SetCommand(ICommand command)

       {

           this.command = command;

       }

       //执行命令

       public void RunCommand()

       {

           command.Execute();

       }

   }

   public class Client

   {

       public Client()

       {

           Receiver receiver = new Receiver();

           Invoker invoker = new Invoker();

           invoker.SetCommand(new ConcreteCommandA(receiver));

           invoker.RunCommand();

           invoker.SetCommand(new ConcreteCommandB(receiver));

           invoker.RunCommand();

       }

}

 

不知道大家看过上面的代码之后是什么感觉,反正我看过上面的代码之后第一反应确实是越看越糊涂了,主要觉得有几点疑问:

1. 执行命令可以,但是为什么要用命令封装起来,这不是有点脱裤子放屁的感觉么?我完全可以这样写:

public class Client

   {

       public Client()

       {

           Receiver receiver = new Receiver();

           receiver.DoA();

           receiver.DoB();

       }

 }

这样不是更加简单明了?两个类搞定。

后续内容请参照:http://www.youxijishu.com/h-nd-135-2_323.html

更多游戏技术资料请参照游戏技术网::http://www.youxijishu.com

posted @ 2016-10-09 09:19  游戏技术  阅读(1432)  评论(0)    收藏  举报