【C# 設計模式-簡單工廠模式 】
網上有很多關於類似工廠模式的部落格,大都說明的很詳細,這裡我結合在專案中的體會簡單說一下!
介紹:簡單工廠模式不能說是一個設計模式,說它是一種程式設計習慣可能更恰當些。因為它至少不是Gof23種設計模式之一。但它在實際的程式設計中經常被用到,而且思想也非常簡單,可以說是一個工廠方法模式的一個引導。
簡單工廠模式結構圖:
角色:
工廠(Creator)角色
簡單工廠模式的核心,它負責實現建立所有例項的內部邏輯。工廠類的建立產品類的方法可以被外界直接呼叫,建立所需的產品物件。
抽象產品(Product)角色
簡單工廠模式所建立的所有物件的父類,它負責描述所有例項所共有的公共介面。
具體產品(Concrete Product)角色
是簡單工廠模式的建立目標,所有建立的物件都是充當這個角色的某個具體類的例項。
引入實際情況:
如果有一個住戶管理系統,裡面的住戶型別是可變的,每一種租戶型別的租金計算公式都存在差異
例如:A型別的住戶租金額=天數*單價+績效*0.005
B型別的住戶租金額=月份*(每月價格+performance*0.001)
分析:
1. 商店存在共有的計算方法,這是實體商店的行為,然而他們的行為的方式不一樣,所有我們抽象商店類,程式碼>>>
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SimpleFactory.App.IFactroy { public interface Ishop { double Getrent(int days, double dayprice, double performance); } }
2.在抽象了商店之後,我們要對建立具體產品類,這裡就是具體的型別商店,裡面實現該商店的行為方法。
建立A型別的商店
建立B型別的商店using SimpleFactory.App.IFactroy; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SimpleFactory.App.product { //A型別的商店的建立 public class Ashop:Ishop { /// <summary> /// /// A型別商店租金額,天數*單價+績效*0.005 /// </summary> /// <param name="days">天數</param> /// <param name="dayprice">每天單價</param> /// <param name="performance">日平均績效</param> /// <returns></returns> public double Getrent(int days, double dayprice, double performance) { Console.WriteLine("A商店的租金演算法"); return days * dayprice + performance * 0.01; } } }
using SimpleFactory.App.IFactroy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SimpleFactory.App.product
{
/// <summary>
/// B型別的商店的建立
/// </summary>
public class Bshop:Ishop
{
/// <summary>
/// B型別商店的租金=月份*(每月價格+performance*0.001)
/// </summary>
/// <param name="month">月數</param>
/// <param name="monthprice">月單價</param>
/// <param name="performance">月平均績效</param>
/// <returns></returns>
public double Getrent(int month, double monthprice, double performance)
{
Console.WriteLine("B商店的租金演算法");
return month * (monthprice + performance * 0.001);
}
}
}
3. 在建立號型別商店並實現方法後,思考在什麼情況下如何建立那種物件,於是簡單工廠模式中最核心的部分:工廠類出來了
using SimpleFactory.App.IFactroy;
using SimpleFactory.App.product;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SimpleFactory.App.factoryMethod
{
public class factorymethod
{
public Ishop CreateShow(string show)
{
switch (show.Trim().ToLower())
{
case"ashop":
return new Ashop();
case "bshop":
return new Ashop();
default:
throw new Exception("該商店不存在");
}
}
}
}
4. 然後就根據當前的商店型別進行判斷,該型別的商店應該進行哪一種演算法:
using SimpleFactory.App.factoryMethod;
using SimpleFactory.App.IFactroy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SimpleFactory.App
{
class Program
{
static void Main(string[] args)
{
Ishop As;
factorymethod afm = new factorymethod();
As = afm.CreateShow("ashop"); //a 型別的某商店
double total = As.Getrent(30, 300, 2000); //30 天/100元 日平均績效為2000
Console.WriteLine("該A型別商店的租金為:" + total);
Console.WriteLine("=============");
Ishop Bs;
factorymethod bfm = new factorymethod();
Bs = bfm.CreateShow("bshop"); //b 型別的某商店
total = Bs.Getrent(3, 3000, 60000); //3 月/4000元 月平均績效為60000
Console.WriteLine("該B型別商店的租金為:" + total);
Console.ReadKey();
}
}
}
這樣就通過簡單工廠模式實現類對於當前商店的店鋪租金應該進行那種演算法的計算。
到這裡我們實現了客戶要求的兩種型別商店的演算法的需求,但是作為一種好的設計架構,還應該考慮到後面的需求變革,如果客戶現在又
增加了C型別商店和D型別商店,它們的演算法要求又不一樣,這個時候我們就需要進行C,D型別商店的建立,並繼承Ishop介面,實現裡面的方法,
同時還得繼續修改工廠類在switc中增加case進行捕捉建立相應的商店物件,一旦出現這樣的情況,是不利於程式的擴充套件性和專案後期的維護性的。
優點:
- 簡單工廠模式能夠根據外界給定的資訊,決定究竟應該建立哪個具體類的物件。通過它,外界可以從直接建立具體產品對 象的尷尬局面中擺脫出來。
- 外界與具體類隔離開來,偶合性低。
- 明確區分了各自的職責和權力,有利於整個軟體體系結構的優化。
缺點:
- 工廠類集中了所有例項的建立邏輯,容易違反GRASPR的高內聚的責任分配原則
- 雖然簡單工廠模式能夠適應一定的變化,但是它所能解決的問題是遠遠有限的。它所能建立的類只能是事先教考慮到的,如果需要新增新的類,則就需要改變工廠類了。
出現的上訴情況,應該如何解決,值得思考,將在下一個工廠方法模式中得到很好的解決。