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创建。

它的默认实现是:DefaultControllerFactory

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

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

这里给一个简单的模拟

    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  网站还在不断开发中…..

C#项目中常用到的设计模式的更多相关文章

  1. Android 项目中常用到的第三方组件

    项目中常用到的第三方组件 1 社会化分享ShareSDK-Core-2.5.9.jarShareSDK-QQ-2.5.9.jarShareSDK-QZone-2.5.9.jarShareSDK-Sin ...

  2. 项目中常用js方法整理common.js

    抽空把项目中常用js方法整理成了common.js,都是网上搜集而来的,大家一起分享吧. var h = {}; h.get = function (url, data, ok, error) { $ ...

  3. 记录下项目中常用到的JavaScript/JQuery代码二(大量实例)

    记录下项目中常用到的JavaScript/JQuery代码一(大量实例) 1.input输入框监听变化 <input type="text" style="widt ...

  4. 项目中常用的MySQL 优化

    本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下: 一.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我 ...

  5. JAVA项目中常用的异常处理情况总结

    JAVA项目中常用的异常知识点总结 1. java.lang.nullpointerexception这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用 ...

  6. VB的一些项目中常用的通用方法-一般用于验证类

    1.VB的一些项目中常用的通用方法: ' 设置校验键盘输入值,数字 Public Function kyd(key As Integer) As Integer Dim mychar mychar = ...

  7. JAVA项目中常用的异常知识点总结

    JAVA项目中常用的异常知识点总结 1. java.lang.nullpointerexception这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用 ...

  8. (42)嵌入式项目中常用到的C语言技能总结

    嵌入式项目中常用到的C语言技能 1.指针 .结构体. 枚举. 联合.数组.字符串.链表七个专题 2.结构体指针.结构体的多重嵌套[结构体中嵌套结构体.结构体中嵌套枚举.联合体.结构体中嵌套函数指针.一 ...

  9. ES6系列之项目中常用的新特性

    ES6系列之项目中常用的新特性 ES6常用特性 平时项目开发中灵活运用ES6+语法可以让开发者减少很多开发时间,提高工作效率.ES6版本提供了很多新的特性,接下来我列举项目中常用的ES6+的特性: l ...

随机推荐

  1. android:onClick vs setOnClickListener

    为Android Widgets添加点击事件处理函数又两种方法,一个是在Xml文件中添加onClick属性,然后在代码中添加对应的函数.另一个是直接在代码中添加setOnClickListener函数 ...

  2. ios UIView autoresizingSubview 属性

    自动尺寸调整行为 当您改变视图的边框矩形时,其内嵌子视图的位置和尺寸往往也需要改变,以适应原始视图的新尺寸.如果视图的autoresizesSubviews属性声明被设置为YES,则其子视图会根据au ...

  3. DDD~领域事件中使用分布式事务

    回到目录 对于一个聚合来说,它可能会被附加很多事件,这里我们叫它领域事务,因为一个聚会我们可以把它理解成一个领域,一个业务.对于领域事件不清楚的同学可以看看我的这篇文章<DDD~领域事件与事件总 ...

  4. Java线程:线程的交互

      一.线程交互的基础知识   SCJP所要求的线程交互知识点需要从java.lang.Object的类的三个方法来学习:    void notify()           唤醒在此对象监视器上等 ...

  5. js 数组

    js中的数组类似与java中的容器 类型可以不同.长度可变 一.数组的声明 var arr1=new Array();//数组的声明一     var arr2=[1,2,3,true,new Dat ...

  6. Java时间日期格式转换

    1.这个是系统自动默认的时间格式,或者说是美式格式: Long time = System.currentTimeMillis();                Date date = new Da ...

  7. 接触LLBL Gen Pro 对象关系映射框架后 前途变的一片光明

    时间回到2010年,那时候还是熟悉代码生成+基础框架这种模式,基本的开发思路是通过代码生成器生成实体,再生成接口与实现类,最后拖拉控件,写界面数据绑定代码.基本上就是动软代码生成器给出的模式,或是微软 ...

  8. HTML内联元素

    前面的话 用于标记段落里的文本和其他内容组的元素种类很多,本文将这些文本级元素进行简单分类,便于整理和记忆 通用容器 <span>元素是短语内容的通用行内容器,并没有任何特殊语义.可以使用 ...

  9. (扩展欧几里德算法)zzuoj 10402: C.机器人

    10402: C.机器人 Description Dr. Kong 设计的机器人卡尔非常活泼,既能原地蹦,又能跳远.由于受软硬件设计所限,机器人卡尔只能定点跳远.若机器人站在(X,Y)位置,它可以原地 ...

  10. Python函数参数默认值的陷阱和原理深究"

    本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的 本博客已经迁移至: http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文 ...