簡單工廠模式(Simple Factory Pattern)

来源:https://www.cnblogs.com/ygsworld/archive/2019/04/04/10649491.html
-Advertisement-
Play Games

簡單工廠模式概述 簡單工廠模式的結構與實現 結構: 實現 1 abstract class Product 2 { 3 public void MethName() 4 { 5 //公共方法的實現 6 } 7 public abstract void MethodDiff(); 8 //聲明抽象業務 ...


  • 簡單工廠模式概述
  1. 定義一個工廠類,他可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父親
  2. 在簡單工廠模式中用於被創建實例的方法通常為靜態(static)方法,因此簡單工廠模式又被成為靜態工廠方法(Static Factory Method)
  3. 需要什麼,只需要傳入一個正確的參數,就可以獲取所需要的對象,而無需知道其實現過程
  4. 例如,我開一家披薩店,當客戶需要某種披薩並且我這家店裡也能做的時候,我就會為其提供所需要的披薩(當然是要錢的哈哈),如果其所需的我這沒有,則是另外的情況,後面會談。這時候,我這家 披薩店就可以看做工廠(Factory),而生產出來的披薩被成為產品(Product),披薩的名稱則被稱為參數,工廠可以根據參數的不同返回不同的產品,這就是簡單工廠模式
  • 簡單工廠模式的結構與實現
  •  結構
  1. Factory(工廠):核心部分,負責實現創建所有產品的內部邏輯,工廠類可以被外界直接調用,創建所需對象
  2. Product(抽象類產品):工廠類所創建的所有對象的父類,封裝了產品對象的公共方法,所有的具體產品為其子類對象
  3. ConcreteProduct(具體產品):簡單工廠模式的創建目標,所有被創建的對象都是某個具體類的實例。它要實現抽象產品中聲明的抽象方法(有關抽象類)
  • 實現
     1 abstract class Product
     2 {
     3     public void MethName()
     4     {
     5         //公共方法的實現
     6     }
     7     public abstract void MethodDiff();
     8     //聲明抽象業務方法
     9 }
    10 class ConcreteProductA : Product
    11 {
    12     public override void MethodDiff()
    13     {
    14         //業務方法的實現
    15     }
    16 }
    17 
    18 class Factory
    19 {    
    20     public static Product GetProduct(string arg)
    21     {
    22         Product product =  null;
    23         if(arg.Equals("A")
    24         {
    25             product = new ConcreteProductA();
    26             //init
    27         }
    28         else if(arg.Equals("B"))
    29         {
    30             product = new ConcreteProductB();
    31             //init
    32         }
    33         else
    34         {
    35         ....//其他情況
    36         }
    37         return product;
    38     }
    39 }
    40 
    41 class Program
    42 {
    43     static void Main(string[] args)
    44     {
    45         Product product;
    46         product = Factory.GetProduct("A");//工廠類創建對象
    47         Product.MethName();
    48         product.MethodDiff();
    49     }
    50 }

     

  • 簡單工廠模式的簡化
  1. 為了簡化簡單工廠模式,將抽象產品類和工廠類合併,將靜態工廠方法移到抽象產品類中
  2. 客戶端可以調用產品父類的靜態工廠方法,根據不同的參數創建不同類型的產品子類對象。
  • 簡單工廠模式的優缺點和適用環境  

 

  • 簡單工廠模式的優點

    (1)工廠類包含必要的邏輯判斷,可以決定在什麼時候創建哪一個產品的實例。客戶端可以免除直接創建產品對象的職責
    (2)客戶端無需知道所創建具體產品的類名,只需知道參數即可
    (3)也可以引入配置文件,在不修改客戶端代碼的情況下更換和添加新的具體產品類。(這也是我在開始的披薩店裡遇到沒有的披薩的解決情況)

  • 簡單工廠模式的缺點

    (1)工廠類集中了所有產品的創建邏輯,職責過重,一旦異常,整個系統將受影響
    (2)使用簡單工廠模式會增加系統中類的個數(引入新的工廠類),增加系統的複雜度和理解難度
    (3)系統擴展困難,一旦增加新產品不得不修改工廠邏輯,在產品類型較多時,可能造成邏輯過於複雜
    (4)簡單工廠模式使用了static工廠方法,造成工廠角色無法形成基於繼承的等級結構。

  • 簡單工廠模式的適用環境

    (1)工廠類負責創建對的對象比較少,因為不會造成工廠方法中的業務邏輯過於複雜

    (2)客戶端只知道傳入工廠類的參數,對如何創建對象不關心

  • 簡單案例
  1. 題目:

    使用簡單工廠模式設計一個可以創建不同幾何圖形(Shape),如Circle,Rectangle,Triangle等繪圖工具類,每個幾何圖形均具有繪製Draw()和擦除Erase()兩個方法
    要求在繪製不支持的幾何圖形時,拋出一個UnsuppShapeException異常,繪製類圖並使用C#語言實現。

  2. UML:

  3.   1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 /*使用簡單工廠模式設計一個可以創建不同幾何圖形(Shape),如Circle,Rectangle,Triangle等繪圖工具類,每個幾何圖形均具有繪製Draw()和擦除Erase()兩個方法
      6  * 要求在繪製不支持的幾何圖形時,拋出一個UnsuppShapeException異常,繪製類圖並使用C#語言實現。
      7 */
      8 
      9 namespace SimpleShapeFactory
     10 {
     11     public interface InShape//圖形介面 抽象產品類
     12     {
     13         void Draw();
     14         void Erase();
     15     }
     16 
     17     public class Circle : InShape//圓形類,具體產品類
     18     {
     19         private static int count;   //生成圖形計數
     20         string radious;
     21         public Circle()//構造
     22         {
     23             Console.WriteLine("Create Circle");
     24             Console.WriteLine("Input the radious of Circle:");
     25             radious = Console.ReadLine();
     26         }
     27         public void Draw()//實現介面方法
     28         {
     29             int Radious = int.Parse(radious);
     30             Console.WriteLine("Display circle " + (++count) +" information:");
     31             Console.WriteLine("Circle "+ count+ " circumference:" + 2 * Radious * 3.14159);
     32             Console.WriteLine("Circle "+ count+" area:" + 3.14159 * Radious * Radious);
     33         }
     34         public void Erase()//實現介面方法
     35         {
     36             while (true)
     37             {
     38                 Console.WriteLine("Erase current shape(y/n)?");
     39                 string choose;
     40                 choose = Console.ReadLine();
     41                 if (choose.Equals("y") || choose.Equals("Y"))
     42                 {
     43                     Console.WriteLine("Erase Circle "+count +" successfully!");
     44                     count--;
     45                     break;
     46                 }
     47                 else if (choose.Equals("n") || choose.Equals("N"))
     48                 {
     49                     Console.WriteLine("Circle "+ count+" successfully saved!");
     50                     break;
     51                 }
     52                 else
     53                 {
     54                     Console.WriteLine("Input error, re-enter!");
     55                 }
     56             }   
     57         }
     58     }
     59 
     60     class Rectangle : InShape//矩形類,具體產品類
     61     {
     62         private static int count = 0;//生成圖形計數
     63         string length;
     64         string wideth;
     65         public Rectangle()//構造
     66         {
     67             Console.WriteLine("Create Rectangle");
     68             Console.WriteLine("Input the length and wideth of Rectangle:");
     69             length = Console.ReadLine();
     70             wideth = Console.ReadLine();
     71         }
     72         public void Draw()//實現介面方法
     73         {
     74             int Length = int.Parse(length);
     75             int Wideth = int.Parse(wideth);
     76             Console.WriteLine("Display rectangle " + (++count) + " information:");
     77             Console.WriteLine("Rectangle "+ count + "circumference:" + 2 * Length * Wideth);
     78             Console.WriteLine("Rectangle "+ count + "area:" + Length * Wideth);
     79            
     80         }
     81         public void Erase()//實現介面方法
     82          {
     83              while (true)
     84              {
     85                  Console.WriteLine("Erase current shape(y/n)?");
     86                  string choose;
     87                  choose = Console.ReadLine();
     88                  if (choose.Equals("y") || choose.Equals("Y"))
     89                  {
     90                      Console.WriteLine("Erase rectangle "+count+ "successfully!");
     91                      --count;
     92                      break;
     93                  }
     94                  else if (choose.Equals("n") || choose.Equals("N"))
     95                  {
     96                      Console.WriteLine("Rectangle "+ count+" successfully saved!");
     97                      break;
     98                  }
     99                  else
    100                  {
    101                      Console.WriteLine("Input error, re-enter!");
    102                  }
    103              }   
    104         }
    105     }
    106 
    107     class Triangle : InShape//三角形類,具體產品類
    108     {
    109         private static int count = 0;//生成圖形計數
    110         string lengtha;
    111         string lengthb;
    112         string lengthc;
    113         public Triangle()//構造
    114         {
    115             Console.WriteLine("Create Triangle");
    116             Console.WriteLine("Input the lengtha ,lengthb and lengthc of Triangle:");
    117             lengtha = Console.ReadLine();
    118             lengthb = Console.ReadLine();
    119             lengthc = Console.ReadLine();
    120 
    121         }
    122         public void Draw()//實現介面方法
    123         {
    124             int Lengtha = int.Parse(lengtha);
    125             int Lengthb = int.Parse(lengthb);
    126             int Lengthc = int.Parse(lengthc);
    127             if ((Lengtha + Lengthb > Lengthc) && (Lengtha + Lengthc > Lengthb) && (Lengthb + Lengthc > Lengtha))
    128             {
    129                 double S = (Lengtha + Lengthb + Lengthc) * 0.5;
    130                 double area = Math.Sqrt(S * (S - Lengtha) * (S - Lengthb) * (S - Lengthc));
    131                 Console.WriteLine("Display triangle "+ (++count)+" information:");
    132                 Console.WriteLine("Triangle " + count +" circumference:" + (Lengtha + Lengthb + Lengthc));
    133                 Console.WriteLine("Triangle "+ count +" area:" + area);
    134                 Erase();
    135             }
    136             else
    137             {
    138                 Console.WriteLine("Create triangle failed!");
    139             }
    140         }
    141         public void Erase()//實現介面方法
    142          {
    143              while (true)
    144              {
    145                  Console.WriteLine("Erase shape(y/n)?");
    146                  string choose;
    147                  choose = Console.ReadLine();
    148                  if (choose.Equals("y") || choose.Equals("Y"))
    149                  {
    150                      Console.WriteLine("Erase tirangle " +count +" successfully!");
    151                      --count;
    152                      break;
    153                  }
    154                  else if (choose.Equals("n") || choose.Equals("N"))
    155                  {
    156                      Console.WriteLine("Triangle "+ count +" successfully saved!");
    157                      break;
    158                  }
    159                  else
    160                  {
    161                      Console.WriteLine("Input error, re-enter!");
    162                  }
    163              }   
    164         }
    165     }
    166 
    167     class ShapeFactory//圖形工廠類,充當工廠類
    168     {
    169         public static  InShape Getshape(string type)//靜態工廠方法
    170         {
    171             InShape shape;
    172             shape = null;
    173             if (type.Equals("Circle"))
    174             {
    175                 shape = new Circle();
    176                 Console.WriteLine("Init set Circle");
    177                 shape.Draw();
    178                 shape.Erase();
    179             }
    180             else if(type.Equals("Rectangle"))
    181             {
    182                 shape = new Rectangle();
    183                 Console.WriteLine("Init set Rectangle");
    184                 shape.Draw();
    185                 shape.Erase();
    186             }
    187             else if (type.Equals("Triangle"))
    188             {
    189                 shape = new Triangle();
    190                 Console.WriteLine("Init set Triangle");
    191                 shape.Draw();
    192                 
    193             }
    194             else//異常 這裡我應該聲明調用異常處理類的,那樣會更好些
    195             {
    196                 Console.WriteLine("UnsupportShapeException!");
    197                 Console.WriteLine("Emotional reminders :Pay 1 million$ to Alipay:132****6151 can create every shape you want!!! ");
    198             }
    199             return shape;
    200         }
    201     }
    202 
    203     class Program//客戶端測試類
    204     {
    205         static void Main(string[] args)
    206         {
    207             while (true)
    208             {
    209                 InShape shape;
    210                 Console.WriteLine("Please input the shape you want to create");
    211                 string str = Console.ReadLine();
    212                 shape = ShapeFactory.Getshape(str);//通過靜態工廠方法創建產品
    213                 Console.ReadLine();
    214             }
    215         }
    216     }
    217 }
  4. 運行結果:
  5. 自我感覺寫的一般般,如有不對的地方,歡迎指正。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 返回一個數組,其內容是把原數組中對應元素的平均海拔轉換成其對應的軌道周期. 原數組中會包含格式化的對象內容,像這樣 {name: 'name', avgAlt: avgAlt}. 至於軌道周期怎麼求,戳這裡 on wikipedia (不想看英文的話可以自行搜索以軌道高度計算軌道周期的公式). 求得 ...
  • 首先列出所有的方法: join(), sort(), slice(), splice(), concat(), reverse(), push()+pop(), shift()+unshift(), forEach(), map(), some(), every(), filter(), reduc ...
  • 有如下代碼要實現換膚功能 這裡通過一個下拉框應用不用主題 首先我們把主題變數抽取出來 這裡包含三個主題red,gredd,blue,每個主題內的font-color變數對應不同的值, 然後我們寫一個主題化的mixin,包括一個themed函數 這段代碼的功能主要是對需要主體化的地方,對樣式根據不同主 ...
  • layui table動態表頭 改變表格頭部 重新載入表格 ...
  • 最近有個需求,是用vue做的頁面,其中嵌入了一個tinymce編輯器,編輯器設置了自動調整高度,也就是說編輯器中內容越多,高度就會自動撐高 我們需要再頁面最下方放一個保存按鈕,保存按鈕必須固定在屏幕下方,本來想用position:fixed這種簡單方法,但是業務比較特殊,不能這麼用,無奈只能用pos ...
  • 前言 鎖,顧名思義就是鎖住一些資源,當只有我們拿到鑰匙的時候,才能操作鎖住的資源。在我們的Java,資料庫,還有一些分散式的環境中,總是充斥著各種各樣的鎖讓人頭疼,例如“公平鎖”、“自旋鎖”、“讀寫鎖”、“分散式鎖”等等。 其實真實的情況是,鎖並沒有那麼多,很多概念只是從不同的功能特性,設計,以及鎖 ...
  • 一般情況下,在我們做訪問許可權管理的時候,會把用戶的正確登錄後的基本信息保存在Session中,以後用戶每次請求頁面或介面數據的時候,拿到 Session中存儲的用戶基本信息,查看比較他有沒有登錄和能否訪問當前頁面。 Session的原理,也就是在伺服器端生成一個SessionID對應了存儲的用戶數據 ...
  • 定義 提供了一個統一的介面,用來訪問子系統中一群介面 適用場景 詳解 外觀模式,主要理解外觀。通俗一點可以認為這個模式是將子系統封裝到一起,提供給應用的層面就提供一個方法。不直接由應用層直接訪問子系統。 下麵我們看看ibatis的源碼來具體理解外觀模式。 上述代碼其實是完成一個創建MetaObjec ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...