五分钟一个设计模式之命令模式

五分钟一个设计模式,用最简单的方法来描述设计模式。

小米智能模块的例子

前一段小米的老总雷军在印度的全英文演讲想必大家都还历历在目,不过今天我们讨论的主题不是那次演讲,而是小米智能模块。小米4发布时,雷军说,小米已经开发了一个智能模块,只要电器厂商将这个智能模块集成到自家的电器中,就可以用小米手机来控制它,并且小米智能模块才22块钱。是不是一件很牛X的事情?这个事情,从宏观上来看,通过小米手机来控制所有集成了智能模块的电器,就是使用了命令模式!下面我们来模拟一下这个事情。

首先,有一些家用电器的厂商,他们能控制自家的电器的开关。

/// <summary>
/// 大灯
/// </summary>
public class Light
{
    public void LightOn()
    {
        Console.WriteLine("灯亮了");
    }
    public void LightOff()
    {
        Console.WriteLine("灯灭了");
    }
}
/// <summary>
/// 热水器
/// </summary>
public class Heater
{
    public void HeaterOn()
    {
        Console.WriteLine("加热中");
    }
    public void HeaterOff()
    {
        Console.WriteLine("停止加热");
    }
}
/// <summary>
/// 冰箱厂商提供的api
/// </summary>
public class Fridge
{
    public void FridgeOn()
    {
        Console.WriteLine("冰箱开了");
    }
    public void FridgeOff()
    {
        Console.WriteLine("冰箱关了");
    }
}
}

这么多个厂商,小米手机怎么能控制他们呢?让他们实现相同的类吗?这就要求所有厂商修改自家的类,他们肯定不愿意。这就会用到一个新的概念,组合。小米手机提供一个统一的智能模块,这个智能模块和各厂商的类组合到一块,然后小米手机直接控制智能模块就OK了。智能模块到底是什么呢,它包含了很多个定义好的类每一个类控制一种家用电器,如,大灯控制器,热水器控制器,冰箱控制器,电视控制器,小米盒子控制器,等等各种控制器。每一种具体的控制器都能在小米手机的控制器应用中找到一个对应的按钮。

下面来看看这个智能模块到底是什么。它是一组类,实现了同一个接口 ICommand

public interface ICommand
{
    void Execute();
}

下面是智能控制模块中庞大的一组类,我们来列举几个

大灯控制器

public class LightOnCommand : ICommand
{
    Light light;
    public LightOnCommand(Light light)
    {
        this.light = light;
    }
    public void Execute()
    {
        light.LightOn();
    }
}
class LightOffCommand : ICommand
{
    Light light;
    public LightOffCommand(Light light)
    {
        this.light = light;
    }
    public void Execute()
    {
        this.light.LightOff();
    }
}

加热器控制器

public class HeaterOnCommand : ICommand
{
    Heater heater;
    public HeaterOnCommand(Heater heater)
    {
        this.heater = heater;
    }
    public void Execute()
    {
        this.heater.HeaterOn();
    }
}
public class HeaterOffCommand : ICommand
{
    Heater heater;
    public HeaterOffCommand(Heater heater)
    {
        this.heater = heater;
    }
    public void Execute()
    {
        this.heater.HeaterOff();
    }
}

类太多了,不列举了。所有的类都有这样的特点:

  1. 实现了ICommand接口
  2. 一个请求(或命令)就是一个类
  3. 不直接执行命令,而是由跟它组合的具体电器对象来执行命令

有了这个智能模块,小米手机的调用就简单了

class Program
{
    static void Main(string[] args)
    {

        //厂商开发电器
        Light light = new Light();
        Heater heater = new Heater();

        //厂商将自家电器集成小米智能模块
        LightOnCommand lightOnCommand = new LightOnCommand(light);
        LightOffCommand lightOffCommand = new LightOffCommand(light);

        HeaterOnCommand heaterOnCommand = new HeaterOnCommand(heater);
        HeaterOffCommand heaterOffCommand = new HeaterOffCommand(heater);

        //小米手机很方便地调用
        lightOnCommand.Execute();
        lightOffCommand.Execute();

        heaterOnCommand.Execute();
        heaterOffCommand.Execute();
    }
}

程序的运行结果是:

灯亮了

灯灭了

加热中

停止加热

认识命令模式

看到了命令模式的强大,下面我们来认识一下命令模式

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

命令模式的关键之处把每一个具体的请求都封装成了一个对象,即命令对象,这些请求实现了同一个接口,而且还不亲自执行具体任务。每一个命令对象都和命令的具体执行者组合在一起,由命令的具体执行者来执行命令。

在上面的例子中,小米智能模块中的每一个类,都是命令对象,他们实现了同一个接口,跟具体电器组合,在Execute方法中调用电器的方法来执行任务。小米手机通过ICommand接口控制智能模块,智能模块调用具体的电器来完成开或关。

关于撤销,也不难实现。在我们的ICommand接口中,只定义了一个Execute方法,我们只需要加入一个Undo方法,让所有的命令对象去实现就好了。这样子的话,在客户端得到的命令对象就可以直接调用Undo方法了。

用命令模式来分析完小米智能盒子后,我想问你:Are you OK ?

时间: 2024-10-12 16:07:09

五分钟一个设计模式之命令模式的相关文章

五分钟一个设计模式之代理模式

五分钟一个设计模式,用最简单的方法来描述设计模式. 认识代理模式 代理模式是通过创建一个代理对象,用这个代理对象去代表真实的对象,客户端得到这个代理对象后,就想得到了真实的对象一样.客户端调用代理对象来执行任务,但任务实际上最重还是由真实对象完成的. 代理模式的本质是控制对象的访问. 代理模式包含以下几部分: Subject:目标接口 RealSubject:具体的目标对象,继承自Subject Proxy:代理对象,继承自Subject,使用Proxy可以代替使用RealSubject. 示例

五分钟一个设计模式之创建者模式

五分钟一个设计模式,用最简单的方法来描述设计模式. 认识创建者模式 创建者模式(又叫生成器模式)是为创建一个产品而生的,这个产品的组装算法是确定的,但零部件可以分配给多个厂商生产.使用创建者模式来创建产品,可以把产品零部件的生产和组装分开了. 创建者模式包含以下几个部分: 产品(Product) 厂商的接口(Builder) 具体的厂商(ConcreteBuilder1.ConcreteBuilder2.-ConcreteBuilderN),实现厂商接口,负责产品零部件的生产工作 指导者(Dir

五分钟一个设计模式之策略模式

五分钟一个设计模式,用最简单的方法来描述设计模式. 开发一个小游戏 还是先来看个例子吧. 有一天老板一拍脑袋,想做一个游戏,于是把你找来,告诉你他的想法: 做一个最简单的闯关游戏,每个关卡都有一些小怪兽,而游戏的角色通过打死所有小怪兽来通关 角色可以使用武器,先做三四个简单的武器,有一般的武器,有厉害的武器,每个武器的伤害值不一样 游戏过程中,角色可以更换武器 先做一个角色,以后可能增加新角色,但不同角色之间的区别现在还没想好. 你作为这个新游戏的主程序员,要做的就是使程序的架构足够灵活,能够为

五分钟一个设计模式之装饰器模式

五分钟一个设计模式,用最简单的方法来描述设计模式.查看更多设计模式,请点击五分钟一个设计模式系列 http://blog.csdn.net/daguanjia11/article/category/3259443 示例代码 今天实在是想不出什么开场白来引出示例了,也想不出特别有意思的示例了,就用一个很土的例子来描述一下装饰器模式吧. 每个人都要穿衣服,每件衣服都具有某些特定的功能,例如,穿上鞋子的话走路舒服,穿上上衣的话上身不冷,穿上裤子的话腿不冷(你这不废话吗).也就是说,每件衣服都具有特定的

五分钟一个设计模式之责任链模式

五分钟一个设计模式,用最简单的方法来描述设计模式.查看更多设计模式,请点击五分钟一个设计模式系列 http://blog.csdn.net/daguanjia11/article/category/3259443 请假流程 假设现在一个公司的请假流程如下:一天及以下由小组组长审批,一天以上三天以下由经理审批,三天以上七天以下由老板审批,七天以上直接劝退. 如果每次请假时都很长的if-else-来判断该去找谁请假,很不容易扩展,我们使用责任链模式来实现. 首先,是一个抽象的父类 public ab

五分钟一个设计模式之单例模式

五分钟一个设计模式,用最简单的方法来描述设计模式. 认识单例模式 单例模式是一个非常简单的设计模式,它的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点 有些数据库操作类或者工具类会使用单例模式. 示例代码 public class Singleton { //将构造函数声明为private,防止外界直接通过构造函数来创建对象,只能在类内部创建对象 private Singleton() { } private static Singleton uniqueInstance; pub

五分钟一个设计模式之观察者模式

五分钟一个设计模式,用最简单的方法来描述设计模式. 认识观察者模式 观察者模式的定义是:定义对象间的一种一对多的依赖关系.当一个对象的状态发生变化时,所有依赖它的对象都会得到通知并自动更新 报社跟读者的例子 我们用报社和读者之间的关系来模拟观察者模式. 包含以下主体: 报社(NewspaperOffice) 读者接口(Reader) 具体读者(Reader_二逼青年.Reader_文艺青年) Reader_二逼青年.Reader_文艺青年实现Reader接口,并订阅报纸,报社有新报纸时,会通知所

五分钟一个设计模式之适配器模式

五分钟一个设计模式,用最简单的方法来描述设计模式.查看更多设计模式,请点击五分钟一个设计模式系列 http://blog.csdn.net/daguanjia11/article/category/3259443 认识适配器模式 适配器模式的定义是:将一个类的接口转换成客户端希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器模式的主要功能是转换接口,目的是复用已有功能,而不是实现新接口,适用于功能实现了但接口不兼容的场合.适配器组合了原有对象,并且提

每天一个设计模式之命令模式

作者按:<每天一个设计模式>旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现.诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) 原文地址是:<每天一个设计模式之命令模式> 欢迎关注个人技术博客:godbmw.com.每周 1 篇原创技术分享!开源教程(webpack.设计模式).面试刷题(偏前端).知识整理(每周零碎),欢迎长期关注! 如果您也想进行知识整理 + 搭建功能完善/设计简约/快速启动的个人博客,请直接戳the