C# 命令模式

任务描述

在这里插入图片描述

在植物大战僵尸的游戏中,植物是通过点击界面上“图片按钮”而生产的,请你用命令模式将不同植物的生产请求封装成命令对象。在此例中只有三种植物,分别是豌豆射手,雪花豌豆射手和双管豌豆射手。

输入格式:
输入第一行给出一个字符串“1,3,2,2,1,3”,表示生产植物的数量及类型,其间以半角逗号分隔。(1代表豌豆射手,2代表雪花豌豆射手,3代表双管豌豆射手)

输出格式:
在多行内输出植物生产成功的语句。

输入样例:
1,3,2,2,1,3

输出样例:
豌豆射手生产出来了
双管豌豆射手生产出来了
雪花豌豆射手生产出来了
雪花豌豆射手生产出来了
豌豆射手生产出来了
双管豌豆射手生产出来了

相关知识

为什么需要命令模式
假如你正在开发一款新的文字编辑器, 当前的任务是创建一个包含多个按钮的工具栏, 并让每个按钮对应编辑器的不同操作。 你创建了一个非常简洁的 按钮类, 它不仅可用于生成工具栏上的按钮, 还可用于生成各种对话框的通用按钮。
在这里插入图片描述

最简单的解决方案是在使用按钮的每个地方都创建大量的子类。 这些子类中包含按钮点击后必须执行的代码。
在这里插入图片描述

你很快就意识到这种方式有严重缺陷。 首先, 你创建了大量的子类, 当每次修改基类 按钮时, 你都有可能需要修改所有子类的代码。 简单来说, GUI 代码以一种拙劣的方式依赖于业务逻辑中的不稳定代码。
还有一个部分最难办。 复制/粘贴文字等操作可能会在多个地方被调用。 例如用户可以点击工具栏上小小的 “复制” 按钮, 或者通过上下文菜单复制一些内容, 又或者直接使用键盘上的 Ctrl+C 。

用命令模式解决问题
软件设计通常会将关注点进行分离。 最常见的例子: 一层负责用户图像界面; 另一层负责业务逻辑。 GUI 层负责在屏幕上渲染美观的图形, 捕获所有输入并显示用户和程序工作的结果。 当需要完成一些重要内容时 (比如计算月球轨道或撰写年度报告), GUI 层则会将工作委派给业务逻辑底层。

在这里插入图片描述

这在代码中看上去就像这样: 一个 GUI 对象传递一些参数来调用一个业务逻辑对象。 这个过程通常被描述为一个对象发送请求给另一个对象。

命令模式结构及角色
命令模式结构图

在这里插入图片描述

抽象命令(Command):定义命令的接口,声明执行的方法。
具体命令(Command1):具体命令,实现要执行的方法,它通常是“虚”的实现;通常会有接收者,并调用接收者的功能来完成命令要执行的操作。
接收者(Receiver):真正执行命令的对象。任何类都可能成为一个接收者,只要能实现命令要求实现的相应功能。
调用者(Invoker):要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
客户端(Client):命令由客户端来创建,并设置命令的接收者。

适合应用场景
(1) 如果你想要将操作放入队列中、 操作的执行或者远程执行操作, 可使用命令模式。
(2) 如果你需要通过操作来参数化对象, 可使用命令模式。
(3) 如果你想要实现操作回滚功能, 可使用命令模式。

编程要求

本关的编程任务是补全右侧代码片段中Begin至End中间的代码,但不要修改本关原有代码

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

namespace F1
{
    class Program
    {
        static void Main(string[] args)
        {
            string str=Console.ReadLine();
            string[] cmdArry = str.Split(',');
            /********** Begin *********/
            int length = cmdArry.Length;
            for (int i = 0; i < length; i++)
            {
                int type = int.Parse(cmdArry[i]);
                if (type == 1)
                {
                    //创建一个接收者
                    Peashooter peashooter = new Peashooter();
                    //创建命令对象,指定他的接收者
                    PeashooterCommand command = new PeashooterCommand(peashooter);
                    //创建请求者,设置命令对象
                    Invokers invokers = new Invokers();
                    invokers.SetCommand(command);
                    //执行方法
                    invokers.ExecuteCommand();

                }
                else if (type == 2)
                {
                    SnowPeashooter peashooter = new SnowPeashooter();
                    SnowPeashooterCommand command = new SnowPeashooterCommand(peashooter);
                    Invokers invokers = new Invokers();
                    invokers.SetCommand(command);
                    invokers.ExecuteCommand();

                }
                else if (type == 3)
                {
                    DoublePeashooter peashooter = new DoublePeashooter();
                    DoublePeashooterCommand command = new DoublePeashooterCommand(peashooter);
                    Invokers invokers = new Invokers();
                    invokers.SetCommand(command);
                    invokers.ExecuteCommand();
                }
            }



            /********** End *********/         
        }
    }
    public interface IBotany
    {
        
    }
    public class Peashooter: IBotany
    {
        public Peashooter()
        {
            Console.WriteLine("豌豆射手生产出来了");
        }
    }
    public class SnowPeashooter : IBotany
    {
        public SnowPeashooter()
        {
            Console.WriteLine("雪花豌豆射手生产出来了");
        }
    }
    public class DoublePeashooter : IBotany
    {
        public DoublePeashooter()
        {
            Console.WriteLine("双管豌豆射手生产出来了");
        }
    }

    public class BotanyFactory  ///植物工厂
    {
        泛型方法(创建任意类型的植物)
        public T CreatBotany<T>() where T : IBotany, new()
        {
            return new T();
        }
        public void CreatePeashooter()
        {
            CreatBotany<Peashooter>();
        }
        public void CreateSnowPeashooter()
        {
            CreatBotany<SnowPeashooter>();
        }
        public void CreateDoublePeashooter()
        {
            CreatBotany<DoublePeashooter>();
        }
    }
    class Invokers
    {
        private Commands command;

        public void SetCommand(Commands command)
        {
            this.command = command;
        }
        public void ExecuteCommand()
        {
            command.Execute();
        }
    }
    abstract class Commands
    {
        /********** Begin *********/

         public abstract void Execute();   

        /********** End *********/ 
    }
    class PeashooterCommand : Commands
    {
        /********** Begin *********/
        public Peashooter peashooter;
        public PeashooterCommand(Peashooter peashooter)
        {
            this.peashooter = peashooter;
        }
        public override void Execute() { }
        
            

        /********** End *********/ 
    }
    class SnowPeashooterCommand : Commands
    {
        /********** Begin *********/
        public SnowPeashooter snowPeashooter;
        public SnowPeashooterCommand(SnowPeashooter snowPeashooter)
        {
            this.snowPeashooter = snowPeashooter;
        }
        public override void Execute() { }
            

        /********** End *********/ 
    }
    class DoublePeashooterCommand : Commands
    {
        /********** Begin *********/
        public DoublePeashooter doublePeashooter;
        public DoublePeashooterCommand(DoublePeashooter doublePeashooter)
        {
            this.doublePeashooter = doublePeashooter;
        }
        public override void Execute() { }
            

        /********** End *********/ 
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值