C#项目中常用到的设计模式
2016-06-23 09:57
585 查看
1.引言
一个项目的通常都是从Demo开始,不断为项目添加新的功能以及重构,也许刚开始的时候代码显得非常凌乱,毫无设计可言。但是随着项目的迭代,往往需要将很多相同功能的代码抽取出来,这也是设计模式的开始。熟练运用设计模式应该是每一个软件开发人员的必备技能。今天给大家介绍几个常用的设计模式。
2. 单例模式
单例模式恐怕是很多开发人员最先接触到的模式之一,可以认为就是一个全局变量。它的初始化过程无非就是一开始就new 一个instance,或者惰性初始化等需要用到的时候new 一个instance。这里需要注意的是在多线程情况下new一个instance。通常加上lock 可以解决问题。这里我们利用C# 的系统函数 Interlocked.CompareExchangeinternal
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
: IEnumerable,
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
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
GetEnumerator()
{
return
new
StackEnumerator(this);
}
}
Stack 的 迭代器内部实现:
internal
class
StackEnumerator
: IEnumerator
,
IEnumerator
{
private
Stack
_stack;
private
int
_index;
public
StackEnumerator(Stack
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
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
_observers;
private
string
_name;
public
WeChatArticle(string
name)
{
this._name
= name;
this._observers
= new
List();
}
public
IEnumerable
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
controls;
public
CompositeControl(IList
cons)
{
this.controls
= new
List(cons);
}
public
void
Draw(ControlContext
context)
{
this.controls.ForEach(c
=> c.Draw(context));
}
public
void
Add(IControl
control)
{
this.controls.Add(control);
}
}
8. 总结
市场上有很多关于设计模式的书,但是基本的设计模式大概有20多种,本文给大家介绍了几种项目中常见的设计模式,其实有些设计模式在实际项目已经不知不觉用起来了。
相关文章推荐
- C# 静态类 考考你
- C#ArrayList
- 【C#】第3章补充(二)如何将图形作为对象
- C#中System.Func<>与System.Action<>的区别
- C#的标准容器类
- 在C#项目中如何添加“Web引用”?
- C#问题
- c# API
- c#服务器管理程序
- C#实现通过模板自动创建Word文档的方法
- C# 捕获关机事件方法
- C#制作、打包、签名、发布Activex全过程
- C#接口的作用
- c# 发送GET 和 POST请求
- c# 序列化和反序列化
- C# dataTable的linq联合查询,插入到新的dataTable中
- 【C#】关于文件的写入与读取
- C#.NET 大型企业信息化系统 - 防黑客攻击 - SSO系统加固优化经验分享
- C# 通过反射获取实例对象
- C# 将两个不同的dataTable合并到一个自定义的dataTable中