抽象工廠模式是我們項目開發中非常常見的一種模式,屬於創建型模式。那么什么是模式呢?世上本沒有所謂的模式,用的人多了也就有了。我們經常看到的各種框架,其實就是各種設計模式的一個集合。
模式就是前人對解決某一類問題的經驗方法的總結,打個比方,取水,你可以自己鑽井,也可以通過安裝自來水。那使用什么樣的方式來達到取水的目的,那就得根據實際情況來用了,比如你住在偏遠的大山里,那安裝自來水肯定就不如鑽井或者直接從山泉里面引流過來了。如果住在城市里,自己鑽井,肯定又不太現實了,一則影響城市規划,二來城市里的地那么貴((*^__^*) 嘻嘻)。
抽象工廠:每一個模式都是針對一定問題的解決方案。抽象工廠模式與工廠方法模式的最大區別就在於,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式則需要面對多個產品等級結構。當每個抽象產品都有多於一個的具體子類的時候,工廠角色怎么知道實例化哪一個子類呢?比如每個抽象產品都有兩個具體產品。抽象工廠模式提供兩個具體工廠角色,分別對應於這兩個具體產品角色,每一個具體工廠角色只負責某一個產品角色的實例化。每一個具體工廠類只負責創建抽象產品的某一個具體子類的實例。
我這里主要給大家演示下下工作中比較low的實現方式,雖然很low,但是很多項目就是這么弄的,只是有一些項目用反射來代替具體實例化某個類對象了。
在典型的三層架構中,我們經常會看到這樣的項目結構,為了演示新建了兩個實體類,Msg和Users


先看下數據訪問層的抽象工廠和工廠
AbsFactoryDAL.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DALFactory { /// <summary> /// 數據 抽象工廠類 /// </summary> public abstract class AbsFactoryDAL { /// <summary> /// 根據配置文件 獲取 實體數據工廠 對象 /// </summary> /// <returns></returns> public static AbsFactoryDAL GetFatory() { string strType = System.Configuration.ConfigurationManager.AppSettings["dalType"].ToString(); AbsFactoryDAL dalFactory = null; switch (strType) { case "dal": dalFactory = new DALFactory(); break; case "dalA": dalFactory = null; break; } return dalFactory; } public abstract IDAL.IUsers GetUser(); public abstract IDAL.IMsg GetMsg(); } }
DALFactory.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DALFactory { /// <summary> /// 數據工廠,只負責生成 數據層 DAL 項目里的 數據操作類 /// </summary> public class DALFactory:AbsFactoryDAL { public override IDAL.IUsers GetUser() { return new DAL.Users(); } public override IDAL.IMsg GetMsg() { return new DAL.Msg(); } } }
接下來是業務邏輯層的抽象工廠和具體工廠

AbsFactoryBLL.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BLLFactory { /// <summary> /// 業務抽象工廠類 /// </summary> public abstract class AbsFactoryBLL { /// <summary> /// 根據配置文件 獲取 實體業務工廠 對象 /// </summary> /// <returns></returns> public static AbsFactoryBLL GetFatory() { string strType = System.Configuration.ConfigurationManager.AppSettings["bllType"].ToString(); AbsFactoryBLL bllFactory = null; switch (strType) { case "bll": bllFactory = new BLLFactory(); break; case "blla": bllFactory = new BLLFactoryA(); break; } return bllFactory; } public abstract IBLL.IUsers GetUser(); public abstract IBLL.IMsg GetMsg(); } }
BLLFactory.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BLLFactory { /// <summary> /// 業務工廠,只負責生成 業務層 BLL 項目里的 業務類 /// </summary> public class BLLFactory:AbsFactoryBLL { public override IBLL.IUsers GetUser() { return new BLL.Users(); } public override IBLL.IMsg GetMsg() { return new BLL.Msg(); } } }
BLLFactoryA.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BLLFactory { /// <summary> /// 負責 生產 BLLA 項目里的業務類對象 /// </summary> public class BLLFactoryA:AbsFactoryBLL { public override IBLL.IUsers GetUser() { return new BLLA.Users(); } public override IBLL.IMsg GetMsg() { return new BLLA.Msg(); } } }
web.config
<?xml version="1.0" encoding="utf-8"?> <!-- 有關如何配置 ASP.NET 應用程序的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <appSettings> <add key="bllType" value="bll"/> <add key="dalType" value="dal"/> </appSettings> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> </configuration>
以上很low的寫法只是說明學習的一個過程。
其實完全可以用倉儲模式和IOC來替代:
業務邏輯層:
using ProjectBase.Data;
using ProjectBase.Utils.Entities;
public class InChina : DomainObject<InChina, int, IInChinaRepository>
{
}
數據層:
public class InChinaRepository:ProjectBase.Data.AbstractNHibernateDao<InChina,int>,IInChinaRepository { }
public interface IInChinaRepository:IDao<InChina,int>
{
}
然后配置文件中使用IOC注入
<unity> <containers> <container> <types> <type type="xxx.Core.xx,xxx.Core" mapTo="xxx.Interface.xx,xxx.Interface" /> </types> </container> </containers> </unity>
