設計模式(九)之工廠模式

這是我參與8月更文挑戰的第9天,活動詳情查看:8月更文挑戰算法

工廠模式:定義一個用於建立對象的接口,讓子類來決定實例化哪個類,工廠方法使一個類的實例化延遲到子類。小程序

以前咱們看過簡單工廠類,使用的是計算器做爲例子。代碼以下:markdown

簡單工廠類Factory.cside

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  /// 簡單工廠類
namespace simpleFactory
{
    public class Factory
    {
        public static Ireckon CreateTreckon(string signStr)
        {
            Ireckon reckon = null;
   
            switch (signStr)
            {
                case "+":
                    reckon = new Plus();
                    break;
                case "-":
                    reckon = new Cut();
                    break;
                case "*":
                    reckon = new Ride();
                    break;
                default:
                    Console.WriteLine("暫不支持您輸入的運算符");
                    break;
            }
            return reckon;
        }
   
    }
}
複製代碼

下面咱們使用工廠模式來實現這個例子:oop

先構建一個工廠接口。post

而後加減乘除各建一個具體的工廠去實現這個接口。ui

定義一個算法接口,一個工廠接口,算法類繼承算法接口,算法工廠類繼承工廠接口(每一個算法類都須要有個算法工廠類來對應),將區分運算符號的邏輯部分放到客戶端。咱們再增長算法的時候,只須要增長對應的算法類。算法工廠類,及修改客戶端便可,這樣不違反開放封閉原則。spa

代碼以下:code

算法類:Ireckon.csorm

namespace simpleFactory
{
    public interface Ireckon
    {
        double getResult(double strNumberA, double strNumberB);
    }
}
複製代碼

工廠類:IForecty.cs

namespace simpleFactory
{
    public interface IForecty
    {
        /// <summary>
        /// 工廠類:返回計算方法
        /// </summary>
        Ireckon CreateReckon();
    }
}
複製代碼

減法類:Cut.cs

namespace simpleFactory
{
    public class Cut:Ireckon
    {
        public double result;
        public double getResult(double strNumberA, double strNumberB)
        {
            result = strNumberA - strNumberB;
            return result;
        }
    }
}
 
複製代碼

減法工廠類:CutFactory.cs

namespace simpleFactory
{
    public class CutFactory:IForecty
    {
        public Ireckon CreateReckon()
        {
            return new Cut();
        }
    }
}
複製代碼

加法類:Plus.cs

namespace simpleFactory
{
    public class Plus:Ireckon
    {
        public double result;
        public double getResult(double strNumberA, double strNumberB)
        {
            result = strNumberA + strNumberB;
            return result;
        }
    }
}
複製代碼

加法工廠類:PlusFactory.cs

namespace simpleFactory
{
    public class PlusFactory:IForecty
    {
        public Ireckon CreateReckon()
        {
            return new Plus();
        }
    }
}
 
複製代碼

乘法類:Ride.cs

namespace simpleFactory
{
    public class Ride:Ireckon
    {
        public double result;
        public double getResult(double strNumberA, double strNumberB)
        {
            result = strNumberA * strNumberB;
            return result;
        }
    }
}
複製代碼

乘法工廠類:RideFactory.cs

namespace simpleFactory
{
    public class RideFactory:IForecty
    {
        public Ireckon CreateReckon()
        {
            return new Ride();
        }
    }
}
複製代碼

客戶端:Program.cs

namespace simpleFactory
{
    class Program
    {
        static void Main(string[] args)
        {
            // 數字A
            double strNumberA;
            // 數字B
            double strNumberB;
            // 運算符
            string signStr;
            // 運算結果
            double result;
            try
            {
                Console.WriteLine("請輸入第一個數字");
                strNumberA = Convert.ToDouble(Console.ReadLine());
                Console.WriteLine("請輸入運算符號");
                signStr = Console.ReadLine();
                Console.WriteLine("請輸入第二個數字");
                strNumberB = Convert.ToDouble(Console.ReadLine());
                // 使用簡單工廠類返回實例化子類的對象(由於子類中都是重寫基類中的方法,指定類型的時候,直接聲明基類就能夠)
                //Ireckon reckon = Factory.CreateTreckon(signStr);
                //// 調用
                //result = reckon.getResult(strNumberA, strNumberB);
  
                // 工廠模式實現調用,如今咱們再增長算法的時候,只須要增長對應的算法類
                // 算法工廠類,及修改調用部分便可,這樣不違反開放封閉原則。
                IForecty reckon = null;
                switch (signStr)
                {
                    case "+":
                        reckon = new PlusFactory();
                        break;
                    case "-":
                        reckon = new CutFactory();
                        break;
                    case "*":
                        reckon = new RideFactory();
                        break;
                    default:
                        Console.WriteLine("暫不支持您輸入的運算符");
                        break;
                }
  
                result = reckon.CreateReckon().getResult(strNumberA, strNumberB);
                Console.WriteLine("運算結果爲:" + result);
            }
            catch (Exception qq )
            {
                // 輸出錯誤信息
                Console.WriteLine(qq.Message);
            }
            Console.ReadLine();
        }
    }
}
複製代碼

上邊的代碼就使用工廠模式實現了簡單工廠模式中的例子,代碼看起來比簡單工廠模式要複雜的多。可是,其更加合理。

簡單工廠模式的優勢:咱們能夠對建立的對象進行一些 「加工」 ,並且客戶端並不知道,由於工廠隱藏了這些細節。若是,沒有工廠的話,那咱們是否是就得本身在客戶端上寫這些代碼,這就比如原本能夠在工廠裏生產的東西,拿來本身手工製做,不只麻煩之後還很差維護。

可是缺點也很明顯:若是須要在方法裏寫不少與對象建立有關的業務代碼,並且須要的建立的對象還很多的話,咱們要在這個簡單工廠類裏編寫不少個方法,每一個方法裏都得寫不少相應的業務代碼,而每次增長子類或者刪除子類對象的建立都須要打開這簡單工廠類來進行修改。這會致使這個簡單工廠類很龐大臃腫、耦合性高,並且增長、刪除某個子類對象的建立都須要打開簡單工廠類來進行修改代碼也違反了開-閉原則。

工廠模式是對簡單工廠模式進一步的解耦,由於在工廠方法模式中是一個子類對應一個工廠類,而這些工廠類都實現於一個抽象接口。這至關因而把本來會由於業務代碼而龐大的簡單工廠類,拆分紅了一個個的工廠類,這樣代碼就不會都耦合在同一個類裏了。

工廠模式中,要增長產品類時也要相應地增長工廠類,客戶端的代碼也增長了很多。工廠方法把簡單工廠的內部邏輯判斷轉移到了客戶端代碼來進行。

你想要加功能,原本是改工廠類的,而如今是修改客戶端。並且各個不一樣功能的實例對象的建立代碼,也沒有耦合在同一個工廠類裏,這也是工廠方法模式對簡單工廠模式解耦的一個體現。工廠方法模式克服了簡單工廠會違背開-閉原則的缺點,又保持了封裝對象建立過程的優勢。

但工廠方法模式的缺點是每增長一個產品類,就須要增長一個對應的工廠類,增長了額外的開發量。

有好的建議,請在下方輸入你的評論。 歡迎訪問我的博客 guanchao.site

歡迎訪問小程序:

在這裏插入圖片描述

相關文章
相關標籤/搜索