设计模式一日一练:命令模式(Command)

    Command模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化(可以被传递、存储、重复利用);对请求排队或记录请求日志,以及支持可撤消的操作。

    public class Unit : MonoBehaviour
    {
        public void Move(Vector3 translation)
        {
            transform.Translate(translation);
        }
    }

    public abstract class Command
    {
        protected float time;
        public float Time { get { return time; } }

        public virtual void execute(Unit unit) { }
        public virtual void undo(Unit unit) { }
    }


    public class MoveCommand : Command
    {
        private Vector3 translation;
        public MoveCommand(Vector3 trans, float t)
        {
            translation = trans;
            time = t;
        }

        public override void execute(Unit unit)
        {
            unit.Move(translation);
        }

        public override void undo(Unit unit)
        {
            unit.Move(-translation);
        }
    }


    public class CommandPattern : MonoBehaviour
    {
        public Unit unit;
        public bool isRun = true;

        private Stack<Command> commands;
        private float passTime;

        // Start is called before the first frame update
        void Start()
        {
            commands = new Stack<Command>();
            passTime = 0f;
        }

        // Update is called once per frame
        void Update()
        {
            if (isRun)
            {
                HandleCommands();
            }
            else
            {
                RollbackCommands();
            }
        }

        void HandleCommands()
        {
            passTime += Time.deltaTime;
            Command command = HandleInput();
            if (command != null) {
                commands.Push(command);
                command.execute(unit);
            }
        }

        void RollbackCommands()
        {
            passTime -= Time.deltaTime;
            if (commands.Count > 0 && passTime < commands.Peek().Time)
            {
                commands.Pop().undo(unit);
            }
        }

        Command HandleInput()
        {
            if (Input.GetKey(KeyCode.W))
                return new MoveCommand(new Vector3(0, Time.deltaTime, 0), passTime);
            if (Input.GetKey(KeyCode.S))
                return new MoveCommand(new Vector3(0, -Time.deltaTime, 0), passTime);
            if (Input.GetKey(KeyCode.A))
                return new MoveCommand(new Vector3(-Time.deltaTime, 0, 0), passTime);
            if (Input.GetKey(KeyCode.D))
                return new MoveCommand(new Vector3(Time.deltaTime, 0, 0), passTime);
            return null;
        }
    }

PS. 腾讯引擎技术中心的一位技术牛人写过一篇用命令模式封装多线程调用的blog,命令模式的典型应用场景。

PS. 我的设计模式系列blog,《设计模式》专栏,通过简单的示例演示设计模式,对于初学者很容易理解入门。深入学习请看GoF的《设计模式》。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值