zoukankan      html  css  js  c++  java
  • C# 设计模式·行为型模式


    这里列举行为型模式·到此23种就列完了···这里是看着菜鸟教程来实现··,他里边列了25种,其中过滤器模式和空对象模式应该不属于所谓的23种模式
    责任链模式:为请求创建一个接收者对象的链,对请求的发送者和接收者进行解耦,大部分用于web中吧。。
    Task中的continuewith和微软的tpl数据流应该是类似这种模式的实现吧

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    //责任链模式
    namespace ExercisePrj.Dsignmode
    {
        public abstract class AbstractLogger
        {
            public static int INFO = 1;
            public static int DEBUG = 2;
            public static int ERROR = 3;
            protected int level;
            //责任链中的下一个对象
            protected AbstractLogger nextLogger;
            public void SetNextLogger(AbstractLogger next)
            {
                nextLogger = next;
            }
            public void LogMessage(int level,string message)
            {
                if(this.level<=level)
                {
                    Write(message);
                }
                if(nextLogger!=null)
                {
                    nextLogger.LogMessage(level, message);
                }
            }
            protected abstract void Write(string message);
        }
        public class ConsoleLogger : AbstractLogger
        {
    
           public ConsoleLogger(int level)
            {
                this.level = level;
            }
    
           protected  override void Write(string message)
            {
                Console.WriteLine("Standard Console::Logger: " + message);
            }
        }
        public class ErrorLogger : AbstractLogger
        {
    
           public ErrorLogger(int level)
            {
                this.level = level;
            }
    
           protected override void Write(String message)
            {
                Console.WriteLine("Error Console::Logger: " + message);
            }
        }
        public class FileLogger : AbstractLogger
        {
           public FileLogger(int level)
            {
                this.level = level;
            }
    
           protected override void Write(String message)
            {
                Console.WriteLine("File::Logger: " + message);
            }
        }
    }

    命令模式(Command Pattern):请求以命令的形式执行,CAD的的命令应该就是以这种方式执行的·二次开发的时候通过特性标识和继承他的接口来添加命令,非常方便

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    //命令模式
    namespace ExercisePrj.Dsignmode
    {
        public interface IOrder
        {
            void Execute();
        }
        public class Stock
        {
            private string name = "ABC";
            private int quantity = 10;
    
            public void Buy()
            {
                Console.WriteLine("Stock name:{0},quantity:{1},bought",name,quantity);
            }
            public void Sell()
            {
                Console.WriteLine("Stock name:{0},quantity:{1}sold", name, quantity);
            }
        }
        //请求类
        public class BuyStock : IOrder
        {
           private Stock abcStock;
    
            public BuyStock(Stock abcStock)
            {
                this.abcStock = abcStock;
            }
    
            public void Execute()
            {
                abcStock.Buy();
            }
        }
        //继承接口的实体
        public class SellStock : IOrder
        {
           private Stock abcStock;
    
            public SellStock(Stock abcStock)
            {
                this.abcStock = abcStock;
            }
    
            public void Execute()
            {
                abcStock.Sell();
            }
        }
    
        //命令调用类
        public class Broker
        {
            private List<IOrder> orderList = new List<IOrder>();
    
            public void takeOrder(IOrder order)
            {
                orderList.Add(order);
            }
    
            public void placeOrders()
            {
                foreach (IOrder order in orderList)
                {
                    order.Execute();
                }
                orderList.Clear();
            }
        }
    
    }

    解释器模式:就是实现一种表达式接口,C#的各种表达式就是这种实现吧··这玩意跟富文本编辑器一样是个大坑吧··,做好了确实很好使,一不小心就得跪

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    //解释器模式
    namespace ExercisePrj.Dsignmode
    {
        public interface Expression
        {
             bool Interpret(string context);
        }
        public class TerminalExpression : Expression
        {
           private string data;
    
            public TerminalExpression(string data)
            {
                this.data = data;
            }
    
           public  bool Interpret(string context)
            {
                if (context.Contains(data))
                {
                    return true;
                }
                return false;
            }
        }
        public class OrExpression : Expression
        {
            private Expression expr1 = null;
            private Expression expr2 = null;
            public OrExpression(Expression expr1, Expression expr2)
            {
                this.expr1 = expr1;
                this.expr2 = expr2;
            }
            public bool Interpret(String context)
            {
                return expr1.Interpret(context) || expr2.Interpret(context);
            }
        }
        public class AndExpression : Expression
        {
            private Expression expr1 = null;
            private Expression expr2 = null;
    
            public AndExpression(Expression expr1, Expression expr2)
            {
                this.expr1 = expr1;
                this.expr2 = expr2;
            }
            public bool Interpret(String context)
            {
                return expr1.Interpret(context) && expr2.Interpret(context);
            }
            }
    }


    迭代器模式(Iterator Pattern):.NET自带接口···,直接实现就行了··注意又泛型接口和非泛型接口··非泛型接口迭代对象返回的是object,泛型接口返回的直接就是对象了,还有通过yield的简化写法不用额外去实现IEnumerator接口

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        public class IteratorEx : IEnumerable //<IteratorEx>
        {
            public string Name;
            private List<IteratorEx> list = new List<IteratorEx>();
    
            //public IEnumerator<IteratorEx> GetEnumerator()
            //{
            //    foreach (var l in list)
            //    {
            //        yield return l;
            //    }
            //}
    
            public void SetList(List<IteratorEx> data)
            {
                list = data;
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                foreach (var l in list)
                {
                    yield return l;
                }
                //return new IteratorExEnum(list.ToArray());
            }
        }
        public class IteratorExEnum : IEnumerator
        {
            private IteratorEx[] list;
            private int position = -1;
            public IteratorExEnum(IteratorEx[] data)
            {
                list = data;
            }
            public object Current
            {
                get
                {
                    try
                    {
                        return list[position];
                    }
                    catch (IndexOutOfRangeException)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }
    
            public bool MoveNext()
            {
                position++;
                return position < list.Length;
            }
    
            public void Reset()
            {
                position = -1;
            }
        }
    
    }

     
    中介者模式(Mediator Pattern):用一个中介对象封装一些对象的交互,中介者使对象不用显式的互相引用,MVC和mvp 的c和p都是类似这玩意的实现吧

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        //中介类
        public class ChatRoom
        {
            public static void ShowMessage(User user, string msg)
            {
                Console.WriteLine(new DateTime().ToString()+"["+ user.Name + "] : " + msg);
            }
        }
        public class User
        {
            public string Name { get; set; }
    
            public User(string name)
            {
                Name = name;
            }
    
            public void SendMessage(String message)
            {
                ChatRoom.ShowMessage(this, message);
            }
        }
    
    
    }

    备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存,

    大部分支持回退的操作场景下应该都是这种模式··之前做的软件中有画图的操作···支持后退,实现方式非常简单粗暴··,直接吧图层的画图对象克隆一份保存··只支持5还是10步,讲道理这么实现确实有点那啥了···

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        public class Memento
        {
            public string State { get; }
            public Memento(string state)
            {
                State = state;
            }
        }
        public class Originator
        {
            public string State { get; set; }
    
            public Memento SaveStateToMemento()
            {
                return new Memento(State);
            }
    
            public void GetStateFromMemento(Memento Memento)
            {
                State = Memento.State;
            }
        }
        public class CareTaker
        {
            private List<Memento> mementoList = new List<Memento>();
    
            public void Add(Memento state)
            {
                mementoList.Add(state);
            }
    
            public Memento Get(int index)
            {
                return mementoList[index];
            }
        }
    
    }

    观察者模式(Observer Pattern):.net自带的有接口提供来实现观察者模式···这里照着msdn来实现一遍,自带的接口里边还实现了资源的释放··,之前并发编程里边的rx也是这个模式的具体实现·

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    //观察者模式
    namespace ExercisePrj.Dsignmode
    {
    
        public class Subject: IObservable<Subject>
        {
            public int State {get; set;}
            public Subject(int state)
            {
                State = state;
            }
            private List<IObserver<Subject>> observers = new List<IObserver<Subject>>();
    
            public IDisposable Subscribe(IObserver<Subject> observer)
            {
                if (!observers.Contains(observer))
                    observers.Add(observer);
                return new Unsubscriber(observers, observer);
            }
            private class Unsubscriber : IDisposable
            {
                private List<IObserver<Subject>> _observers;
                private IObserver<Subject> _observer;
    
                public Unsubscriber(List<IObserver<Subject>> observers, IObserver<Subject> observer)
                {
                    this._observers = observers;
                    this._observer = observer;
                }
    
                public void Dispose()
                {
                    if (_observer != null && _observers.Contains(_observer))
                        _observers.Remove(_observer);
                }
            }
    
            public void TrackLocation(Subject ob)
            {
                Console.WriteLine("start");
                foreach (var observer in observers)
                {
                    if (ob==null)
                        observer.OnError(new Exception("unknowExeption"));
                    else
                        observer.OnNext(ob);
                }
            }
    
            public void EndTransmission()
            {
                foreach (var observer in observers.ToArray())
                    if (observers.Contains(observer))
                        observer.OnCompleted();
    
                observers.Clear();
            }
    
        }
    
    
        public class BinaryObserver : IObserver<Subject>
        {
            public void OnCompleted()
            {
                Console.WriteLine("complete");
            }
    
            public void OnError(Exception error)
            {
                Console.WriteLine(error.Message);
            }
    
            public void OnNext(Subject value)
            {
                Console.WriteLine("Binary String: " + Convert.ToString(value.State, 2));
            }
        }
        public class OctalObserver : IObserver<Subject>
        {
            public void OnCompleted()
            {
                Console.WriteLine("complete");
            }
    
            public void OnError(Exception error)
            {
                Console.WriteLine(error.Message);
            }
    
            public void OnNext(Subject value)
            {
                Console.WriteLine("Octal String: " + Convert.ToString(value.State, 8));
            }
    
        }
        public class HexaObserver : IObserver<Subject>
        {
            public void OnCompleted()
            {
                Console.WriteLine("complete");
            }
    
            public void OnError(Exception error)
            {
                Console.WriteLine(error.Message);
            }
    
            public void OnNext(Subject value)
            {
                Console.WriteLine("Hex String: " + Convert.ToString(value.State,16));
            }
        }
    }


    状态模式(State Pattern):当对象内部状态发生改变时,行为也跟着改变

    这个模式是为了解决类里边的大量if和swicth语句,讲道理例子写的有点怪···主体是context

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        public class Context
        {
            public State State { get; set; }
    
            public Context()
            {
                State = null;
            }
        }
        public interface State
        {
             void DoAction(Context context);
        }
    
        public class StartState : State
        {
           public void DoAction(Context context)
            {
                Console.WriteLine("Player is in start state");
                context.State = this;
            }
    
            public override string ToString()
            {
                return "Start State";
            }
        }
        public class StopState : State
        {
    
           public void DoAction(Context context)
            {
                Console.WriteLine("Player is in stop state");
                context.State = this;
            }
    
            public override string  ToString()
            {
                return "Stop State";
            }
        }
    }

    空对象模式(Null Object Pattern):就是吧对空值的判断定义一个啥也不做的实体对象出来··C#的Nullable就是这个的实现···这玩意不在23种设计模式里边···

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        public abstract class AbstractCustomer
        {
            public abstract bool IsNull();
            public abstract string Name { get; }
        }
        public class RealCustomer : AbstractCustomer
        {
            public override string Name { get; }
    
            public RealCustomer(string name)
            {
                Name = name;
            }
            public override bool IsNull()
            {
                return false;
            }
        }
        public class NullCustomer : AbstractCustomer
        {
                public override string Name { get { return "Not Available in Customer Database"; } }
                public override bool IsNull()
                {
                    return true;
                }
        }
        public class CustomerFactory
        {
            public static  string[] names = {"Rob", "Joe", "Julie"};
             public static AbstractCustomer getCustomer(string name)
            {
                if(names.Contains(name))
                {
                    return new RealCustomer(name);
                }
                return new NullCustomer();
            }
        }
    }

    策略模式(Strategy Pattern):定义一系列算法,封装成类,可以相互替换,通过构造不同的类,执行不同的操作。这样做方便调用,添加新的算法也方便,

    最后加了自己之前对这个模式的奇葩写法

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        public interface IStrategy
        {
             int DoOperation(int num1, int num2);
        }
        public class OperationAdd : IStrategy
        {
            
           public int DoOperation(int num1, int num2)
            {
                return num1 + num2;
            }
        }
    
        public class OperationSubstract : IStrategy
        {
    
            public int DoOperation(int num1, int num2)
            {
                return num1 - num2;
            }
        }
        public class OperationMultiply : IStrategy
        {
    
            public int DoOperation(int num1, int num2)
            {
                 return num1 * num2;
            }
        }
    
        public class ContextEx
        {
            private IStrategy strategy;
    
            public ContextEx(IStrategy strategy)
            {
                this.strategy = strategy;
            }
    
            public int ExecuteStrategy(int num1, int num2)
            {
                return strategy.DoOperation(num1, num2);
            }
    
            //奇葩的写法简单粗暴
            private Dictionary<string, Func<int, int, int>> funcs = new Dictionary<string, Func<int, int, int>>();
            public int ExecuteStrategy(string name, int num1, int num2)
            {
                if(funcs.Count==0)
                {
                    //反射写法
                    var assembly = Assembly.GetExecutingAssembly();
                    var types = assembly.GetTypes();
                    foreach (var t in types)
                    {
                        if (t.GetInterface("IStrategy") != null)
                        {
                            var instance = assembly.CreateInstance(t.FullName) as IStrategy;
                            funcs.Add(t.Name, instance.DoOperation);
                        }
                    }
                    //直接添加
                    //funcs.Add("OperationAdd", new Func<int, int, int>((n1, n2) => { return n1 + n2; }));
                    //funcs.Add("OperationSubstract", new Func<int, int, int>((n1, n2) => { return n1 - n2; }));
                    //funcs.Add("OperationMultiply", new Func<int, int, int>((n1, n2) => { return n1 * n2; }));
                }
                return funcs[name](num1, num2);
            }
    
    
        }
    }

    模板模式(Template Pattern):.net的泛型就是这个模式的实现吧··照着模子写就行了

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        public abstract class Game
        {
           public  abstract void Initialize();
            public  abstract void StartPlay();
            public abstract void EndPlay();
    
            //模板
            public void play()
            {
    
                //初始化游戏
                Initialize();
                //开始游戏
                StartPlay();
                //结束游戏
                EndPlay();
            }
        }
        public class Cricket : Game
        {
            public override void EndPlay()
            {
                Console.WriteLine("Cricket Game Finished!");
            }
    
            public override void Initialize()
            {
                Console.WriteLine("Cricket Game Initialized! Start playing.");
            }
    
    
            public override void StartPlay()
            {
                Console.WriteLine("Cricket Game Started. Enjoy the game!");
            }
        }
    }

    访问者模式(Visitor Pattern):在被访问的类里边加一个对外提供接待访问的接口
     吧数据结构和对应的操作分开·添加操作很容易,但是如果结构变化多的化,改起来就麻烦了··
     没研究没用过····

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
    
        public interface IComputerPartVisitor
        {
            void Visit(Computer computer);
            void Visit(Mouse mouse);
            void Visit(Keyboard keyboard);
            void Visit(Monitor monitor);
        }
    
        public interface IComputerPart
        {
            void Accept(IComputerPartVisitor computerPartVisitor);
        }
    
        public class Keyboard  : IComputerPart
        {
    
           public void Accept(IComputerPartVisitor computerPartVisitor)
            {
                computerPartVisitor.Visit(this);
            }
        }
        public class Monitor  : IComputerPart
        {
    
           public void Accept(IComputerPartVisitor computerPartVisitor)
            {
                computerPartVisitor.Visit(this);
            }
    }
        public class Mouse  : IComputerPart
        {
           public void Accept(IComputerPartVisitor computerPartVisitor)
            {
                computerPartVisitor.Visit(this);
            }
        }
        public class Computer : IComputerPart
        {
            IComputerPart [] parts;
            public Computer()
            {
                parts = new IComputerPart[] { new Mouse(), new Keyboard(), new Monitor() };
            }
            public void Accept(IComputerPartVisitor computerPartVisitor)
            {
                for (int i = 0; i < parts.Length; i++)
                {
                    parts[i].Accept(computerPartVisitor);
                }
                computerPartVisitor.Visit(this);
            }
        }
    
        public class ComputerPartDisplayVisitor : IComputerPartVisitor
        {
            public void Visit(Computer computer)
            {
                Console.WriteLine("Displaying Computer.");
            }
            public void Visit(Mouse mouse)
            {
                Console.WriteLine("Displaying Mouse.");
            }
            public void Visit(Keyboard keyboard)
            {
                Console.WriteLine("Displaying Keyboard.");
            }
            public void Visit(Monitor monitor)
            {
                Console.WriteLine("Displaying Monitor.");
            }
        }
    }
  • 相关阅读:
    boxcox1p归一化+pipeline+StackingCVRegressor
    rt-thread调度锁与关闭中断深度探究
    树莓派4最小化安装Linux
    树莓派4可以不用SD卡启动
    树莓派JTAG详细使用笔记
    树莓派上玩街机游戏
    用树莓派制作红白游戏机
    树莓派4上使用uboot+tftp调试rt-thread程序
    在window上搭建树莓派4b的RT-Thread开发环境2
    树莓派上运行RT-Thread并通过esp8266连接网络
  • 原文地址:https://www.cnblogs.com/onegarden/p/7201907.html
Copyright © 2011-2022 走看看