命令模式

维基百科,自由的百科全书
跳转至: 导航搜索

物件導向程式設計的範疇中,命令模式是一種設計模式,它嘗試以物件來代表實際行動。命令物件可以把行動(action) 及其參數封裝起來,於是這些行動可以被:

  • 重複多次
  • 取消(如果該物件有實作的話)
  • 取消後又再重做

這些都是現代大型應用程式所必須的功能,即「復原」及「重複」。除此之外,可以用命令模式來實作的功能例子還有:

  • 交易行為
  • 進度列
  • 精靈
  • 使用者介面按鈕及功能表項目
  • 執行緒 pool
  • 巨集收錄

結構[编辑]

Command Design Pattern Class Diagram.png

範例[编辑]

C#[编辑]

using System;
using System.Collections.Generic;
 
namespace CommandPattern
{
    public interface ICommand
    {
        void Execute();
    }
 
    /* The Invoker class */
    public class Switch
    {
        private List<ICommand> _commands = new List<ICommand>();
 
        public void StoreAndExecute(ICommand command)
        {
            _commands.Add(command);
            command.Execute();
        }
    }
 
    /* The Receiver class */
    public class Light
    {
        public void TurnOn()
        {
            Console.WriteLine("The light is on");
        }
 
        public void TurnOff()
        {
            Console.WriteLine("The light is off");
        }
    }
 
    /* The Command for turning on the light - ConcreteCommand #1 */
    public class FlipUpCommand : ICommand
    {
        private Light _light;
 
        public FlipUpCommand(Light light)
        {
            _light = light;
        }
 
        public void Execute()
        {
            _light.TurnOn();
        }
    }
 
    /* The Command for turning off the light - ConcreteCommand #2 */
    public class FlipDownCommand : ICommand
    {
        private Light _light;
 
        public FlipDownCommand(Light light)
        {
            _light = light;
        }
 
        public void Execute()
        {
            _light.TurnOff();
        }
    }
 
    /* The test class or client */
    internal class Program
    {
        public static void Main(string[] args)
        {
            Light lamp = new Light();
            ICommand switchUp = new FlipUpCommand(lamp);
            ICommand switchDown = new FlipDownCommand(lamp);
 
            Switch s = new Switch();
            string arg = args.Length > 0 ? args[0].ToUpper() : null;
            if (arg == "ON")
            {
                s.StoreAndExecute(switchUp);
            }
            else if (arg == "OFF")
            {
                s.StoreAndExecute(switchDown);
            }
            else
            {
                Console.WriteLine("Argument \"ON\" or \"OFF\" is required.");
            }
        }
    }
}

Java[编辑]

import java.util.List;
import java.util.ArrayList;
 
/* The Command interface */
public interface Command {
   void execute();
}
 
/* The Invoker class */
public class Switch {
   private List<Command> history = new ArrayList<Command>();
 
   public Switch() {
   }
 
   public void storeAndExecute(Command cmd) {
      this.history.add(cmd); // optional 
      cmd.execute();        
   }
}
 
/* The Receiver class */
public class Light {
   public Light() {
   }
 
   public void turnOn() {
      System.out.println("The light is on");
   }
 
   public void turnOff() {
      System.out.println("The light is off");
   }
}
 
/* The Command for turning on the light - ConcreteCommand #1 */
public class FlipUpCommand implements Command {
   private Light theLight;
 
   public FlipUpCommand(Light light) {
      this.theLight = light;
   }
 
   public void execute(){
      theLight.turnOn();
   }
}
 
/* The Command for turning off the light - ConcreteCommand #2 */
public class FlipDownCommand implements Command {
   private Light theLight;
 
   public FlipDownCommand(Light light) {
      this.theLight = light;
   }
 
   public void execute() {
      theLight.turnOff();
   }
}
 
/* The test class or client */
public class PressSwitch {
   public static void main(String[] args){
      Light lamp = new Light();
      Command switchUp = new FlipUpCommand(lamp);
      Command switchDown = new FlipDownCommand(lamp);
 
      Switch mySwitch = new Switch();
 
      try {
         if ("ON".equalsIgnoreCase(args[0])) {
            mySwitch.storeAndExecute(switchUp);
         }
         else if ("OFF".equalsIgnoreCase(args[0])) {
            mySwitch.storeAndExecute(switchDown);
         }
         else {
            System.out.println("Argument \"ON\" or \"OFF\" is required.");
         }
      } catch (Exception e) {
         System.out.println("Arguments required.");
      }
   }
}

Python[编辑]

class Switch(object):
    """The INVOKER class"""
    def __init__(self, flip_up_cmd, flip_down_cmd):
        self.flip_up = flip_up_cmd
        self.flip_down = flip_down_cmd
 
class Light(object):
    """The RECEIVER class"""
    def turn_on(self):
        print("The light is on")
    def turn_off(self):
        print("The light is off")
 
class LightSwitch(object):
    """The CLIENT class"""
    def __init__(self):
        lamp = Light()
        self._switch = Switch(lamp.turn_on, lamp.turn_off)
 
    def switch(self, cmd):
        cmd = cmd.strip().upper()
        if cmd == "ON":
            self._switch.flip_up()
        elif cmd == "OFF":
            self._switch.flip_down()
        else:
            print("Argument 'ON' or 'OFF' is required.")
 
# Execute if this file is run as a script and not imported as a module
if __name__ == "__main__":
    light_switch = LightSwitch()
    print("Switch ON test.")
    light_switch.switch("ON")
    print("Switch OFF test.")
    light_switch.switch("OFF")
    print("Invalid Command test.")
    light_switch.switch("****")

Scala[编辑]

/* The Command interface */
trait Command {
   def execute()
}
 
/* The Invoker class */
class Switch {
   private var history: List[Command] = Nil
 
   def storeAndExecute(cmd: Command) {
      cmd.execute()
      this.history :+= cmd
   }
}
 
/* The Receiver class */
class Light {
   def turnOn() = println("The light is on")
   def turnOff() = println("The light is off")
}
 
/* The Command for turning on the light - ConcreteCommand #1 */
class FlipUpCommand(theLight: Light) extends Command {
   def execute() = theLight.turnOn()
}
 
/* The Command for turning off the light - ConcreteCommand #2 */
class FlipDownCommand(theLight: Light) extends Command {
   def execute() = theLight.turnOff()
}
 
/* The test class or client */
object PressSwitch {
   def main(args: Array[String]) {
      val lamp = new Light()
      val switchUp = new FlipUpCommand(lamp)
      val switchDown = new FlipDownCommand(lamp)
 
      val s = new Switch()
 
      try {
         args(0).toUpperCase match {
            case "ON" => s.storeAndExecute(switchUp)
            case "OFF" => s.storeAndExecute(switchDown)
            case _ => println("Argument \"ON\" or \"OFF\" is required.")
         }
      } catch {
         case e: Exception => println("Arguments required.")
      }
   }
}

Javascript[编辑]

/* The Invoker function */
var Switch = function(){
    var _commands = [];
    this.storeAndExecute = function(command){
        _commands.push(command);
        command.execute();
    }
}
 
/* The Receiver function */
var Light = function(){
    this.turnOn = function(){ console.log ('turn on')};
    this.turnOff = function(){ console.log ('turn off') };
}
 
/* The Command for turning on the light - ConcreteCommand #1 */
var FlipUpCommand = function(light){
    this.execute = light.turnOn;
}
 
/* The Command for turning off the light - ConcreteCommand #2 */
var FlipDownCommand = function(light){
    this.execute = light.turnOff;
}
 
var light = new Light();
var switchUp = new FlipUpCommand(light);
var switchDown = new FlipDownCommand(light);
var s = new Switch();
 
s.storeAndExecute(switchUp);
s.storeAndExecute(switchDown);