設計模式——建立型模式

解決問題:建立對象,將建立對象的任務交給另外一個對象完成web

組成:安全

  • 簡單工廠:客戶傳遞建立產品的類型到工廠類中去,工廠類根據類型實例化不一樣的類。
  • 工廠方法Factory Method:定義一個用戶建立對象的接口,讓子類決定實例化哪個類。

                          優勢:客服了簡單工廠違背開放封閉原則的缺點。服務器

  • 抽象工廠Abstract Factory:提供一個建立一系列或相關依賴對象的接口,而無需指定它們具體的類。

                          優勢:讓具體的建立實例過程與客戶端分離,客戶端是經過他們的抽象接口操縱實例,產品的具體類名也被多線程

                                   具體工廠的實現分離,不會出如今客戶端代碼中。併發

                          缺點:若是新增一個業務產品,就須要修改原有各工廠子類,添加生產新產品的方法,同時還須要新增每一個負載均衡

                                   工廠生產的具體業務產品類,才能夠徹底實現。函數

  • 建造者模式Builder:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
  • 原型模式Prototype:用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。
  • 單例模式Singleton:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

優勢:客戶不須要知道具體建立對象,隱藏了類的實例是如何被建立的。性能

簡單工廠:網站

UML圖:ui

ZY4QAYA%DN0X0RN@T{}ZJBC[8]

僞代碼實現:

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圖:

image

僞代碼實現:

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圖:

image

僞代碼:

//客戶端
IFactory fac=new SqlserverFactory();//new AcessFactory();

IUser iu=fac.CreatUser():
iu.insert();

IDepartment id=fac.CreateDepartment();
id.insert();

建造者模式:

理解:指揮者指揮某某作事。好比常見舉例飯店經理指揮收銀員點餐、工做人員出餐就是這個思想。

UML圖:

image

僞代碼實現:

/// 事情
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圖:

image

僞代碼實現:

//淺複製
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圖:

image

僞代碼實現,「懶漢式單例類」(被第一次引用時纔會本身實例化):

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;
        }
    }
相關文章
相關標籤/搜索