.Net23种设计模式
C#常见的设计模式
⼀、概要:
模式分为三种,设计模式、体系结构模式与惯⽤法。其中惯⽤法是⼀种语⾔紧密相关的模式,例如,定界加锁模式其实是⼀种惯⽤法。
在C#项⽬开发过程中,很多情况下您已经使⽤了某些模式,但或许您并不知道⾃⼰所使⽤的这种解决⽅案是⼀种已经被总结归纳的模式。
⼯⼚、策略、桥接、模板⽅法、代理等等23种Gof经典模式是属于设计模式,设计模式的粒度相对较⼩,基本上⽤于提⾼模块内部的可扩展性和可维护性需求
writeline方法属于类三层、MVC、IoC/DI等属于体系结构模式,粒度⽐设计模式⼤,它是从项⽬的整体⾓度去看项⽬的架构。设计需要合理性,架构同样追求合理性,这就是架构模式的⽤途。
C#的经典样例petshop中,采⽤分层思想构架了整个⽹站,这⾥的分层就是体系结构模式;⽽在数据库访问层,则采⽤⼯⼚模式来泛化数据库操作,使得业务层不需要关⼼您现在的数据库是SQL server的,还是oracle的。这就是设计模式的使⽤。
模式应⽤不是⼀两句话能够说清楚的,也不是⼀天两天能够体会的,需要楼主慢慢体会与学习。
⼆、分类⽬录:
创建型:
1. 单件模式(Singleton Pattern)
2. 抽象⼯⼚(Abstract Factory)
3. 建造者模式(Builder)
4. ⼯⼚⽅法模式(Factory Method)
5. 原型模式(Prototype)
结构型:
6. 适配器模式(Adapter Pattern)
7. 桥接模式(Bridge Pattern)
8. 装饰模式(Decorator Pattern)
9. 组合模式(Composite Pattern)
10. 外观模式(Facade Pattern)
11. 享元模式(Flyweight Pattern)
12. 代理模式(Proxy Pattern)
13. 模板⽅法(Template Method)
14. 命令模式(Command Pattern)
15. 迭代器模式(Iterator Pattern)
⾏为型:
16. 观察者模式(Observer Pattern)
17. 解释器模式(Interpreter Pattern)
18. 中介者模式(Mediator Pattern)
19. 职责链模式(Chain of Responsibility Pattern)
20. 备忘录模式(Memento Pattern)
21. 策略模式(Strategy Pattern)
22. 访问者模式(Visitor Pattern)
23. 状态模式(State Pattern)
C# 23种设计模式
China Document 4 Colors
1.1节⼯期
How are you
1.1.1 完成⽇期
1.2节创建型模式
1.2.1 单件模式(Singleton Pattern)
动机(Motivation):
在软件系统中,经常有这样⼀些特殊的类,必须保证它们在系统中只存在⼀个实例,才能确保它们的逻辑正确性、以及良好的效率。如何绕过常规的构造器,提供⼀种机制来保证⼀个类只创建⼀个实例?
这应该是类设计者的责任,⽽不是类使⽤者的责任。
结构图:
意图:
保证⼀个类仅有⼀个实例,并提供⼀个访问它的全局访问点。
------<<;设计模式>>GOF
⽣活的例⼦:
适⽤性:
(1)当类只能有⼀个实例⽽且客户可以从⼀个众所周知的访问点访问它时。
(2)当这个唯⼀实例应该是通过⼦类化可扩展的,并且客户应该⽆需更改代码就能使⽤⼀个扩展的实例时。
代码实现:
(1)单线程Singleton实现
class SingleThread_Singleton
{
private static SingleThread_Singleton instance = null;
private SingleThread_Singleton(){}
public static SingleThread_Singleton Instance
{
get
{
if (instance == null)
{
instance = new SingleThread_Singleton();
}
return instance;
}
}
}
以上代码在单线程情况下不会出现任何问题。但是在多线程的情况下却不是安全的。
如两个线程同时运⾏到 if (instance == null)判断是否被实例化,⼀个线程判断为True后,在进⾏创建
instance = new SingleThread_Singleton();之前,另⼀个线程也判断(instance == null),结果也为True.
这样就就违背了Singleton模式的原则(保证⼀个类仅有⼀个实例)。
怎样在多线程情况下实现Singleton?
(2)多线程Singleton实现:
1 class MultiThread_Singleton
2 {
3 private static volatile MultiThread_Singleton instance = null;
4 private static object lockHelper = new object();
5 private MultiThread_Singleton() { }
6 public static MultiThread_Singleton Instance
7 {
8 get
9 {
10 if (instance == null)
11 {
12 lock (lockHelper)
13 {
14 if (instance == null)
15 {
16 instance = new MultiThread_Singleton();
17 }
18 }
19 }
20 return instance;
21 }
22 }
23
此程序对多线程是安全的,使⽤了⼀个辅助对象lockHelper,保证只有⼀个线程创建实例(如果instance为空,保证只有⼀个线程instance = new MultiThread_Singleton();创建唯⼀的⼀个实例)。(Double Check)
请注意⼀个关键字volatile,如果去掉这个关键字,还是有可能发⽣线程不是安全的。
volatile 保证严格意义的多线程编译器在代码编译时对指令不进⾏微调。
(3)静态Singleton实现
3 class Static_Singleton
4 {
5 public static readonly Static_Singleton instance = new Static_Singleton();
6 private Static_Singleton() { }
7 }
以上代码展开等同于
1 class Static_Singleton
2 {
3 public static readonly Static_Singleton instance;
4 static Static_Singleton()
5 {
6 instance = new Static_Singleton();
7 }
8 private Static_Singleton() { }
9 }
由此可以看出,完全符合Singleton的原则。
优点:简洁,易懂
缺点:不可以实现带参数实例的创建
1.2.2 抽象⼯程模式(Abstract Factory)
常规的对象创建⽅法:
//创建⼀个Road对象
Road road =new Road();
new 的问题:
实现依赖,不能应对“具体实例化类型”的变化。
解决思路:
封装变化点-----哪⾥变化,封装哪⾥
潜台词:如果没有变化,当然不需要额外的封装!
⼯⼚模式的缘起
变化点在“对象创建”,因此就封装“对象创建”
⾯向接⼝编程----依赖接⼝,⽽⾮依赖实现
最简单的解决⽅法:
1 class RoadFactory{
2 public static Road CreateRoad()
3 {
4 return new Road();
5 }
6 }
7 //创建⼀个Road对象
8 Road road=roadFactory.CreateRoad();
创建⼀系列相互依赖对象的创建⼯作:
假设⼀个游戏开场景:
我们需要构造"道路"、"房屋"、"地道","从林"...等等对象
⼯⼚⽅法如下:
1 class RoadFactory
2 {
3 public static Road CreateRoad()
4 {
5 return new Road();
6 }
7 public static Building CreateBuilding()
8 {
9 return new Building();
10 }
11 public static Tunnel CreateTunnel()
12 {
13 return new Tunnel();
14 }
15 public static Jungle CreateJungle()
16 {
17 return new Jungle();
18 }
19 }
调⽤⽅式如下:
1 Road road = RoadFactory.CreateRoad();
3 Building building = RoadFactory.CreateBuilding();
4 Tunnel tunnel = RoadFactory.CreateTunnel();
5 Jungle jungle = RoadFactory.CreateJungle();
如上可见简单⼯⼚的问题:
不能应对"不同系列对象"的变化。⽐如有不同风格的场景---对应不同风格的道路,房屋、地道....
如何解决:
使⽤⾯向对象的技术来"封装"变化点。
动机(Motivate):
在软件系统中,经常⾯临着"⼀系统相互依赖的对象"的创建⼯作:同时,由于需求的变化,往往存在更多系列对象的创建⼯作。
如何应对这种变化?如何绕过常规的对象创建⽅法(new),提供⼀种"封装机制"来避免客户程序和这种"多系列具体对象创建⼯作"的紧耦合?
意图(Intent):
提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
----《设计模式》GOF
结构图(Struct):
适⽤性:
1.⼀个系统要独⽴于它的产品的创建、组合和表⽰时。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论