• C#项目中常用到的设计模式


    1. 引言

    一个项目的通常都是从Demo开始,不断为项目添加新的功能以及重构,也许刚开始的时候代码显得非常凌乱,毫无设计可言。但是随着项目的迭代,往往需要将很多相同功能的代码抽取出来,这也是设计模式的开始。熟练运用设计模式应该是每一个软件开发人员的必备技能。今天给大家介绍几个常用的设计模式。

    2. 单例模式

    单例模式恐怕是很多开发人员最先接触到的模式之一,可以认为就是一个全局变量。它的初始化过程无非就是一开始就new 一个instance,或者惰性初始化等需要用到的时候new 一个instance。这里需要注意的是在多线程情况下new一个instance。通常加上lock 可以解决问题。这里我们利用C# 的系统函数 Interlocked.CompareExchange

        internal class SingletonOne
        {
            private static SingletonOne _singleton;
            private SingletonOne()
            {
            }
    
            public static SingletonOne Instance
            {
                get
                {
                    if (_singleton == null)
                    {
                        Interlocked.CompareExchange(ref _singleton, new SingletonOne(), null);
                    }
    
                    return _singleton;
                }
            }
        }

    3. 迭代器模式

    迭代器模式也是用的比较多的一种,通常见于C#的内置容器数据结构 List,Stack等等,为了便于遍历容器内元素。这里给出一个简单版的Stack实现

        internal class Stack<T> : IEnumerable<T>, IEnumerable
        {
            private T[] _array;
            private int _index;
            private const int DefaultSize = 4;
    
            public Stack(int size)
            {
                var sized = size > 0 ? size : DefaultSize;
                this._array = new T[sized];
                this._index = 0;
            }
    
            public int Count
            {
                get { return this._index; }
            }
    
            public Stack(IEnumerable<T> data) : this(0)
            {
                var enumrator = data.GetEnumerator();
                while (enumrator.MoveNext())
                {
                    var item = enumrator.Current;
                    this.Push(item);
                }
            }
    
            public void Push(T item)
            {
                if (this._index < this._array.Length)
                {
                    this._array[this._index++] = item;
                }
                else
                {
                    var newLength = this._array.Length << 1;
                    T[] newArray = new T[newLength];
                    Array.Copy(this._array, newArray, this.Count);
    
                    this._array = newArray;
                    this.Push(item);
                }
            }
    
            public T Pop()
            {
                if (this.Count <= 0)
                {
                    throw new ArgumentOutOfRangeException("pop");
                }
                else
                {
                    this._array[this._index] = default(T);
                    return this._array[--this._index];
                }
            }
    
            public T Get(int index)
            {
                if (this.Count <= index)
                {
                    throw new ArgumentOutOfRangeException("Get");
                }
                else
                {
                    return this._array[index];
                }
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return this.GetEnumerator();
            }
    
            public IEnumerator<T> GetEnumerator()
            {
                return new StackEnumerator<T>(this);
            }
        }

    Stack 的 迭代器内部实现:

        internal class StackEnumerator<T> : IEnumerator<T> , IEnumerator
        {
            private Stack<T> _stack;
            private int _index;
    
            public StackEnumerator(Stack<T> stack)
            {
                this._stack = stack;
                this._index = -1;
            }
    
            public bool MoveNext()
            {
                this._index++;
                return this._index < this._stack.Count;
            }
    
            public void Reset()
            {
                this._index = -1;
            }
    
            object  IEnumerator.Current 
            {
                get { return this.Current; } 
            }
    
            public T Current
            {
                get { return this._stack.Get(this._index); }
            }
    
            public void Dispose()
            {
                this._stack = null;
            }
        }

    4 工厂模式

    工厂模式细分的话有简单工厂模式、抽象工厂模式等。它最核心的就是如何通过 Factory new 一个 对象出来。在ASP.NET MVC 消息处理实现过程中工厂模式运用的非常多。比如

    在MVC中处理一个Request,其实就是调用Controller下的一个Action,这就需要从Url 和Route 中反射出Controller对象,内部由ControllerFactory创建。

    image

    它的默认实现是:DefaultControllerFactory

    image

    另一个例子是ValueProviderFactory,它使得Controller 下的Action 能够接收到前端传回来的数据并实现模型绑定,是典型的抽象工厂实现。

    image

    5. 订阅模式

    订阅模式在某些项目运用比较多,比如 Knockout 整个项目就是一个大的订阅模式的实现,但是它是用javascript编写的。还有像微博、微信公众号等等订阅模式通常少不了。

    通常可以定义接口:

        internal interface ISubject
        {
            IEnumerable<IObserver> Observers { get; } 
            void Notify();
            void AddObserver(IObserver observer);
            void RemoveObserver(IObserver observer);
        }
    
        internal interface IObserver
        {
            void ReceiveSubject(ISubject subject);
        }

    实现:

        internal class AritcleObserver : IObserver
        {
            public void ReceiveSubject(ISubject subject)
            {
                // receive the subject
            }
        }
    
        class WeChatArticle : ISubject
        {
            private ICollection<IObserver> _observers;
            private string _name;
    
            public WeChatArticle(string name)
            {
                this._name = name;
                this._observers = new List<IObserver>();
            }
    
            public IEnumerable<IObserver> Observers
            {
                get { return this._observers; }
            }
    
            public void Notify()
            {
                foreach (IObserver observer in this._observers)
                {
                    observer.ReceiveSubject(this);
                }
            }
    
            public void AddObserver(IObserver observer)
            {
                this._observers.Add(observer);
            }
    
            public void RemoveObserver(IObserver observer)
            {
                this._observers.Remove(observer);
            }
        }

    6.  责任链模式

    责任链模式没有像工厂模式那样被人熟悉,在ASP.NET WebApi 中有一个非常典型的实现 就是WebApi的消息处理管道HttpMessageHandler

    image

    这里给一个简单的模拟

        class DataRequest
        {
            public string FileName { get; set; }
        }
    
        class DataResponse
        {
            public string Error { get; set; }
            public string Data { get; set; }
        }
    
        internal abstract class RequestHandler
        {
            public RequestHandler NextHandler { get; set; }
            public abstract DataResponse Process(DataRequest request);
        }
    
        class ReadRequestHandler : RequestHandler
        {
            public override DataResponse Process(DataRequest request)
            {
                return new DataResponse()
                {
                    Data = File.ReadAllText(request.FileName)
                };
            }
        }
    
        class ExistsRequestHandler : RequestHandler
        {
            public override DataResponse Process(DataRequest request)
            {
                if (File.Exists(request.FileName))
                {
                    return this.NextHandler.Process(request);
                }
                else
                {
                    return new DataResponse()
                    {
                        Error = "no exists"
                    };
                }
            }
        }

    7. 组合模式

    组合模式是使得单个对象和组合对象有一致的行为,一致的行为可以理解为拥有同一个接口,比如图形显示

        class ControlContext
        {
        }
    
        internal interface IControl
        {
            void Draw(ControlContext context);
        }
    
        class Line : IControl
        {
            public void Draw(ControlContext context)
            {
            }
        }
    
        class Circle : IControl
        {
            public void Draw(ControlContext context)
            {}
        }
    
        class CompositeControl : IControl
        {
            private List<IControl> controls;
    
            public CompositeControl(IList<IControl> cons)
            {
                this.controls = new List<IControl>(cons);
            }
    
            public void Draw(ControlContext context)
            {
                this.controls.ForEach(c => c.Draw(context));
            }
    
            public void Add(IControl control)
            {
                this.controls.Add(control);
            }
        }

    8. 总结

    市场上有很多关于设计模式的书,但是基本的设计模式大概有20多种,本文给大家介绍了几种项目中常见的设计模式,其实有些设计模式在实际项目已经不知不觉用起来了。

    以后再给大家介绍其他的几种设计模式。

    欢迎访问我的个人主页 51zhang.net  网站还在不断开发中…..

  • 相关阅读:
    项目经理-要材料
    java stream 处理
    listGiftBagShowInfo 这个方法 我搞了一晚上
    BigDecimal.ROUND_UP 如果 从 double 到 Decimal 有异常, 必须从double到String然后 Decimal 就可以了
    json串 转 list<class> 方法 List转JSONArray和JSONArray转List
    昨晚加班到3点多-身体都虚脱了
    MVN 点击compile总是失败
    IDEA使用笔记(八)——自动生成 serialVersionUID 的设置
    Maven 版本号规范
    java多线程学习
  • 原文地址:https://www.cnblogs.com/VectorZhang/p/5554388.html
Copyright © 2020-2023  润新知