解決問題:建立對象,將建立對象的任務交給另外一個對象完成。web
組成:安全
優勢:客服了簡單工廠違背開放封閉原則的缺點。服務器
優勢:讓具體的建立實例過程與客戶端分離,客戶端是經過他們的抽象接口操縱實例,產品的具體類名也被多線程
具體工廠的實現分離,不會出如今客戶端代碼中。併發
缺點:若是新增一個業務產品,就須要修改原有各工廠子類,添加生產新產品的方法,同時還須要新增每一個負載均衡
工廠生產的具體業務產品類,才能夠徹底實現。函數
優勢:客戶不須要知道具體建立對象,隱藏了類的實例是如何被建立的。性能
簡單工廠:網站
UML圖:ui
僞代碼實現:
public class 工廠 { public static 產品 Factory(string 產品名稱) { Product result=null; switch(產品名稱) { case"產品1": result=new 產品1(); break; case"產品2": result=new 產品2(); break; } return result; } } 客戶端: 產品 =工廠.Factory("產品1");
工廠方法:
UML圖:
僞代碼實現:
public interface IFactory { Product Factory(); } public class FactoryProduct1 : IFactory { public Product Factory() { return new Product1(); } } //客戶端 IFactory factory=new FactoryProduct1(); Product product=factory.Factory();
抽象工廠:
在工廠方法(只能生產一種業務產品)的基礎上擴展而來,能生產多種業務產品,以下圖的用戶和部門;
可是一旦咱們須要增長一個新的業務產品,好比項目Project,則至少須要增長3個類,IProject、SqlserverProject、AccessProject,還須要修改IFactory、SqlserverFactory、AccessFactory,才能徹底實現。
可以使用簡單工廠來改進抽象工廠,更進一步,經過反射+抽象工廠、反射+配置文件來進行改進。
UML圖:
僞代碼:
//客戶端 IFactory fac=new SqlserverFactory();//new AcessFactory(); IUser iu=fac.CreatUser(): iu.insert(); IDepartment id=fac.CreateDepartment(); id.insert();
建造者模式:
理解:指揮者指揮某某作事。好比常見舉例飯店經理指揮收銀員點餐、工做人員出餐就是這個思想。
UML圖:
僞代碼實現:
/// 事情 public class Thing { public void print(string Name) { } } // 工做者接口 public interface IWorker { void doThing(); } //具體工做者1 public class Worker1 : IWorker { public void doThing() { // TODO: implement } } //具體工做者2 public class Worker2 : IWorker { public void doThing() { // TODO: implement } } /// 指揮者 public class Director { public Director(IWorker worker) { iWorker=worker; } public void command() { iworker.doThing(); } public IWorker iWorker; } //客戶端 Director director=new Director(new Worker1()); director.command();
原型模式:
通俗的講:就是爲了複製一個對象,避免每次new類生成對象後須要重複設置相同的屬性,複製後只需對個別須要個性化的屬性設置個性化的值就能夠了;避免每new一次,執行一次構造函數,若是構造函數的執行時間很長,屢次執行致使系統低效,在初始化信息不發生變化的狀況下,克隆既隱藏了對象建立的細節,又能對性能大大的提升。
重點:須要注意深複製與淺複製兩種的區別。
UML圖:
僞代碼實現:
//淺複製 class Program { static void Main(string[] args) { ShallowCopy sc1 = new ShallowCopy(); ShallowCopy sc2 = (ShallowCopy)sc1.Clone(); sc1.v[0] = 9; sc1.Display();//輸出:9,2,3 sc2.Display();//輸出:9,2,3 Console.Read(); } } class ShallowCopy : ICloneable { public int[] v = { 1, 2, 3 }; public Object Clone() { return this.MemberwiseClone();//淺複製 } public void Display() { foreach (int i in v) Console.Write(i + ", "); Console.WriteLine(); } }
//深複製 class Program { static void Main(string[] args) { DeepCopy dc1 = new DeepCopy(); DeepCopy dc2 = (DeepCopy)dc1.Clone(); dc1.v[0] = 9; dc1.Display(); dc2.Display(); Console.Read(); } } class DeepCopy : ICloneable { public int[] v = { 1, 2, 3 }; // 默認構造函數 public DeepCopy() { } // 供Clone方法調用的私有構造函數 private DeepCopy(int[] v) { this.v = (int[])v.Clone(); } public Object Clone() { // 構造一個新的DeepCopy對象,構造參數爲 // 原有對象中使用的 v return new DeepCopy(this.v); } public void Display() { foreach (int i in v) Console.Write(i + ", "); Console.WriteLine(); } }
單例模式:
使用場景:
一個網站的服務端程序,須要考慮怎樣才能承載大量用戶,在作web程序的時候有各類負載均衡的方案,其基本思想就是有一個統一的入口,而後由它來分配用戶到各個服務器上去。須要考慮的問題是,即便在多線程的併發狀態下,用戶只能經過一個惟一的入口來分配,由此引入單例模式來實現這個惟一的入口。
不要濫用Singleton模式,只有非一個實例不可的狀況下才考慮引入Singleton。不然,程序的可擴展性可能會受到限制。
UML圖:
僞代碼實現,「懶漢式單例類」(被第一次引用時纔會本身實例化):
class Singleton { private static Singleton instance; private static readonly object syncRoot = new object();//程序運行時建立一個靜態只讀的進程輔助對象 private Singleton()//構造方法改爲private,堵死外界經過new來建立此類實例的可能 { } public static Singleton GetInstance() { if (instance == null)//先判斷實例是否存在,不存在再加鎖處理,雙重鎖定 { lock (syncRoot) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
C#提供了一種「靜態初始化」方法,這種方法不須要開發人員顯示的編寫線程安全的代碼,便可解決多線程環境下它是不安全的問題,稱爲「餓漢式單例類」(本身被加載時就實例化)。
public sealed class Singleton//sealed阻止派生髮生,而派生可能會增長實例 { private static readonly Singleton instance = new Singleton();//在第一次引用類的任何成員時建立實例,公共語言運行庫負責處理變量初始化 private Singleton() { } public static Singleton GetInstance() { return instance; } }