乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      設(shè)計模式中的那些工廠

       頭號碼甲 2021-03-24

      Intro

      設(shè)計模式中有幾個工廠模式,聊一聊這幾個工廠模式的各自用法和使用示例,工廠模式包含簡單工廠,抽象工廠,工廠方法,這些均屬于創(chuàng)建型模式,
      所謂創(chuàng)建型模式,就是說這幾個設(shè)計模式是用來創(chuàng)建對象的。

      簡單工廠

      首先來說一說,最簡單的簡單工廠

      簡單工廠模式是由一個工廠對象決定創(chuàng)建出哪一種產(chǎn)品類的實例

      嚴(yán)格的來說,簡單工廠模式是工廠模式家族中最簡單實用的模式,但不屬于23種 GOF 設(shè)計模式之一。因為每次要新增類型的時候必須修改工廠內(nèi)部代碼,不符合開閉原則。

      來看一個例子:

      public class OperationFactory
      {
          public static Operation CreateOperation(string operate)
          {
              Operation operation = null;
              switch (operate)
              {
                  case "+":
                      operation = new OperationAdd();
                      break;
      
                  case "-":
                      operation = new OpertaionSub();
                      break;
      
                  case "*":
                      operation = new OperationMul();
                      break;
      
                  case "/":
                      operation = new OperationDiv();
                      break;
              }
              return operation;
          }
      }

      這是一個簡單的計算器的示例,支持簡單的加減乘除操作,如果要增加一個操作的話就必須要有增加一個 switch ... case 分支,需要修改 CreateOperation 方法不能滿足對擴(kuò)展開放對修改關(guān)閉的開閉原則,所以普遍地認(rèn)為簡單工廠不屬于設(shè)計模式之一,但是我覺得有時候簡單的業(yè)務(wù)處理用簡單工廠還是比較方便的。

      抽象工廠

      抽象工廠模式,提供一系列相關(guān)或相互依賴對象的接口,而無需指定他們具體的類。

      實現(xiàn)抽象工作模式所需要的組件,主要部分:

      • 抽象工廠/抽象產(chǎn)品

      • 具體工廠1/具體產(chǎn)品1

      • 具體工廠2/具體產(chǎn)品2

      • ...

      在客戶端根據(jù)不同的配置選擇不同的工廠,例如根據(jù)配置的數(shù)據(jù)庫類型的不同選擇使用 Access 數(shù)據(jù)庫倉儲的工廠還是使用 SqlServer 數(shù)據(jù)庫的倉儲工廠

      示例:

      IDbFactory factory = new AccessFactory();
      var userRepo = factory.CreateUserRepo();
      userRepo.Insert(null);
      var departmentRepo = factory.CreateDepartmentRepo();
      
      factory = new SqlServerFactory();
      userRepo = factory.CreateUserRepo();
      userRepo.Insert(null);

      工廠方法

      工廠方法模式(Factory Method)定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到子類。

      工廠方法模式實現(xiàn)時,客戶端需要決定實例化哪一個工廠來實現(xiàn)客戶端的操作,也會存在著選擇判斷的問題,不過和簡單工廠相比,簡單工廠的選擇判斷是在工廠內(nèi)部,而工廠方法則將選擇判斷轉(zhuǎn)移到了客戶端。

      示例:

      ILeifengFactory factory = new UndergraduteFactory();
      var studentLeifeng = factory.CreateLeifeng();
      studentLeifeng.BuyRice();
      
      factory = new VolunteerFactory();
      var leifeng1 = factory.CreateLeifeng();
      leifeng1.Sweep();

      More

      工廠模式的作用無外乎下面這四個。這也是判斷要不要使用工廠模式的最本質(zhì)的參考標(biāo)準(zhǔn)。

      • 封裝變化:創(chuàng)建邏輯有可能變化,封裝成工廠類之后,創(chuàng)建邏輯的變更對調(diào)用者透明。

      • 代碼復(fù)用:創(chuàng)建代碼抽離到獨立的工廠類之后可以復(fù)用。

      • 隔離復(fù)雜性:封裝復(fù)雜的創(chuàng)建邏輯,調(diào)用者無需了解如何創(chuàng)建對象。

      • 控制復(fù)雜度:將創(chuàng)建代碼抽離出來,讓原本的函數(shù)或類職責(zé)更單一,代碼更簡潔。

      工廠方法和抽象工廠的區(qū)別

      工廠方法模式:定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪一個類
      抽象工廠模式:為創(chuàng)建一組相關(guān)或相互依賴的對象提供一個接口,而且無需指定他們的具體類
      區(qū)別在于產(chǎn)品,如果產(chǎn)品單一,最合適用工廠模式,但是如果有多個業(yè)務(wù)品種、業(yè)務(wù)分類時,通過抽象工廠模式產(chǎn)生需要的對象是一種非常好的解決方式。再通俗深化理解下:工廠模式針對的是一個產(chǎn)品等級結(jié)構(gòu) ,抽象工廠模式針對的是面向多個產(chǎn)品等級結(jié)構(gòu)的。

      抽象工廠關(guān)鍵在于產(chǎn)品之間的抽象關(guān)系,所以一般至少要兩個產(chǎn)品;工廠方法在于生成產(chǎn)品,不關(guān)注產(chǎn)品間的關(guān)系,所以可以只生成一個產(chǎn)品。

      抽象工廠更像一個復(fù)雜版本的策略模式,策略模式通過更換策略來改變處理方式或者結(jié)果;而抽象工廠的客戶端,通過更換工廠而改變結(jié)果。

      工廠方法目的是生產(chǎn)產(chǎn)品,所以能看到產(chǎn)品,而且還要使用產(chǎn)品。當(dāng)然,如果產(chǎn)品在創(chuàng)建者內(nèi)部使用,那么工廠方法就是為了完善創(chuàng)建者,從而可以使用創(chuàng)建者。另外創(chuàng)建者本身是不能更換所生產(chǎn)產(chǎn)品的。

      抽象工廠的工廠是類;工廠方法的工廠是方法。抽象工廠的工廠類就做一件事情生產(chǎn)產(chǎn)品。生產(chǎn)的產(chǎn)品給客戶端使用,絕不給自己用。工廠方法生產(chǎn)產(chǎn)品,可以給系統(tǒng)用,可以給客戶端用,也可以自己這個類使用。自己這個類除了這個工廠方法外,還可以有其他功能性的方法。

      選擇的優(yōu)化

      簡單工廠因為選擇是在工廠內(nèi)部的,不符合開閉原則,抽象工廠和工廠方法是將選擇權(quán)交給客戶端,由客戶端根據(jù)需要自己決定要實例化的工廠。
      在實際應(yīng)用的時候大部分情況是只會使用一種工廠,這種情況我們一般可以借助反射+配置來優(yōu)化選擇,如果使用依賴注入,可以直接注入需要的服務(wù)即可。

      使用反射+配置優(yōu)化

      private static readonly string AssemblyName = "AbstractFactoryPattern";
      private static readonly string DbName = ConfigurationHelper.AppSetting("DbName");
      
      public static IUserRepo CreateUserRepo()
      {
          return (IUserRepo)typeof(DataAccess).Assembly.CreateInstance($"{AssemblyName}.{DbName}UserRepo");
      }
      
      public static IDepartmentRepo CreateDepartmentRepo()
      {
          return (IDepartmentRepo)typeof(DataAccess).Assembly.CreateInstance($"{AssemblyName}.{DbName}DepartmentRepo");
      }

      使用依賴注入

      依賴注入可以使得我們的代碼變得更加良好,擴(kuò)展性更強(qiáng)。

      // 依賴注入
      var builder = new ContainerBuilder();
      builder.RegisterType<VolunteerFactory>().As<ILeifengFactory>();
      builder.RegisterType<SqlServerFactory>().As<IDbFactory>();
      var container = builder.Build();
      
      var leifengFactory = container.Resolve<ILeifengFactory>();
      var volunteer = leifengFactory.CreateLeifeng();
      volunteer.Wash();
      
      var dbFactory = container.Resolve<IDbFactory>();
      dbFactory.CreateDepartmentRepo().CreateDepartment(null);

      Reference

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多