設計模式是軟件開發討論中,亙古不變的話題,今天又拿出來說道兩句,也是對設計模式的一個復習吧。
### 工廠方法模式
??????**工廠方法模型定義了一個用于創建對象的接口,讓子類決定實例化哪一個類,工廠模式使一個類的實例化延遲到了其子類中**。工廠方法模式是優化的簡單工廠模式,它很好的支持了“開閉原則”。每一個具體的工廠只能構建一個類的對象。具體工廠類與產品類是一對一的關系。

~~~
/// <summary>
/// 抽象產品類
/// </summary>
public class Product{
public Product(){
Console.Write("new Product");
}
}
/// <summary>
/// 具體產品類A
/// </summary>
public class ConcreteProductA:Product {
public ConcreteProduct(){
Console.Write("創建了一個 ConcreteProductA");
}
}
/// <summary>
/// 具體產品類B
/// </summary>
public class ConcreteProductB:Product {
public ConcreteProduct(){
Console.Write("創建了一個 ConcreteProductB");
}
}
/// <summary>
/// 抽象的創建者
/// </summary>
abstract public class Creator{
//抽象的工廠方法
public abstract Product FactoryMethod();
}
/// <summary>
/// 具體方法工廠A
/// </summary>
public class ConcreteCreatorA:Creator{
//返回一個產品A的對象
public override Product FactoryMethod(){
return new ConcreteProductA();
}
}
/// <summary>
/// 具體方法工廠B
/// </summary>
public class ConcreteCreatorB:Creator{
//返回一個產品B的對象
public override Product FactoryMethod(){
return new ConcreteProductB();
}
}
//client端
static void Main(string[] args)
{
Creator c = new ConcreteCreatorA();
Product p = c.FcatoryMethod();
c = new ConcreteCreatorB();
p = c.FcatoryMethod();
Console.ReadLine();
}
~~~
### 適配器模式Adapter
?????**適配器模式是將一個類的接口轉換成客戶希望的另外一個接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。**
?????兩個成熟的類需要通信,但是接口不同,由于開閉原則,我們不能去修改這兩個類的接口,所以就需要一個適配器來完成銜接過程。
?????變壓器就是很好的適配器模式的例子。用電設備所需要的電壓是9V,但是電線上的電壓卻是220V的,我們不能去更改它們的電壓輸入或輸出,所以我們用到了變壓器。變壓器是220V的輸入,9V的輸出。這樣就可以將200V的電壓變為9V的電壓,用變壓器將用電設備連接到了電線上工作了。


????? 上面兩幅圖中,都是Client端需要Request這個方法,但是Adaptee沒有這個方法,所以就需要提供一個中間件/包裝類(Wrapper)Adapter類來銜接。不同的是第一幅圖Adapter繼承自Adaptee,而第二幅圖是在Adapter類中包裝了一個Adaptee的實例。這就決定了第一幅圖講的是“類的結構模式”,而第二幅圖則是“對象的結構模式”。
~~~
/// <summary>
/// 目標接口,客戶所期待的接口。
/// </summary>
public class Target{
public virtual void Request(){
Console.Write("我是本系統中的普通請求.");
}
}
/// <summary>
/// 適配器,匹配2個接口不一致的類
/// </summary>
public class Adapter:Target{
private Adaptee adaptee = new Adaptee();
public void Request(){
adaptee.SpecificRequest();
}
}
/// <summary>
/// 源接口,與客戶期待的接口不一致
/// </summary>
public class Adaptee(){
public void SpecificRequest(){
Console.Write("我是原有的真實調用的系統");
}
}
//client端
static void Main(string[] args)
{
Target t = new Adapter();
t.Request();
Console.ReadLine();
}
~~~
### 橋接模式 Bridge
?????**橋接模式將抽象部分與它的實現部分分離,使它們都可以獨立地變化**。它很好的支持了開閉原則和組合及復用原則。實現系統可能有多角度分類,每一種分類都有可能變化,那么就把這些多角度分離出來讓他們獨立變化,減少他們之間的耦合。
?????2個相互耦合的系列,每個系列都有各自的產品變動。將這2個系列抽象成2個角色類,將各自的變化封裝到對象的角色類中,然后再將2個角色類之間用組合的關系表示,這樣就大大簡化了使用類繼承的復雜性,邏輯變得清晰了,易于擴展和維護。
?????橋接模式封裝了變化,完成了解耦,實現了弱耦合。

~~~
/// <summary>
/// 抽象部分
/// </summary>
public class Abstraction{
protected Implementor implementor;
public void SetImplementor(Implementor implementor){
this.implementor = implementor;
}
public virtual void Operation(){
implementor.OperationImp();
}
}
/// <summary>
/// 被提煉的抽象部分
/// </summary>
public class RefinedAbstraction:Abstraction{
public override void Operation(){
implementor.OperationImp();
}
}
/// <summary>
/// 實現部分
/// </summary>
abstract public class Implementor{
public abstract void OperationImp();
}
/// <summary>
/// 具體實現A
/// </summary>
public class conscreteImplementorA:Implementor{
pulic override void OperationImp(){
Console.Write("我是具體的A");
}
}
/// <summary>
/// 具體實現B
/// </summary>
public class conscreteImplementorB:Implementor{
pulic override void OperationImp(){
Console.Write("我是具體的B");
}
}
//client端
static void Main(string[] args)
{
Abstraction ab = new RefinedAbstraction();
ab.SetImplementor(new conscreteImplementorA());
ab.Operaton();
ab.SetImplementor(new conscreteImplementorB());
ab.Operaton();
Console.ReadLine();
}
~~~
具體的實例可以看我的另一篇博文《[面與鹵的鵲橋相會——橋接模式](http://blog.csdn.net/xiaoxian8023/article/details/7642352)》
### 裝飾模式 Decorator
????? **裝飾模式動態地給一個對象添加一些額外的職責,就增加功能來說,它比生成子類更靈活**。也可以這樣說,裝飾模式把復雜類中的核心職責和裝飾功能區分開了,這樣既簡化了復雜類,有去除了相關類中重復的裝飾邏輯。裝飾模式沒有通過繼承原有類來擴展功能,但卻達到了一樣的目的,而且比繼承更加靈活,所以可以說裝飾模式是繼承關系的一種替代方案。裝飾模式解耦了核心和裝飾功能,所以也是強調了松耦合。?

~~~
/// <summary>
/// 最高接口,被裝飾者和“裝飾品”都繼承于此
/// </summary>
abstract public class Component{
public abstract void Operation();
}
/// <summary>
/// 具體的被裝飾者
/// </summary>
public class Concretecomponent:Component{
public override void Operation(){
Console.Write("具體對象的裝飾操作");
}
}
/// <summary>
/// 裝飾類
/// </summary>
abstract public class Decorator:Component(){
protected Component component;
public void SetComponent(Component component){
this.component = component;
}
public override void Operation(){
if(component!=null) component.Operation();
}
}
/// <summary>
/// 具體的裝飾類A
/// </summary>
public class ConcreteDecoratorA:Decorator{
private string addedState;
public override void Operation(){
base.Operation();
addedState="New State";
Console.Write("具體裝飾A的操作(添加了新的狀態)");
}
}
/// <summary>
/// 具體的裝飾類B
/// </summary>
public class ConcreteDecoratorB:Decorator{
public override void Operartion(){
base.Operation();
AddedBehavior();
Console.WriteLine("具體裝飾B的操作(添加了新的方法)");
}
private void AddedBehavior(){
//添加新的行為
}
}
//client端
static void Main(string[] args)
{
Concretecomponent c = new Concretecomponent();
Decorator d1 = new ConcreteDecoratorA();
Decorator d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);//注意這里裝飾的是d1,因為這里的d1是裝飾了d1的c。
d2.Operation();
Console.ReadLine();
}
~~~
### 外觀模式 Facade
????? **外觀模式為子系統中的一組接口提供了一個一致的界面,此模式**定義了一個高層接口,這個接口使得這些子系統更加容易使用。**
????? 外觀模式中,客戶對各個具體的子系統是不了解的,所以對這些子系統進行了封裝,對外只提供了用戶所明白的單一而簡單的接口,用戶直接使用這個接口就可以完成操作,而不用去理睬具體的過程,而且子系統的變化不會影響到用戶,這樣就做到了信息隱蔽。
????? 這就相當于新生接待員。新生對入學流程不清楚,但是接待員學長可是明白的。學生跟著接待員就可以把各個手續辦理完畢了。可以說**外觀模式封裝了細節**。

~~~
/// <summary>
/// 高層的統一接口,封裝了子系統繁雜的接口。
/// </summary>
public class Facade{
private SubSystemOne one;
private SubSystemTwo two;
private SubSystemThree three;
public Facade(){
one = new SubSystemOne();
two = new SubSystemTwo();
three = new SubSystemThree();
}
public void MethodA(){
one.MethodOne();
two.MethodTwo();
}
public void MethodB(){
one.MethodOne();
three.MethodThree();
}
}
/// <summary>
/// 子系統One。
/// </summary>
public class SubSystemOne{
public void MethodOne(){
Console.Write("我是One");
}
}
/// <summary>
/// 子系統Two
/// </summary>
public class SubSystemTwo{
public void MethodTwo(){
Console.Write("我是Two");
}
}
/// <summary>
/// 子系統Three
/// </summary>
public class SubSystemThree{
public void MethodThree(){
Console.Write("我是Three");
}
}
//client端
static void Main(string[] args)
{
Facade f1 = new Facade();
f1.MethodA();
Facade f2 = new Facade();
f2.MethodB();
Console.ReadLine();
}
~~~
### 策略模式 Strategy
?????**策略模式定義一系列的算法,把它們一個個封裝起來,并且使它們可以相互替換。本模式使得算法的變化不會影響到使用算法的客戶。**
??????策略模式將每一個算法封裝到一個具有公共接口的獨立類中,解除了客戶與具體算法的直接耦合,是客戶改變算法更為容易。
???????策略模式+簡單工廠+反射+配置文件可以組成更為靈活的方式。?

~~~
/// <summary>
/// 算法的公共接口
/// </summary>
abstract public class Strategy{
public abstract void AlgorithmInterface();
}
/// <summary>
/// 具體算法A
/// </summary>
public class ConcreteStrategyA:Strategy{
public override void AlgorithmInterface(){
Console.Write("具體算法A");
}
}
/// <summary>
/// 具體算法B
/// </summary>
public class ConcreteStrategyB:Strategy{
public override void AlgorithmInterface(){
Console.Write("具體算法B");
}
}
/// <summary>
/// 具體算法C
/// </summary>
public class ConcreteStrategyC:Strategy{
public override void AlgorithmInterface(){
Console.Write("具體算法C");
}
}
/// <summary>
/// 上下文,用來維護一個對Strategy對象的引用。
/// </summary>
public class Context{
private Strategy strategy;
public Context(Strategy strategy){
this.strategy=strategy;
}
//上下文接口
public void ContextInterface(){
strategy.AlgorithmInterface();
}
}
//client端
static void Main(string[] args)
{
Context context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
Console.ReadLine();
}
~~~
### 觀察者模式 Observer
??????**觀察者模式定義了對象間的一種一對多的依賴關系,當一個對象的狀態發生變化時,所有依賴它的對象都會得到通知,并被自動更新,**
????????系統中有兩個方面,其中一個方面依賴與另一個方面,我們把這兩個方面抽象,是各自可以獨立的變化和復用。
????????就像我們現在所用到的分層,不就是一層層的依賴么?還有系統組件升級,系統功能也跟著變化,這也屬于觀察者模式。

~~~
/// <summary>
/// 抽象觀察類
/// </summary>
abstract public class Observer{
public abstract void Update();
}
/// <summary>
/// 具體觀察類
/// </summary>
public class Concreteobserver:Observer{
private string name;
private string observerState;
private ConcreteSubject subject;
public Concreteobserver(ConcreteSubject subject,string name){
this.subject=subject;
this.name= name;
}
public override void Update(){
observerState=subject.GetState();
Console.write("觀察者{0}的新狀態是{1}",name,observerState);
}
}
/// <summary>
/// 抽象主題類
/// </summary>
abstract public class Subject(){
private List<observer> observers = new List<observer>() ;
public void Attach(Observer observer){
observers.Add(Observer);
}
public void Detach(Observer Observer){
observers.Remove(Observer);
}
public void NotifyObservers(){
foreach(Observer o in observers){
o.Update();
}
}
}
/// <summary>
/// 具體主題類
/// </summary>
public class ConcreteSubject:Subject{
private string subjectState;
public string SubjectState{
get{return subjectstate;}
set{subjectstrate=value;}
}
public void GetState(){
return subjectstate;
}
}
//client端
static void Main(string[] args)
{
ConcreteSubject c = new ConcreteSubject();
Concreteobserver o1 = new Concreteobserver(c,"X");
Concreteobserver o2 = new Concreteobserver(c,"Y");
Concreteobserver o3 = new Concreteobserver((c,"Z");
c.Attach(o1);
c.Attach(o2);
c.Attach(o3);
c.subjectstate="abc";
c.Nofify();
Console.ReadLine();
}
~~~
欲了解其他模式,請查看我的這3篇博文:
《[設計模式之創建型模式](http://blog.csdn.net/xiaoxian8023/article/details/6933972)》
《[設計模式之結構型模式](http://blog.csdn.net/xiaoxian8023/article/details/6937589)》
《[設計模式之行為型模式](http://blog.csdn.net/xiaoxian8023/article/details/6943768)》