设计模式之命令模式总结

快速切入

命令模式,顾名思义是对命令的封装,其实也就是一个个行为,同属于行为模式中你的一种,我们平时处理一个命令是这样的,将各种命令写入一个类中,然后客户端直接调用即可。这样的话其实一个类就职责不明,干了很多事,代码也非常多,维护困难。如果用命令模式的话会被分解成这样:请求者(调用命令执行操作)类,然后是命令(定义所有的具体命令及其实现)类,最后是接收者(接收请求并执行请求)类,这样分成三步它的耦合度要比把所有的操作都封装到一个类中要低的多,而这也正是命令模式的精髓所在:把命令的调用者与执行者分开,使双方不必关心对方是如何操作的。

实战

我们用生活中的例子来举例,比如一台打印机,可以执行打印,复印,扫描等操作,而你是命令的下达者。
首先我们定义一个接收者类,用来具体实施或执行一个请求,就是执行具体逻辑,这里我们需要执行打印,复印,扫描等操作。

public class Receiver {
    // 执行具体的逻辑的方法

    public void toPrint() {
        System.out.println("打印中...");
    }

    public void toCopy() {
        System.out.println("复印中...");
    }

    public void toScan() {
        System.out.println("扫描中...");
    }
}

定义命令类,先对其抽象出来一层,然后写好具体的命令者,命令者是用来调用具体的逻辑的。


public interface Command {
    // 执行具体操作的命令
    void execute();

}

// 具体命令者
public class PrintCommand implements Command {

    private Receiver receiver;

    public PrintCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        // TODO Auto-generated method stub
        receiver.toPrint();
    }

}

// 具体命令者
public class CopyCommand implements Command {

    private Receiver receiver;

    public CopyCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        // TODO Auto-generated method stub
        receiver.toCopy();
    }

}

// 具体命令者
public class ScanCommand implements Command {

    private Receiver receiver;

    public ScanCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        // TODO Auto-generated method stub
        receiver.toScan();
    }

}

编写请求者类,请求者是用来执行具体请求,比如我想要打印,就调用这个类把打印命令类传进去


// 请求者类
public class Invoker {
    private Command command;

    public Invoker(Command command) {
        this.command = command;
    }

    public void action() {
        command.execute();
    }

}

使用,Receiver (接受者)就好像是做事的人,Command就是命令,而Invoker更像一个调度者,我们把命令传给invoker,他来执行具体的请求,其实就是把请求转发给了receiver去做事。


 //一层一曾构造,命令对象根据接受者构造,请求者根据具体的命令对象构造
Receiver receiver = new Receiver();
Command printCommand = new PrintCommand(receiver);
Invoker invoker = new Invoker(printCommand);
//执行请求方法 即打印
invoker.action();
//执行copy方法只需要重新构造即可,接受者对象无需重新构造
Command copyCommand = new PrintCommand(receiver);
Invoker invoker = new Invoker(copyCommand);
//执行请求方法 即复制
invoker.action();

总结

写完这些类其实我是很累的,明明一个类就可以解决硬是写出了这么多类,这其实就是这个类最大的毛病了,类极度膨胀,但是不可否认更加灵活耦合度更低了,这就是我们想要的,在我们实际中,请求-响应模式的功能非常常见,一般来说,我们会把对请求的响应操作封装到一个方法中,这个封装的方法可以称之为命令,就好像开头我说的没学习设计模式之前的解决方案,但不是命令模式。到底要不要把这种设计上升到模式的高度就要另行考虑了,因为,如果使用命令模式,就要引入调用者、接收者两个角色,原本放在一处的逻辑分散到了三个类中,设计时,必须考虑这样的代价是否值得。

猜你喜欢

转载自blog.csdn.net/HJsir/article/details/80300759