簡單工廠模式(2)

来源:http://www.cnblogs.com/xiaomowang/archive/2016/12/30/6232893.html
-Advertisement-
Play Games

一、舉例 用控制台程式做一個非常簡單的電腦,實現加減乘除運算即可,那麼,大家自然而然的會寫出如下代碼 二、演繹 1、第一步演繹 ①由於在判斷運算符時,用的是if語句,這意味著每個條件都需要做判斷,相當於電腦做了三次無用功。 ②沒有輸入校驗,例如,除數不能為零的問題等等 就上述兩個問題,做如下修改 ...


一、舉例

用控制台程式做一個非常簡單的電腦,實現加減乘除運算即可,那麼,大家自然而然的會寫出如下代碼

 1 static void Main(string[] args)
 2         {
 3             Console.WriteLine("請輸入數字A:");
 4             string strNumA = Console.ReadLine();
 5             Console.WriteLine("請選擇運算符號(+、-、*、、)");
 6             string strOperate = Console.ReadLine();
 7             Console.WriteLine("請輸入數字C:");
 8             string strNumB = Console.ReadLine();
 9             string strResult = "";
10             if (strOperate == "+")
11             {
12                 strResult = Convert.ToString(Convert.ToDouble(strNumA) + Convert.ToDouble(strNumB));
13             }
14             if (strOperate == "-")
15             {
16                 strResult = Convert.ToString(Convert.ToDouble(strNumA) - Convert.ToDouble(strNumB));
17             }
18             if (strOperate == "*")
19             {
20                 strResult = Convert.ToString(Convert.ToDouble(strNumA) * Convert.ToDouble(strNumB));
21             }
22             if (strOperate == "/")
23             {
24                 strResult = Convert.ToString(Convert.ToDouble(strNumA) / Convert.ToDouble(strNumB));
25             }
26             Console.WriteLine($"結果是:{strResult}");
27             Console.ReadKey();
28         }

二、演繹

1、第一步演繹

①由於在判斷運算符時,用的是if語句,這意味著每個條件都需要做判斷,相當於電腦做了三次無用功。

②沒有輸入校驗,例如,除數不能為零的問題等等

就上述兩個問題,做如下修改:(輸入校驗此處先只做除數為零的校驗)

 1 static void Main(string[] args)
 2         {
 3             Console.WriteLine("請輸入數字A:");
 4             string strNumA = Console.ReadLine();
 5             Console.WriteLine("請選擇運算符號(+、-、*、、)");
 6             string strOperate = Console.ReadLine();
 7             Console.WriteLine("請輸入數字C:");
 8             string strNumB = Console.ReadLine();
 9             string strResult = "";
10             switch (strOperate)
11             {
12                 case "+":
13                     strResult = Convert.ToString(Convert.ToDouble(strNumA) + Convert.ToDouble(strNumB));
14                     break;
15                 case "-":
16                     strResult = Convert.ToString(Convert.ToDouble(strNumA) - Convert.ToDouble(strNumB));
17                     break;
18                 case "*":
19                     strResult = Convert.ToString(Convert.ToDouble(strNumA) * Convert.ToDouble(strNumB));
20                     break;
21                 case "/":
22                     if (strNumB != "0")
23                     {
24                         strResult = Convert.ToString(Convert.ToDouble(strNumA) / Convert.ToDouble(strNumB));
25                     }
26                     else
27                     {
28                         strResult = "除數不能為0";
29                     }
30                     break;
31             }
32             Console.WriteLine($"結果是:{strResult}");
33             Console.ReadKey();
34         }

2、第二步演繹

①上述寫的簡單的計算器僅僅體現了面向過程的編程,沒有體現面向對象的編程

②上述代碼使用控制台應用實現的,假如有一天我需要用Winform、Web 等實現一模一樣的需求,那麼,上述代碼則需要重新編寫,好可怕。

就上述問題,做如下修改:

將業務邏輯與界面分離

Operation運算類

 1 public class Operation
 2     {
 3         public static double GetResult(double numA, double numB, string strOperate)
 4         {
 5             double result = 0d;
 6             switch (strOperate)
 7             {
 8                 case "+":
 9                     result = numA + numB;
10                     break;
11                 case "-":
12                     result = numA - numB;
13                     break;
14                 case "*":
15                     result = numA * numB;
16                     break;
17                 case "/":
18                     result = numA / numB;
19                     break;
20             }
21             return result;
22         }
23     }

客戶端

 1 static void Main(string[] args)
 2         {
 3             try
 4             {
 5                 Console.WriteLine("請輸入數字A:");
 6                 string strNumA = Console.ReadLine();
 7                 Console.WriteLine("請選擇運算符號(+、-、*、、)");
 8                 string strOperate = Console.ReadLine();
 9                 Console.WriteLine("請輸入數字C:");
10                 string strNumB = Console.ReadLine();
11                 string strResult = "";
12                 strResult = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumA), Convert.ToDouble(strNumB), strOperate));
13                 Console.WriteLine($"結果是:{strResult}");
14                 Console.ReadKey();
15             }
16             catch (Exception ex)
17             {
18                 Console.WriteLine($"您的輸入有錯:{ex.Message}");
19             }
20         }

這樣的話,無論是控制台,還是Winform以及其他應用,只需要調用 Operation 這個類即可了。實現了業務邏輯與界面的分離。這裡,也用到了面向對象編程的三大特性之一的封裝。

3、第三步演繹

①如果我想增加一種計算方式,例如開根號(sqrt)運算怎麼辦,只能是修改Operation類,在switch中增加一種情況。

②針對①問題做修改的話,那麼另一個問題就來了,我修改Oeration類的時候,之前寫好的加減乘除功能全在其中,如果我不小心,或者有意搞破壞,將本來運行的好好的加減乘除功能改掉,怎麼辦?(此例中僅僅是計算器,如果換做是成熟的產品,或者涉及到資金運算等等的代碼,運行的好好的,不可能會讓程式員在其中胡作非為的)

針對上述問題,作如下修改:

我可以將加減乘除各種運算分別封裝到不同的類裡面,這樣,就能解決②的問題,每增加一種運算,我就增加一個類,這樣①問題也解決了。

首先,將不同的運算抽象出一個共同的類,即父類

 1 public class Operation
 2     {
 3         private double _numberA = 0;
 4         private double _numberB = 0;
 5         public double NumberA
 6         {
 7             get
 8             {
 9                 return _numberA;
10             }
11 
12             set
13             {
14                 _numberA = value;
15             }
16         }
17         public double NumberB
18         {
19             get
20             {
21                 return _numberB;
22             }
23 
24             set
25             {
26                 _numberB = value;
27             }
28         }
29         public virtual double GetResult()
30         {
31             double result = 0;
32             return result;
33         }
34     }

其次,讓不同的運算繼承這個父類,然後根據不同的運算,重寫父類中的GetResult方法

 1 //加法類
 2     public class OperationAdd:Operation
 3     {
 4         public override double GetResult()
 5         {
 6             double result = 0;
 7             result = NumberA + NumberB;
 8             return result;
 9         }
10     }
11     //減法類
12     public class OperationSub : Operation
13     {
14         public override double GetResult()
15         {
16             double result = 0;
17             result = NumberA = NumberB;
18             return result;
19         }
20     }
21     //乘法類
22     public class OperationMul : Operation
23     {
24         public override double GetResult()
25         {
26             double result = 0;
27             result = NumberA * NumberB;
28             return result;
29         }
30     }
31     //除法類
32     public class OperationDiv : Operation
33     {
34         public override double GetResult()
35         {
36             double result = 0;
37             if (NumberB==0)
38             {
39                 throw new Exception("除數不能為0");
40             }
41             result = NumberA / NumberB;
42             return result;
43         }
44     }

這樣,上述的兩個問題就迎刃而解了。

4、第四步演繹

到了簡單工廠最核心的地方了。

 這麼多的類,客戶端該如何用這些類呢,換句話說,客戶端如何實例化這些類呢?那麼,就需要一個核心的東西——工廠,這個工廠負責給客戶端提供他想要的類的實例。我想要實例化什麼類,告訴工廠就可以了。

代碼如下:

 1 public class OperationFactory
 2     {
 3         public static Operation createOperate(string operate)
 4         {
 5             Operation oper = null;
 6             switch (operate)
 7             {
 8                 case "+":
 9                     oper = new OperationAdd();
10                     break;
11                 case "-":
12                     oper = new OperationSub();
13                     break;
14                 case "*":
15                     oper = new OperationMul();
16                     break;
17                 case "/":
18                     oper = new OperationDiv();
19                     break;
20             }
21             return oper;
22         }
23     }

註意一點,這個工廠中的方法,返回的是加減乘除這些類的父類。

好了,製造類實例的工廠有了,那麼,客戶端只需要告訴工廠,給我造一個什麼類的實例,然後用這個實例就可以了。

客戶端代碼如下

 1 static void Main(string[] args)
 2         {
 3             Operation oper;
 4             //告訴工廠,給我一個加法類的實例
 5             oper = OperationFactory.createOperate("+");
 6             oper.NumberA = 1;
 7             oper.NumberB = 2;
 8             double result = oper.GetResult();
 9             Console.WriteLine(result);
10             Console.ReadKey();
11         }

 經過上述一系列的演繹,也就形成了簡單工廠模式。

三、總結

簡單工廠模式,即 通過一個‘工廠類’,用於子類返回父類對象。


工廠模式結束,下一次,將講解策略模式 


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

-Advertisement-
Play Games
更多相關文章
  • 一、 前言 本章將學習:當執行程式時,其main函數是如何被調用的,命令行參數是如何傳送給執行程式的,典型的存儲器佈局是什麼樣式,如何分配另外的存儲空間,進程如何使用環境變數,進程終止的不同方式等。另外還將說明longjmp和setjmp函數以及它們與棧的交互作用。 二、 main函數 C程式的入口 ...
  • 本文原創,轉載請註明出處! 參考文章: 《“JUC鎖”03之 公平鎖(一)》 《“JUC鎖”03之 公平鎖(二)》 AbstractOwnableSynchronizer,用於供子類存取獨占鎖的所屬線程。 #getExclusiveOwnerThread()/#setExclusiveOwnerTh ...
  • var n=0; for(var i=2;i<=1000;i++){ var zhishu=true; for(var j=2;j<i;j++){ if(i%j==0){ zhishu=false; break; } } if(zhishu==true){ document.write(i+"<br ...
  • 前言 前一階段對MVC模式及其衍生模式做了一番比較深入的研究和實踐,這篇文章也算是一個階段性的回顧和總結。 經典MVC模式 經典MVC模式中,M是指業務模型,V是指用戶界面,C則是控制器,使用MVC的目的是將M和V的實現代碼分離,從而使同一個程式可以使用不同的表現形式。其中,View的定義比較清晰, ...
  • 這是一個商場收費軟體的一個案例,如下: 用Winform做一個非常簡單的商場計算價格的工具,一般我們寫的代碼和界面如下: 界面: 代碼: 執行效果: 二、演繹 1、第一步演繹 ①商場搞活動,所有商品八折出售。 有的小伙伴直接將原來計算總價的代碼改成下麵的代碼: 額,如果商場不打折了,還需要將這段代碼 ...
  • C#使用GET、POST請求獲取結果,這裡以一個簡單的用戶登陸為例。 1、 使用GET請求獲取結果 1.1 創建LoginHandler.aspx處理頁面 [csharp] view plain copy protected void Page_Load(object sender, EventAr ...
  • ------------------------------------------------------------------------------------------------... ...
  • 在學習springAOP時,出現如下異常: 無法訪問org.springframework.core.NestedRuntimeException 找不到org.springframework.core.NestedRuntimeException的類文件 原因是:缺少spring-core.jar ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...