抽象工廠模式在 ASP.NET MVC 三層架構中的落地實踐:介面隔離、工廠封裝、配置驅動、依賴倒置,附完整專案結構與代碼。
AXCModel (實體) ← IAXCDAL (DAL介面) ← AXCDAL (DAL實作) ↑ ↑ IAXCBLL (BLL介面) ← AXCBLL (BLL實作) ↑ ↑ AXCFactoryDAL (DAL工廠) ← AXCFactoryBLL (BLL工廠) ↑ AXCWeb (表現層) → 依賴介面與工廠
**核心原則**:高層模組 (BLL/Web) 不依賴低層實作 (DAL),雙方依賴抽象 (介面);工廠負責具體類別實例化。
namespace AXCModel
{
public class PeopleModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public bool Sex { get; set; }
}
}
// IAXCDAL
public interface IPeopleDAL
{
List<PeopleModel> GetPeopleList();
}
// AXCDAL
public class PeopleDAL : IPeopleDAL
{
public List<PeopleModel> GetPeopleList()
{
// 模擬資料,實際連接資料庫
return new List<PeopleModel>
{
new PeopleModel { Id=1, Name="艾新草", Age=25, Sex=false },
new PeopleModel { Id=2, Name="艾新草1", Age=23, Sex=true },
new PeopleModel { Id=3, Name="艾新草2", Age=22, Sex=false }
};
}
}
// AXCFactoryDAL
public abstract class AbsFactoryDAL
{
public static AbsFactoryDAL GetFactory()
{
string type = ConfigurationManager.AppSettings["dalType"]; // "dal"
switch (type)
{
case "dal": return new DALFactory();
default: throw new NotSupportedException($"Unknown DAL type: {type}");
}
}
public abstract IPeopleDAL GetPeople();
}
public class DALFactory : AbsFactoryDAL
{
public override IPeopleDAL GetPeople() => new PeopleDAL();
}
// IAXCBLL
public interface IPeopleBLL
{
List<PeopleModel> GetPeopleList();
}
// AXCBLL
public class PeopleBLL : IPeopleBLL
{
private readonly AbsFactoryDAL _dalFactory = AbsFactoryDAL.GetFactory();
public List<PeopleModel> GetPeopleList()
{
IPeopleDAL dal = _dalFactory.GetPeople();
return dal.GetPeopleList(); // 可加入業務邏輯、快取、驗證
}
}
// AXCFactory
public abstract class AbsFactoryBLL
{
public static AbsFactoryBLL GetFactory()
{
string type = ConfigurationManager.AppSettings["bllType"]; // "bll"
switch (type)
{
case "bll": return new BLLFactory();
default: throw new NotSupportedException($"Unknown BLL type: {type}");
}
}
public abstract IPeopleBLL GetPeople();
}
public class BLLFactory : AbsFactoryBLL
{
public override IPeopleBLL GetPeople() => new PeopleBLL();
}
<appSettings>
<add key="dalType" value="dal" />
<add key="bllType" value="bll" />
</appSettings>
public ActionResult Index()
{
AbsFactoryBLL bllFactory = AbsFactoryBLL.GetFactory();
IPeopleBLL peopleBll = bllFactory.GetPeople();
List<PeopleModel> list = peopleBll.GetPeopleList();
return View(list);
}
抽象工廠是「手動 DI」過渡形態。現代 ASP.NET Core 內建 DI 容器可直接註冊:
// Program.cs / Startup.cs
services.AddScoped<IPeopleDAL, PeopleDAL>();
services.AddScoped<IPeopleBLL, PeopleBLL>();
// Controller 建構函數注入
public class HomeController : Controller
{
private readonly IPeopleBLL _peopleBll;
public HomeController(IPeopleBLL peopleBll) => _peopleBll = peopleBll;
public IActionResult Index() => View(_peopleBll.GetPeopleList());
}
| 維度 | 抽象工廠 | 依賴注入容器 |
|---|---|---|
| 控制反轉 | 手動 (工廠類) | 框架自動 (容器) |
| 生命週期管理 | 自行實作 (Singleton/Transient) | 內建支援 |
| 攔截/AOP | 困難 | 容易 (裝飾器/動態代理) |
| 測試替身 | 需修改工廠邏輯 | 輕鬆 Mock 介面 |
| 遷移成本 | 低 (既有專案) | 中 (需重構建構函數) |
抽象工廠是理解「依賴倒置」的最佳切入點。掌握其精髓——**介面隔離變化、工廠封裝創建**——再遷移至 DI 容器將水到渠成。