命令模式--Command

命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。

Command:
    定义命令的接口,声明执行的方法。
ConcreteCommand:
    命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
Receiver:
    接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
Invoker:
    要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
Client:
    创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。

 

命令模式的优点:

1.命令模式将发出请求的对象和执行请求的对象解耦

 

2.在被解耦的两者之间间是通过命令对象进行沟通的,命令对象封装了一个或一组动作

 

3.调用者通过调用命令对象的execute方法发出请求,这使得接收者对象的劢作被调用

 

4.宏命令是命令的一种简单延伸,允许调用多个命令

 

package com.qinsoft.design;

import java.util.ArrayList;
import java.util.List;

//Receiver:命令接收者
class Tv
{
    public int currentChannel = 0;

    public void turnOn()
    {
        System.out.println("The televisino is on.");
    }

    public void turnOff()
    {
        System.out.println("The television is off.");
    }

    public void changeChannel(int channel)
    {
        this.currentChannel = channel;
        System.out.println("Now TV channel is " + channel);
    }
}

//Command:执行命令的接口
interface CommandInter
{

    void execute();
}

//ConcreteCommand:开机命令
class CommandOn implements CommandInter
{

    private Tv myTv;

    public CommandOn(Tv tv)
    {
        myTv = tv;
    }

    public void execute()
    {
        myTv.turnOn();
    }
}

//ConcreteCommand:关机命令
class CommandOff implements CommandInter
{

    private Tv myTv;

    public CommandOff(Tv tv)
    {
        myTv = tv;
    }

    public void execute()
    {
        myTv.turnOff();
    }
}

//ConcreteCommand:频道切换命令
class CommandChange implements CommandInter
{

    private Tv myTv;

    private int channel;

    public CommandChange(Tv tv, int channel)
    {
        myTv = tv;
        this.channel = channel;
    }

    public void execute()
    {
        myTv.changeChannel(channel);
    }
}

//Invoker:可以看作是遥控器吧
class Control
{

    private CommandInter onCommand, offCommand, changeChannel;
    
    public Control(CommandInter on, CommandInter off, CommandInter channel)
    {
        onCommand = on;
        offCommand = off;
        changeChannel = channel;
    }

    public void turnOn()
    {
        onCommand.execute();
    }

    public void turnOff()
    {
        offCommand.execute();
    }

    public void changeChannel()
    {
        changeChannel.execute();
    }
}

//Client:测试类
public class Command
{

    public static void main(String[] args)
    {
        // 命令接收者
        Tv myTv = new Tv();
        // 开机命令
        CommandInter on = new CommandOn(myTv);
        // 关机命令
        CommandInter off = new CommandOff(myTv);
        // 频道切换命令
        CommandInter channel = new CommandChange(myTv, 2);
        // 命令控制对象
        Control control = new Control(on, off, channel);
        //开机
        control.turnOn();
        //切换频道
        control.changeChannel();
        //关机
        control.turnOff();
    }
}

在Invoker类遥控器中都是对应命令的CommandInter对象,所以也可以修改为一个list对象

//Invoker:可以看作是遥控器吧
class Control
{

    public List<CommandInter> commands = new ArrayList<CommandInter>();

    public List<CommandInter> getCommands()
    {
        return commands;
    }
}

//Client:测试类
public class Command
{

    public static void main(String[] args)
    {
        // 命令接收者
        Tv myTv = new Tv();
        // 开机命令
        CommandInter on = new CommandOn(myTv);
        // 关机命令
        CommandInter off = new CommandOff(myTv);
        // 频道切换命令
        CommandInter channel = new CommandChange(myTv, 2);
        
        Control control = new Control();
        control.getCommands().add(on);
        control.getCommands().add(channel);
        control.getCommands().add(off);

        for(java.util.Iterator<CommandInter> it = control.getCommands().iterator();it.hasNext();){
            //客户端直接调用execute方法,无需知道被调用者的其它更多类的方法名。
            it.next().execute();
        }
    }
}

这样的话,使程序变得更加灵活一些。

posted @ 2012-09-12 11:20  何长春  阅读(167)  评论(0编辑  收藏  举报