命令模式
此條目需要精通或熟悉相关主题的编者参与及协助编辑。 (2013年9月12日) |
此條目没有列出任何参考或来源。 (2013年9月12日) |
在物件導向程式設計的範疇中,命令模式(英語:Command pattern)是一種設計模式,它嘗試以物件來代表實際行動。命令物件可以把行動(action) 及其參數封裝起來,於是這些行動可以被:
- 重複多次
- 取消(如果該物件有實作的話)
- 取消後又再重做
這些都是現代大型應用程式所必須的功能,即「復原」及「重複」。除此之外,可以用命令模式來實作的功能例子還有:
- 交易行為
- 進度列
- 精靈
- 使用者介面按鈕及功能表項目
- 執行緒 pool
- 巨集收錄
結構
範例
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);
C++
class ICommand
{
public:
virtual void Execute() = 0;
};
class Swicher
{
private:
std::vector<ICommand *> _commands;
public:
void StoreAndExecute(ICommand *command)
{
if (command){
_commands.push_back(command);
command->Execute();
}
}
};
class Light
{
public:
void TurnOn()
{
std::cout<<"The light is on."<<std::endl;
}
void TurnOff()
{
std::cout << "The light is off." << std::endl;
}
};
/* The Command for turning on the light - ConcreteCommand #1 */
class FlipUpCommand : public ICommand
{
private:
Light *_light;
public:
FlipUpCommand(Light *light)
{
_light = light;
}
void Execute()
{
_light->TurnOn();
}
};
/* The Command for turning off the light - ConcreteCommand #2 */
class FlipDownCommand : public ICommand
{
private:
Light *_light;
public:
FlipDownCommand(Light *light)
{
_light = light;
}
void Execute()
{
_light->TurnOff();
}
};
int main()
{
Light *light = new Light();
ICommand *switchOn = dynamic_cast<ICommand *>(new FlipUpCommand(light));
ICommand *switchDown = dynamic_cast<ICommand *>(new FlipDownCommand(light));
Swicher *switcher = new Swicher();
switcher->StoreAndExecute(switchOn);
switcher->StoreAndExecute(switchDown);
delete switcher;
delete switchOn;
delete switchDown;
delete light;
}