Saturday, December 15, 2012

Design Patterns-Command Patterns

將一個請求封裝為物件,讓你可用不同的請求對客戶進行參數化。對請求排隊或記錄請求日誌,以及支援可取消的操作。

繪圖1

KinectManager:

   1: public class KinectManager
   2: {
   3:     public void KinectWave()
   4:     {
   5:         Console.WriteLine("Doing WaveGesture");
   6:     }
   7:     public void KinectHold()
   8:     {
   9:         Console.WriteLine("Doing HoldGesture");
  10:     }
  11: }


Client:



   1: static void Main(string[] args)
   2: {
   3:     KinectManager kinectManager = new KinectManager()
   4:     kinectManager.KinectWave();
   5:     kinectManager.KinectHold();
   6:     kinectManager.KinectWave();
   7:     kinectManager.KinectWave();
   8:     kinectManager.KinectHold();
   9:     Console.Read();
  10:  
  11: }

當執行命令時,皆要透過kinectManager,當命令變多時則就容易肇成混亂。(有如客人直接向廚師點菜,廚師不只要炒菜還要處理客人點的菜單) 緊耦合的設計。


Tem


Command:




   1: public abstract class Command
   2: {
   3:     protected KinectManager receiver;
   4:     pulbic Command(KinectManager receiver)
   5:     {
   6:         this.receiver = receiver;
   7:     }
   8:     abstract public void ExcuteCommand();
   9: }


WaveCommand:




   1: class WaveCommand : Command
   2: {
   3:     public WaveCommand(KinectManager receiver)
   4:         :base(receiver){}
   5:     
   6:     public override void ExcuteCommand()
   7:     {
   8:         receiver.KinectWave();
   9:     }
  10: }


HoldCommand:




   1: class HoldCommand : Command
   2: {
   3:     public HoldCommand(KinectManager receiver)
   4:         :base(receiver){}
   5:     pulibc override void ExcuteCommand()
   6:     {
   7:         receiver.KinectHold();
   8:     }
   9: }

Service:


   1: public class Service
   2: {
   3:     private Command command;
   4:     public void SetOrder(Command command)
   5:     {
   6:         thos.command = command;
   7:     }
   8:     public void NotifyCommand()
   9:     {
  10:         command.ExcuteCommand();
  11:     }
  12: }

KinectManager:Same as above


再來考慮到Service可能需要取消Command且,若Command 是一連續判斷(在Kinect 可能需要把Gesture分解成數個Part)因此,還要再修改Service:



   1: public class Service
   2: {
   3:     private IList<Command> orders = new List<Command>();
   4:  
   5:     public void SetOrder(Command command)
   6:     {
   7:         if(Command can be add)
   8:             orddes.Add(command);
   9:         else
  10:             //some problem so Command can't be excute
  11:     }
  12:     
  13:     public void CancelOrder(Command command)
  14:     {
  15:         orders.Remove(command);
  16:     }
  17:     
  18:     public void NotifyCommand()
  19:     {
  20:         foreach(Command cmd in orders)
  21:             cmd.ExcuteCommand();
  22:     }
  23: }

Client:



   1: static void Main(string[]  args)
   2: {
   3:     KinectManager kinectManager = new KinectManager();
   4:     Command waveCommand1 = new WaveCommand(kinectManager);
   5:     Command waveCommand2 = new WaveCommand(kinectManager);
   6:     Command holdCommand = new HoldCommand(kinectManager);
   7:     
   8:     Service serviceOrder = new Service();
   9:     serviceOrder.SetOrder(waveCommand1);
  10:     serviceOrder.SetOrder(waveCommand2);
  11:     serviceOrder.SetOrder(holdCommand1);
  12:     
  13:     service.NotifyCommand();
  14:     Console.Read();
  15:     
  16: }

在Kinect的姿勢判斷,可以將動作分為數個檢查點,假設一個Wave的Gesture分成兩個Part(兩個Command),當如果IList 存取的東西為依序的兩個Part 代表這一連串動作辨識是成功,則Excute Wave Gesture 的行為。


 


Command Pattern:


優點:



1.容易設計一個命令的佇列。


2.容易將命令記入到日誌(List)。


3.接收請求的一方決定是否要否決或接受。


4.加入新的具體命令不影響其他命令(Encapsulation)。

No comments:

Post a Comment