设计模式学习之一个命令就可以搞定

命令模式定义:

        命令模式是一种高内聚的模式,将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。在命令模式中,低层模块对高层模块是不可见的,高层模块对于低层模块的调用都通过命令接收者,降低了两个模块的间的耦合性。命令接收者,将命令请求封装成一个执行方法,命令者只需要下达命令到接收者,就可以达到想要的结果。

通用命令模式框架:

  • Receive接收者角色该角色就是干活的角色,命令传递到这里是应该被执行的,具体到我们上面的例子中就是Group的三个实现类。
  • Command命令角色需要执行的所有命令都在这里声明。
  • Invoker调用者角色接收到命令,并执行命令。

命令模式实现:

需求:装修房子是一个大工程,需要不同的工种配合,有水电工,泥瓦工,还有木工,如果每次都需要亲自找工人会耗费很多精力和时间,这时候包工头的角色出现了,只需要把你的需求命令下达到包工头,那么剩下的事就靠包工头来完成了。

设计思路:抽象工人类Worker实现公共方法,然后根据工种不同实现不同的工人类,命令类Command,接收业主下达的命令,包工头ContractorInvoker,接收业主下发的命令,并依照业务的需求命令对应的工人去执行。

代码实现如下:

/**
 *命令模式
 * 工人抽象类
 *
 */
public abstract class Worker {
    //每个工人的工作
    protected  abstract void work();
    //会做也会拆
    protected abstract void rollback();
}

/**
 * 命令模式
 * 泥瓦工
 */
public class BricklayWorker  extends Worker{
    @Override
    protected void work() {
        System.out.println("泥瓦匠砌了一道墙");
    }

    @Override
    protected void rollback() {
        System.out.println("泥瓦匠拆了一道墙");
    }
}
/**
 * 命令模式
 * 木工
 */
public class CarpentryWorker extends Worker{
    @Override
    protected void work() {
        System.out.println("做一个壁橱");
    }

    @Override
    protected void rollback() {
        System.out.println("拆了壁橱");
    }
}

/**
 * 命名模式
 * 电工
 */
public class ElectricianWorker extends Worker {
    @Override
    protected void work() {
        System.out.println("换个灯泡");
    }

    @Override
    protected void rollback() {
        System.out.println("换回去");
    }
}

/**
 * 命令模式
 * 接收命令抽象类
 */
public abstract class Command {
    protected  BricklayWorker bricklayWorker = new BricklayWorker();//泥瓦工
    protected  CarpentryWorker carpentryWorker = new CarpentryWorker();//木工
    protected  ElectricianWorker electricianWorker = new ElectricianWorker();//电工
    //接收命令
    protected abstract void excute();
}
/**
 * 命令模式
 * 泥瓦工的命令接收类
 */
public class BricklayComand  extends Command{
    @Override
    protected void excute() {
        super.bricklayWorker.work();
    }
}

/**
 * 命令模式
 * 木工接收命令类
 */
    public class CarpentryComand extends Command{
    @Override
    protected void excute() {
        System.out.println("木匠打了个壁橱");
    }
}

/**
 * 命令模式
 * 拆除
 */
public class RollBackComand extends Command {
    @Override
    protected void excute() {
        super.bricklayWorker.rollback();
    }
}

/**
 * 命令模式
 * 包工头类
 */
public class ContractorInvoker {
    //命令类
    private Command command;

    //接收命令
    public void setCommand(Command command) {
        this.command = command;
    }
    //执行命令
    public void action(){
        command.excute();
    }
}

/**
 * 业务类
 */
public class Business {
    public static void main(String[] args) {
        System.out.println("业务主说:给我砌道墙");
        ContractorInvoker contractorInvoker = new ContractorInvoker();
        //泥瓦工命令
        BricklayComand bricklayComand = new BricklayComand();
        contractorInvoker.setCommand(bricklayComand);
        contractorInvoker.action();
        System.out.println("业务主说:给我打个壁橱");
        //木工命令
        CarpentryComand carpentryComand = new CarpentryComand();
        contractorInvoker.setCommand(carpentryComand);
        contractorInvoker.action();
        System.out.println("业务主说:不喜欢这道墙,给我拆了");
        //拆墙命令
        RollBackComand rollBackComand = new RollBackComand();
        contractorInvoker.setCommand(rollBackComand);
        contractorInvoker.action();

    }
}

//执行结果
业务主说:给我砌道墙
泥瓦匠砌了一道墙
业务主说:给我打个壁橱
木匠打了个壁橱
业务主说:不喜欢这道墙,给我拆了
泥瓦匠拆了一道墙

从代码中可以看出,业主Business并没有和工人Worker直接交流,他只需要下达命令Command并传递给包工头ContractorInvoker,包工头会去执行业务的命令,命令工人去工作。而根据命令的不同很容易扩展出一个命令类。而工种由于定义了抽象类,也很容易进行扩展。

总结:

命令模式的优点:

  • 类间解耦:调用层和接收层没有交互,调用者实际调用的是Command的excute方法,完全不知道真正的执行者,完成了解耦。
  • 可扩展性:Command的类的可扩展性强,调用者和Client由于通过父类传递,没有过度耦合。

命令模式的缺点:

  • 缺点也是Command的类随着命令的增多而越来越多

参考《设计模式之禅》秦小波著

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值