C#项目中常用到的设计模式
1. 引言
一個項目的通常都是從Demo開始,不斷為項目添加新的功能以及重構(gòu),也許剛開始的時候代碼顯得非常凌亂,毫無設(shè)計可言。但是隨著項目的迭代,往往需要將很多相同功能的代碼抽取出來,這也是設(shè)計模式的開始。熟練運用設(shè)計模式應(yīng)該是每一個軟件開發(fā)人員的必備技能。今天給大家介紹幾個常用的設(shè)計模式。
?
2. 單例模式
單例模式恐怕是很多開發(fā)人員最先接觸到的模式之一,可以認為就是一個全局變量。它的初始化過程無非就是一開始就new 一個instance,或者惰性初始化等需要用到的時候new 一個instance。這里需要注意的是在多線程情況下new一個instance。通常加上lock 可以解決問題。這里我們利用C# 的系統(tǒng)函數(shù) 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#的內(nèi)置容器數(shù)據(jù)結(jié)構(gòu) List,Stack等等,為了便于遍歷容器內(nèi)元素。這里給出一個簡單版的Stack實現(xiàn)
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 的 迭代器內(nèi)部實現(xiàn):
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 消息處理實現(xiàn)過程中工廠模式運用的非常多。比如
在MVC中處理一個Request,其實就是調(diào)用Controller下的一個Action,這就需要從Url 和Route 中反射出Controller對象,內(nèi)部由ControllerFactory創(chuàng)建。
它的默認實現(xiàn)是:DefaultControllerFactory
另一個例子是ValueProviderFactory,它使得Controller 下的Action 能夠接收到前端傳回來的數(shù)據(jù)并實現(xiàn)模型綁定,是典型的抽象工廠實現(xiàn)。
?
5. 訂閱模式
訂閱模式在某些項目運用比較多,比如 Knockout 整個項目就是一個大的訂閱模式的實現(xiàn),但是它是用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);}實現(xiàn):
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.? 責任鏈模式
責任鏈模式?jīng)]有像工廠模式那樣被人熟悉,在ASP.NET WebApi 中有一個非常典型的實現(xiàn) 就是WebApi的消息處理管道HttpMessageHandler
這里給一個簡單的模擬
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. 總結(jié)
市場上有很多關(guān)于設(shè)計模式的書,但是基本的設(shè)計模式大概有20多種,本文給大家介紹了幾種項目中常見的設(shè)計模式,其實有些設(shè)計模式在實際項目已經(jīng)不知不覺用起來了。
以后再給大家介紹其他的幾種設(shè)計模式。
?
歡迎訪問我的個人主頁 51zhang.net? 網(wǎng)站還在不斷開發(fā)中…..
posted on 2016-06-02 21:06?禪宗花園...迷失的佛 閱讀(...) 評論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/VectorZhang/p/5554388.html
總結(jié)
以上是生活随笔為你收集整理的C#项目中常用到的设计模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: adb -s指定安卓设备进行shell连
- 下一篇: 使用 Log4Net 记录日志