设计模式 之 命令

33 篇文章 10 订阅
17 篇文章 0 订阅

命令模式(Command):

        将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持科撤销的操作。


        你写过信吗?你去邮局寄过信吗?你写的第一封信是寄给谁的呢?日常生活中的邮局,可能已经成为人们眼中的一道风景线,现在已经很少有人使用信件交流传递感情。然而邮局作为一个发信人和收信人的中转机构,它的作用不容小觑,省去了发信人与收信人的直接交流,为发信人和收信人传递消息。今天我们就来重温一下信纸、邮局时代...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Command
{
    //信件接收者接口
    public interface IReceiver
    {
        //收件人收到信件读取
        void readMail(String message);
    }

    //信件接收者
    public class Receiver : IReceiver
    {
        public void readMail(String message)
        {
            Console.WriteLine("收件人读取信件:" + message);
        }
    }

    //邮局接口
    public interface IPost
    {
        //邮局发送信件
        void sendMail(String message);
    }
    public class Post : IPost
    {
        private IReceiver receiver;

        public Post(IReceiver receiver)
        {
            this.receiver = receiver;
        }

        public void sendMail(string message)
        {
            Console.WriteLine("邮局将信件发给收信人...");
            this.receiver.readMail(message);
        }
    }

    //发信人
    public class Invoker
    {
        private IPost post;

        public void setPost(IPost post)
        {
            this.post = post;
        }

        //发信人发送信件
        public void postMail(string message)
        {
            Console.WriteLine("发信人投递信件给邮局...");
            this.post.sendMail(message);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Receiver receiver = new Receiver();
            IPost post = new Post(receiver);
            Invoker invoker = new Invoker();

            invoker.setPost(post);
            invoker.postMail("您好,好久不见,最近工作忙吗?");
        }
    }
}



类图:

                                                      



命令模式包含如下几个角色:
    Command(抽象命令角色):声明命令执行操作的接口。
    Concrete Command(具体命令角色):在具体的命令角色中绑定命令接收者,命令调用接收者做出相应的操作,从而实现命令角色声明的执行操作的接口行为。
    Invoker(请求者角色):命令的启动者角色,调用命令对象执行请求。
    Receiver(接收者角色):具体命令执行时的行为对象,任何类都可能作为一个接收者。
    Client(客户角色):创建一个具体命令对象,并分配命令的接收者。


主要优点:

    1.降低系统的耦合度。
    2.可以比较容易地设计一个命令队列或宏命令(组合命令)。
    3.为请求的撤销(Undo)和恢复(Redo)操作提供了一种设计和实现方案。


主要缺点:

    使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个对请求接收者的调用操作都需要设计一个具体命令类,因此在某些系统中可能需要提供大量的具体命令类,这将影响命令模式的使用。


使用场合:

    1.抽象出待执行的动作以参数化某对象。类似于过程设计中的回调机制,而命令模式正是回调机制的一个面向对象的替代品。
    2.在不同的时刻指定、排列和执行请求。
    3.需要支持可撤销的操作。
    4.需要支持修改日志功能,这样当系统崩溃时,这些修改可以被重做一遍。




相关模式:

    1.组合:在使用宏命令时,我们会用到组合模式。
    2.备忘录:可以用来存储命令的效果状态信息,用于命令的撤销和恢复功能。








命令模式是一种行为型设计模式,它将请求封装成一个对象,从而使得请求的发送者和接收者解耦。在命令模式中,请求以命令的形式包裹在对象中,并传递给调用对象。调用对象寻找可以处理该命令的合适的对象,并将命令传递给相应的对象,该对象执行命令。 在C语言中,可以使用函数指针来实现命令模式。具体步骤如下: 1. 定义一个命令接口,该接口包含一个执行命令的方法。 2. 创建具体的命令类,实现命令接口,并在执行方法中调用相应的函数。 3. 创建一个调用者类,该类包含一个命令对象,并提供一个执行命令的方法。 4. 在调用者类中,将命令对象传递给相应的对象,并调用命令对象的执行方法。 下面是一个简单的示例代码: ```c #include <stdio.h> // 定义命令接口 typedef struct { void (*execute)(void); } Command; // 创建具体的命令类 typedef struct { Command command; void (*function)(void); } ConcreteCommand; void concreteCommand_execute(void) { printf("执行具体的命令\n"); } // 创建调用者类 typedef struct { Command *command; void (*setCommand)(Command *command); void (*executeCommand)(void); } Invoker; void invoker_setCommand(Command *command) { Invoker *invoker = (Invoker *)command; invoker->command = command;} void invoker_executeCommand(void) { Invoker *invoker = (Invoker *)invoker->command; invoker->command->execute(); } int main() { // 创建具体的命令对象 ConcreteCommand concreteCommand; concreteCommand.command.execute = concreteCommand_execute; concreteCommand.function = concreteCommand_execute; // 创建调用者对象 Invoker invoker; invoker.setCommand((Command *)&concreteCommand); invoker.executeCommand(); return 0; } ```
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值