Command 命令模式

>>返回《C#常用设计模式》

1. 简介

方法调用封装起来: 通过封装方法调用,可以把运算块封装成形,所以调用此运算对象不需要知道事情是如何进行的。通过封装方法调用,可以实现一些很聪明的事,比如日志记录。

  • 类图

    其中提到的一个Command,可能为多个
  • 日志的封装
    • Ilogger就是Invoker
    • ILogger中的info、warn等方法就是执行的Command
    • Receiver就是对应:FileWriter、DBWriter

2. 示例


//遥控器 Invoker
public class RemoteControl
{
    private readonly ICommand _onCommand;
    private readonly ICommand _offCommand;

    public RemoteControl()
    {
        var noCommand = new NoCommand();
        _onCommands = noCommand;
        _offCommands = noCommand;
    }

    public void SetCommand(ICommand onCommand, ICommand offCommand)
    {
        _onCommand = onCommand;
        _offCommand = offCommand;
    }

    public void OnButtonWasPushed()
    {
        _onCommand.Execute();
    }

    public void OffButtonWasPushed()
    {
        _offCommand.Execute();
    }
}

//Command
public interface ICommand
{
    void Execute();
    void Undo();
}

//NoCommand对象是一个空对象,当你不想返回一个有意义的对象时,空对象就很有用
public class NoCommand : ICommand
{
    public void Execute()
    {
        Console.WriteLine("No command was executed!");
    }
    public void Undo()
    {
        Console.WriteLine("No command was executed!");
    }
}

//ConcreteCommand
public class LightOffCommand : ICommand
{
    private readonly Light _light;

    public LightOffCommand(Light light)
    {
        _light = light;
    }

    public void Execute()
    {
        _light.Off();
    }

    public void Undo()
    {
        _light.On();
    }
}
public class LightOnCommand : ICommand
{
    private readonly Light _light;//这个字段就是ConcreteCommand中的一个Receiver,多用组合少用继承!

    public LightOnCommand(Light light)
    {
        _light = light;
    }

    public void Execute()
    {
        _light.On();
    }

    public void Undo()
    {
        _light.Off();
    }
}

//Receiver
public class Light
{
    public void On()
    {
        Console.WriteLine("light's on");
    }

    public void Off()
    {
        Console.WriteLine("light's off");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var control = new RemoteControl();
        var light = new Light();
        var lightOnCommand = new LightOnCommand(light);
        var lightOffCommand = new LightOffCommand(light);

        control.SetCommand(lightOnCommand, lightOffCommand);
        control.OnButtonWasPushed();
        Console.ReadKey();
    }
}
posted @ 2021-02-17 22:33  大师兄石头  阅读(204)  评论(0编辑  收藏  举报