命令模式

延迟任务的例子:

  public class WakeUpCommand : ICommand
    {
        public bool executed = false; //这里开关可以控制自己的逻辑块,但是这里暂时是个摆设
        public void Execute()
        {
            Trace.WriteLine("working...");
            executed = true;
        }
    }
    public class SleepCommand : ICommand
    {
        private ICommand wakeUpCommand = null; //唤醒命令
        private ActiveObjectEngine engine = null; //命令集
        private DateTime startTime; //开始执行时间标记
        private long sleepTime = 0;    //休眠时间戳
        private bool started = false;
        public SleepCommand(ICommand wakeUpCommand, ActiveObjectEngine engine, long sleepTime)
        {
            this.wakeUpCommand = wakeUpCommand;
            this.engine = engine;
            this.sleepTime = sleepTime;
        }

        public void Execute()
        {
            DateTime currentTime = DateTime.Now;
            if (!started)
            {
                started = true;
                startTime = currentTime;
                engine.Add(this);
            }
            else
            {
                if (currentTime.Subtract(startTime).TotalMilliseconds < sleepTime)
                {
                    engine.Add(this);
                }
                else
                {
                    engine.Add(wakeUpCommand);
                }
            }
        }
    }
    public class ActiveObjectEngine
    {
        private List<ICommand> commands = new List<ICommand>();
        public void Run()
        {
            while (commands.Count > 0)
            {
                var command = commands[0];
                commands.RemoveAt(0);
                command.Execute();
            }
        }
        public void Add(ICommand command) { commands.Add(command); }
    }
    public interface ICommand
    {
        void Execute();
    }
    public class DelayTyper : ICommand
    {
        private long itsDelay;
        private char itsChar;
        private static bool stop = false;
        private static ActiveObjectEngine engine = new ActiveObjectEngine();
        private class StopCommand : ICommand
        {
            public void Execute()
            {
                DelayTyper.stop = true;
            }
        }
        public static void FakeMain(params string[] args)
        {
            engine.Add(new DelayTyper(100, '1'));
            engine.Add(new DelayTyper(300, '3'));
            engine.Add(new DelayTyper(500, '5'));
            engine.Add(new DelayTyper(700, '7'));
            ICommand stopCommand = new StopCommand();
            engine.Add(new SleepCommand(stopCommand, engine, 20000));
            engine.Run();
        }

        public void Execute()
        {
            Trace.Write(itsChar);
            if (!stop)
                DelayAndRepeat();
        }
        private void DelayAndRepeat()
        {
            engine.Add(new SleepCommand(this, engine, itsDelay));
        }

        public DelayTyper(long itsDelay, char itsChar)
        {
            this.itsDelay = itsDelay;
            this.itsChar = itsChar;
        }
    }

实现:

   [Test]
        public void TestSleepC()
        {
            #region test001
            
                WakeUpCommand wakeUpCommand = new WakeUpCommand();
                ActiveObjectEngine activeObjectEngine = new ActiveObjectEngine();

                SleepCommand sleepCommand = new SleepCommand(wakeUpCommand, activeObjectEngine, 10000);//10秒
                activeObjectEngine.Add(sleepCommand);
                DateTime start = DateTime.Now;
                activeObjectEngine.Run();
                DateTime end = DateTime.Now;
                Trace.WriteLine($"第一次休眠:{start.Subtract(end)}");

                sleepCommand = new SleepCommand(wakeUpCommand, activeObjectEngine, 100);
                activeObjectEngine.Add(sleepCommand);
                start = DateTime.Now;
                activeObjectEngine.Run();
                end = DateTime.Now;
                Trace.WriteLine($"第二次休眠:{start.Subtract(end)}");

                activeObjectEngine.Add(sleepCommand);
                start = DateTime.Now;
                activeObjectEngine.Run(); //执行sleep else分支
                end = DateTime.Now;
                Trace.WriteLine($"第三次休眠:{start.Subtract(end)}");
            
            #endregion

        }
        [Test]
        public void TestDelayTyper()
        {
            DelayTyper.FakeMain();
        }

 

计算器例子:

  public class Command : ICommand
    {
        private Queue<decimal> queue = new Queue<decimal>();
        public decimal[] GetResults=>queue.ToArray();
        private Receiver _receiver;
        public Receiver Receiver { get => _receiver; set => _receiver=value; }

        public decimal Execute(params decimal[] items)
        {
            var result = _receiver.Cal(items);
            queue.Enqueue(result);
            return result;
        }

        public decimal Reset()
        {
            return queue.Dequeue();
        }
    }

    public class Add : Receiver { public decimal Cal(params decimal[] items) { return items.Aggregate((x, y) => x + y); } }
    public class Sub : Receiver { public decimal Cal(params decimal[] items) { return items.Aggregate((x, y) => x - y); } }
    public class Mul : Receiver { public decimal Cal(params decimal[] items) { return items.Aggregate((x, y) => x * y); } }
    public class Div : Receiver { public decimal Cal(params decimal[] items) { return items.Aggregate((x, y) => x/ y); } }
    public interface Receiver
    {
        decimal Cal(params decimal[] items);
    }
    
    public interface ICommand
    {
        decimal Execute(params decimal[] items); 
     decimal Reset();
     Receiver Receiver { get; set; } }

 

 

客户端实现:

ICommand addCommand = new Command();
addCommand.Receiver = new Add();

ICommand subCommand = new Command();
subCommand.Receiver = new Sub();

 

下面是另外示例:

  public  class Store
    {
        private readonly Dictionary<string, Func<decimal[], decimal>> _dic = new Dictionary<string, Func<decimal[], decimal>>()
        {
            {"add",items=>items.Aggregate((x,y)=>x+y) },
            {"sub",items=>items.Aggregate((x,y)=>x-y) },
            {"mul",items=>items.Aggregate((x,y)=>x*y) },
            {"div",items=>items.Aggregate((x,y)=>x/y) }
        };
        private readonly Dictionary<string, decimal[]> _parameters = new Dictionary<string, decimal[]>();

        public decimal GetAddResult()
        {
            return GetResult("add");
        }
        public decimal GetSubResult()
        {
            return GetResult("sub");
        }
        public decimal GetMulResult()
        {
            return GetResult("mul");
        }

        public decimal GetDivResult()
        {
            return GetResult("div");
        }
        public void Add(params decimal[] items)
        {
            var key = $"add_{Guid.NewGuid().ToString()}";
            _parameters.Add(key, items.ToArray());
        }
      
        public void RestAdd()
        {
            Remove("add");
        }

        public void Sub(params decimal[] items)
        {
            var key = $"sub{Guid.NewGuid().ToString()}";
            _parameters.Add(key, items.ToArray());
        }
        public void RestSub()
        {
            Remove("sub");
        }

        public void Mul(params decimal[] items)
        {
            var key = $"mul_{Guid.NewGuid().ToString()}";
            _parameters.Add(key, items.ToArray());
        }
        public void RestMul()
        {
            Remove("mul");
        }

        public void Div(params decimal[] items)
        {
            var key = $"div{Guid.NewGuid().ToString()}";
            _parameters.Add(key, items.ToArray());
        }
        public void RestDiv()
        {
            Remove("div");
        }


        #region private 
      
        private void Remove(string charater)
        {
            var key = _parameters.Where(x => x.Key.Contains($"{charater}_")).Select(x => x.Key).OrderByDescending(x=>x).FirstOrDefault();
            _parameters.Remove(key);
        }
        private decimal GetResult(string charater)
        {
            decimal result = 0;
            var parameters = _parameters.Where(x => x.Key.Contains($"{charater}_")).ToDictionary(x=>x.Key,y=>y.Value);
            var keys = parameters.Keys;
            //计算
            foreach (var item in parameters)
            {
                result += _dic[charater].Invoke(item.Value);
            }
            foreach (var item in keys)
            {
                _parameters.Remove(item);
            }
            return result;
        } 
        #endregion
    }
        Store store = new Store();
            store.Add(1, 2, 3, 4, 5);
            var result = store.GetAddResult();

            store.Mul(8, 8);
            store.Mul(9, 9);
            store.RestMul();
            result = store.GetMulResult();

 

posted @ 2022-11-21 11:26  星仔007  阅读(21)  评论(0编辑  收藏  举报