二、18【设计模式】之迭代器模式

今天的博客主题

       设计模式 ——》 设计模式之迭代器模式


命令模式   CP  (Command Pattern)

 

定义

将一个请求封装成一个对象,使不同的请求把客户端参数化。

命令模式是对命令的封装,每一个命令都对应了一个操作:请求方发出命令,接收方执行命令对应的操作。主要是解耦了请求方和接收方,请求方只需关心请求执行的命令,而不关心命令怎么被接收以被处理的。

现在写出的代码都是请求者与实现者通常都是一种紧耦合的关系,这样更简单明了,但缺乏扩展性。不适合在某些场合使用(行为记录,撤销等)。命令模式可以通过请求与实现中间引入一个抽象的命令接口,解耦了请求与实现,中间也是抽象的,可以有不同的子类,扩展性好。

命令模式其主要本质是解耦命令的请求与处理。

 

其精髓是把行为封装成对象!!!

 

应用场景

1)语义中具备命令的操作(如shell命令,命令菜单)。

2)调用方与接收方需要解耦,不直接交互。

3)需要抽象出等待的行为,比如撤销(Undo)和恢复(Redo)等操作。

4)支持命令组合操作。

5)

 

优点

1)通过引入抽象接口,可以很好的解耦命令请求与实现。

2)扩展性良好,可以很方便的新增命令。

3)支持组合命令,支持命令队列。

4)可在现有命令的基础上,增加额外功能

5)

 

缺点

1)具体的命令类可能过多。

2)增加代码理解难度(解耦请求与实现,引入额外类型结构)

3)

 

源码中应用

public interface Runnable {
    public abstract void run();
}

Runnable 相当于一个命令的抽象,实现了该抽象的接口都被认为一个线程。调用线程的 start() 方法之后才有资格获取 CPU 资源,不需要我们来实现去获取 CPU 资源的逻辑。在抢到 CPU 资源之后,执行 run() 方法中的内容。可以发现 Runnable 接口把用户请求和CPU执行进行了解耦。

代码示例

命令模式主要包含四种角色

接收者角色(Receiver):负责实施执行一个请求,也就是具体的命令实现。

抽象命令角色(Command):定义需要执行的所有命令。

具体命令角色(ConcreteCommand):维护一个接收者,在其执行命令方法中调用接收者的相关方法。

请求者角色(Invoker):接收客户端命令,并执行命令,维护抽象命令角色。

/**
 * 场景:游戏里的人物进行移动,发出命令,人物做出相应的动作(w前进s后退a左移d右移)
 * 人物攻击同样是发出命令,人物做出响应的动作(q狱血魔神e噬魂r大闹天宫) 【请自行实现呦】
 */

// 抽象命令类,只有实现了抽象命令类的具体命令才与请求者关联。最简单的抽象命令类中只包含了一个抽象的execute()方法
interface Command{
    void execute();
}

// 具体命令类
class MoveForwardConcreteCommand implements Command {

    private MoveForwardReceiver moveForwardReceiver;

    public MoveForwardConcreteCommand(MoveForwardReceiver moveForwardReceiver){
        this.moveForwardReceiver = moveForwardReceiver;
    }

    @Override
    public void execute() {
        moveForwardReceiver.forward();
    }
}
class MoveBackOffConcreteCommand implements Command {

    private MoveBackOffReceiver moveBackOffReceiver;

    public MoveBackOffConcreteCommand(MoveBackOffReceiver moveBackOffReceiver){
        this.moveBackOffReceiver = moveBackOffReceiver;
    }

    @Override
    public void execute() {
        moveBackOffReceiver.backoff();
    }
}
class MoveLeftCommandConcreteCommand implements Command{

    private MoveLeftReceiver moveLeftReceiver;

    public MoveLeftCommandConcreteCommand(MoveLeftReceiver moveLeftReceiver){
        this.moveLeftReceiver = moveLeftReceiver;
    }

    @Override
    public void execute() {
        moveLeftReceiver.left();
    }
}
class MoveRightCommandConcreteCommand implements Command{

    private MoveRightReceiver moveRightReceiver;

    public MoveRightCommandConcreteCommand(MoveRightReceiver moveRightReceiver){
        this.moveRightReceiver = moveRightReceiver;
    }

    @Override
    public void execute() {
        moveRightReceiver.right();
    }
}

// 请求的接收者,也就是具体的命令实现
class MoveForwardReceiver{
    public void forward(){
        System.out.println("前进");
    }
}
class MoveBackOffReceiver{
    public void backoff(){
        System.out.println("后退");
    }
}
class MoveLeftReceiver{
    public void left(){
        System.out.println("左移");
    }
}
class MoveRightReceiver{
    public void right(){
        System.out.println("右移");
    }
}

// 请求发送者
class Invoker{

    private Command command;

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

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

// 客户端调用
public class CommandPatternSample {
    public static void main(String[] args) {
        // 使用一种策略来维护命令集合
        Map<String, Invoker> maps = new HashMap<>();
        maps.put("w", new Invoker(new MoveForwardConcreteCommand(new MoveForwardReceiver())));
        maps.put("s", new Invoker(new MoveBackOffConcreteCommand(new MoveBackOffReceiver())));
        maps.put("a", new Invoker(new MoveLeftCommandConcreteCommand(new MoveLeftReceiver())));
        maps.put("d", new Invoker(new MoveRightCommandConcreteCommand(new MoveRightReceiver())));

        Scanner scan = new Scanner(System.in);
        while (scan.hasNextLine()) {
            String command = scan.nextLine();
            if(maps.containsKey(command)){
                maps.get(command).call();
            }
        }
        scan.close();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值