命令模式
此条目需要精通或熟悉相关主题的编者参与及协助编辑。 (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;
}