“戏”说设计模式——命令模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wfy2695766757/article/details/86372755

首先请出今天的主人公——“人工智能”智能家电控制器

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

现在我们做一个简单的控制器,假如它只有三个功能:显示使用物品名、开、关。

public interface Switch {

    public void nameOfThing();//物品名称

    public void on();//开

    public void off();//关
}

 两个可以实现功能的家电:电视、电灯。

public class TV implements Switch{//电视
    @Override
    public void nameOfThing() {
        System.out.println("您正在操作电视");
    }
    @Override
    public void on() {
        System.out.println("电视显示画面");
    }
    @Override
    public void off() {
        System.out.println("电视画面消失");
    }
}

public class lamp implements Switch {//电灯
    @Override
    public void nameOfThing() {
        System.out.println("您正在操作灯");
    }
    @Override
    public void on() {
        System.out.println("灯亮");
    }
    @Override
    public void off() {
        System.out.println("灯灭");
    }
}

那么设计到这就结束了?那就太过简单了,做一个合格的程序猿应该具备实现“解耦”,所以我们加入了“一键启动”和“一键关闭”两个方法

public class Switcher {
    private Switch aSwitch;
    public void setaSwitch(Switch aSwitch) {
        this.aSwitch = aSwitch;
    }
    public void nameOut(){
        aSwitch.nameOfThing();
    }
    public void buttonOnClick(){
        System.out.println("点击【开】");
        aSwitch.on();
    }
    public void buttonOffClick(){
        System.out.println("点击【关】");
        aSwitch.off();
    }
}

在第三行中,我们引入了接口类,然后实现了名字显示、“一键启动”、“一键关闭”功能。

在客户使用时,就直接“傻瓜式”的操作即可

public class Client {//客户使用端
    public static void main(String[] args) {
        Switcher switcher = new Switcher();//创造一个可以使用的控制器
        switcher.setaSwitch(new TV());//控制器上连接电视
        switcher.nameOut();
        switcher.buttonOnClick();
        switcher.buttonOffClick();
        
        switcher.setaSwitch(new lamp());//控制器连接电灯
        switcher.nameOut();
        switcher.buttonOnClick();
        switcher.buttonOffClick();
    }
}

让我们来运行一下

那么这个所谓的中央智能控制器就这么low吗?只能控制开关吗?

我们在控制开关的接口上来拓展功能,现在我们得新定义出一组”命令“接口把控制器(发令者)与设备(执行者)彻底解耦,我们在原有接口上拓展一个音量控制接口和一个温度控制接口。这样一来,你就会发现,如果一类家电都有同一功能,我们就可以用同一种方式来对物品控制,比如具有音量控制的电视、音响、收音机,有温度控制的空调、冰箱。

我们都知道家电如使用,就必须打开它,所以我们继承了开关接口,并保持了向后兼任性。

public interface TemperatureCommand extends Switch {//温度控制
    public void temperatureUp();//温度增高
    public void temperatureDown();//温度降低
}

public interface VolumeCommand extends Switch {//音量控制
    public void volumeUp();//音量增高
    public void volumeDown();//音量降低
}

我们具体一个事物:比如有温度控制的空调和有音量控制的电视

public class Air_conditioner implements TemperatureCommand {
    @Override
    public void nameOfThing() { System.out.println("您正在操作【空调】"); }
    @Override
    public void on() { System.out.println("空调开启"); }
    @Override
    public void off() { System.out.println("空调关闭"); }
    @Override
    public void temperatureUp() { System.out.println("空调温度增高【+】"); }
    @Override
    public void temperatureDown() { System.out.println("空调温度降低【-】"); }
}

public class TV implements VolumeCommand{
    @Override
    public void nameOfThing() { System.out.println("您正在操作【电视】"); }
    @Override
    public void on() { System.out.println("电视显示画面");}
    @Override
    public void off() { System.out.println("电视画面消失"); }
    @Override
    public void volumeUp() { System.out.println("电视音量增加【+】"); }
    @Override
    public void volumeDown() { System.out.println("电视音量减低【-】"); }
}

看过代码的你,是否发现如果我们都实现了这些功能,那我们的控制器上有几个按钮呢?至少8个!!!到这里,我们控制器外观设计师说了:“我们最好用一对控制键来完成一类功能”,所以我们只能由2个按钮,作为程序员的你一定要完成设计师和项目经理的任务!这是命令模式的关键

public interface Commend {
    public void Up();//增加+
    public void Down();//降低-
}

现在就ok了,只有两个了

public class Volume implements Commend {
    private VolumeCommand volumeCommand;
    public Volume(VolumeCommand volumeCommand) {
        this.volumeCommand = volumeCommand;
    }
    @Override
    public void Up() {
        volumeCommand.volumeUp();
    }
    @Override
    public void Down() {
        volumeCommand.volumeDown();
    }
}

public class Temperture implements Commend{
    private TemperatureCommand temperatureCommand;//引入温度控制接口
    public Temperture(TemperatureCommand temperatureCommand) {
        this.temperatureCommand = temperatureCommand;
    }
    @Override
    public void Up() {
        temperatureCommand.temperatureUp();
    }
    @Override
    public void Down() {
        temperatureCommand.temperatureDown();
    }
}

到这里,你会发现程序的复杂程序很大,所以需要耐心搞懂关系。然后我们做一个控制器

public class Controller  {
    private Commend commend;

    public void setCommend(Commend commend) {
        this.commend = commend;
    }
    public void buttonUpClick(){
        System.out.println("按下【+】按钮");
        commend.Up();
    }
    public void buttonDownClick(){
        System.out.println("按下【-】按钮");
        commend.Down();
    }
}

对!它只有【+】和【-】

public class ImproveClient {
    public static void main(String[] args) {
        VolumeCommand tv = new TV();
        TemperatureCommand air = new Air_conditioner();
        Controller controller = new Controller();
        //绑定命令和控制器
        controller.setCommend(new Volume(tv));
        controller.buttonUpClick();
        controller.buttonDownClick();

        controller.setCommend(new Temperture(air));
        controller.buttonUpClick();
        controller.buttonDownClick();
    }
}

这是我们改进后的客户使用端,运行一下

这样的遥控器就可以使用与老人与小孩,大大提升了性能,这就是命令模式的魅力,虽然加大了程序的复杂程度,开发者需要有较强的逻辑思维,但作为程序员的你,这还不是小菜一碟!

发令控制方与接受执行方完全被拆解开,这样每个模块都可以自由的扩展胡维护,对指令映射、设备绑定的灵活操控,最终达到解耦的效果,这才是设计模式的精髓的所在啊。

如果你觉得文章不错,加个关注吧

https://blog.csdn.net/wfy2695766757

猜你喜欢

转载自blog.csdn.net/wfy2695766757/article/details/86372755