IT知识库 购物 网址 游戏 小说 歌词 快照 开发 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 编程 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> .NET新手区 -> 设计模式(10) -> 正文阅读

[.NET新手区]设计模式(10)

设计模式(10) 一、引言:
  路边有一个烤肉摊,有一位老板负责给客人烧烤食物。如果客人很少,老板都能准确记住大家的要求,随着客人的增多,要求越来越多,老板很难满足大家要求,老板应该怎么办?
首先说明为什么客人多了,老板满足不了大家的要求,因为“用程序猿的话说是因为:紧耦合”。松耦合就能很好的解决此问题,也就是本文介绍的命令模式。先给出紧耦合代码:


class Program
    {
        static void Main(string[] args)
        {
            Receiver receiver = new Receiver();
            receiver.BakeChickenWing();

            Console.Read();
        }
    }

    public class Receiver//boss
    {
        public void BakeMutton()
        {
            Console.WriteLine("bake mutton");
        }

        public void BakeChickenWing()
        {
            Console.WriteLine("bake chickenwing");
        }
    }

View Code
二、定义:
命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销操作。
解释:将请求命令封装为一个对象,并用日志记录下来,其中它支持命令撤销功能。
三、UML图及基本代码:

基本代码:

class Receicer
    {
        public void Action()
        {
            Console.WriteLine("执行请求");
        }
    }

    abstract class Command
    {
        protected Receicer receiver;

        public Command(Receicer receiver)
        {
            this.receiver = receiver;
        }

        abstract public void Execute();
    }

    class ConcreteCommand : Command
    {
        public ConcreteCommand(Receicer receiver)
            : base(receiver)
        { }

        public override void Execute()
        {
            receiver.Action();
        }
    }

    class Invoker
    {
        private Command command;

        public void SetCommand(Command command)
        {
            this.command = command;
        }

        public void ExecuteCommand()
        {
            command.Execute();
        }
    }

调用:

Receicer receiver = new Receicer();
            Command command = new ConcreteCommand(receiver);
            Invoker invoker = new Invoker();
invoker.SetCommand(command);

invoker.ExecuteCommand();

解释:映射客人到酒店就餐。Receiver是命令的接收者,相当于酒店中的大厨;Command命令抽象类,ConcreteCommand是具体的命令,相当于点菜请求,命令中应该包含命令的接收者。Invoke是命令的传达者,相当于酒店的服务员,负责记录客人点菜请求,并传达给后厨。
四、举例说明:
 学校高一学生进行军训,校长发布让学生跑10000米的命令。整个过程:校长发布命令给军训教官,教官传达校长命令给学生,学生接收到命令后执行相应的操作。在下面实例中,Receiver是学生,操作跑10000米的命令。Command是命令,必需知道命令的接收者。Drillmaster是教官,教官必需知道命令是什么,并传达命令。


//校长发布学生跑1000米的命令,教官传达此命令给学生,学生是命令的接收者
    //客户端:校长,命令的发出者必须知道具体的命令、接受者、传达命令者
    class Program
    {
        static void Main(string[] args)
        {
            Receiver receiver = new Receiver();
            Command command = new ConcreteCommand(receiver);
            Drillmaster drillmaster = new Drillmaster(command);
            drillmaster.ExecuteCommand();

            Console.Read();
        }
    }

    //命令接收者
    public class Receiver
    {
        public void Run1000Meters()
        {
            Console.WriteLine("跑10000米");
        }
    }

    //抽象命令
    public abstract class Command
    {
        protected Receiver receiver;

        public Command(Receiver receiver)
        {
            this.receiver = receiver;
        }

        public abstract void Action();
    }

    //具体的命令,必须知道命令接受者
    public class ConcreteCommand : Command
    {
        public ConcreteCommand(Receiver receiver)
            : base(receiver)
        { }

        public override void Action()
        {
            receiver.Run1000Meters();
        }
    }

    //教官:命令的传达者,负责调用命令对象的方法来保证命令执行
    public class Drillmaster
    {
        public Command command;

        public Drillmaster(Command command)
        {
            this.command = command;
        }

        public void ExecuteCommand()
        {
            command.Action();
        }
    }

View Code
五、解决引言中的问题
客人点菜命令的接收者,老板(大厨):

public class Receiver
    {
        public void BakeMutton()
        {
            Console.WriteLine("bake mutton");
        }

        public void BakeChickenWing()
        {
            Console.WriteLine("bake chickenwing");
        }
    }

点菜命令:

public abstract class Command
    {
        protected Receiver receiver;

        public Command(Receiver receiver)
        {
            this.receiver = receiver;
        }

        abstract public void Execute();
    }

    class ConcreteCommand1 : Command
    {
        public ConcreteCommand1(Receiver receiver)
            : base(receiver)
        { }

        public override void Execute()
        {
            receiver.BakeMutton();
        }
    }

    class ConcreteCommand2 : Command
    {
        public ConcreteCommand2(Receiver receiver)
            : base(receiver)
        { }

        public override void Execute()
        {
            receiver.BakeChickenWing();
        }
    }

增加一个服务生,负责记录客人点菜命令,并传达给大厨。点菜命令可以进行增加或取消操作。

public class Invoker
    {
        private IList<Command> commands = new List<Command>();

        public void AddCommand(Command command)
        {
            commands.Add(command);
            Console.WriteLine("增加订单" + command.ToString());
        }

        public void CancelCommand(Command command)
        {
            commands.Remove(command);
            Console.WriteLine("取消订单" + command.ToString());
        }

        public void ExecuteCommand()
        {
            foreach (Command command in commands)
            {
                command.Execute();
            }
        }
    }

客户端调用:

Receiver receiver = new Receiver();
            Command command1 = new ConcreteCommand1(receiver);
            Command command2 = new ConcreteCommand2(receiver);
            Invoker invoker = new Invoker();

            invoker.AddCommand(command1);
            invoker.AddCommand(command2);
            invoker.CancelCommand(command1);
            invoker.ExecuteCommand();

六、优缺点及适用场景
优点:
比较容易的设计一个命令队列;在需要的情况下,可以比较容易的将命令计入日志;允许接收请求的一方决定是否要否决请求;比较容易的对命令实现撤销和重做;由于加入新的具体命令类不影响其他的类,因此增加新的具体命令类比较容易。
缺点:
可能会导致系统具有过多的具体命令类。
适用场景:
个人理解:基本上能表现其优点的地方都可以使用命令模式。
上一篇文章      下一篇文章      查看所有文章
加:2015-03-29 20:35:22  更:2017-05-14 05:11:06 
 
  .NET新手区 最新文章
将ZIP文件添加到程序集资源文件然后在运行时
Web服务的调用
.NET创建WebService服务简单的例子
多线程编程学习笔记——任务并行库(三)
序列化和反序列化
Spring学习之路
多线程(2)Thread
五小步让VS Code支持AngularJS智能提示
Log4net入门(SQL篇)
C#十五子游戏
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 新闻资讯 小游戏 Chinese Culture 股票 三丰软件 开发 中国文化 网文精选 阅读网 看图 日历 万年历 2018年11日历
2018-11-20 2:22:11
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库