前文引入 Factory 類別解決客戶端直接 new 具體類別的問題,但移植時仍需修改 Factory 源碼(將 ChineseTax 改為 AmericanTax),工作量未減少且違反 OCP。
新增 AbstractFactory 抽象基類,提供靜態 GetInstance() 根據組態檔 factoryName 動態決定實例化哪個具體工廠:
public abstract class AbstractFactory
{
public static AbstractFactory GetInstance()
{
string factoryName = Constant.STR_FACTORYNAME; // 從 App.config/Web.config 讀取
AbstractFactory instance = null;
if (factoryName == "ChineseFactory")
instance = new ChineseFactory();
else if (factoryName == "AmericanFactory")
instance = new AmericanFactory();
return instance;
}
public abstract Tax CreateTax();
public abstract Bonus CreateBonus();
}
public class ChineseFactory : AbstractFactory
{
public override Tax CreateTax() => new ChineseTax();
public override Bonus CreateBonus() => new ChineseBonus();
}
public class AmericanFactory : AbstractFactory
{
public override Tax CreateTax() => new AmericanTax();
public override Bonus CreateBonus() => new AmericanBonus();
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="factoryName" value="AmericanFactory" />
</appSettings>
</configuration>
Calculator 完全不變,持續依賴抽象介面若新增日本廠商,仍需修改 AbstractFactory.GetInstance() 加入 else if。下一集將引入反射機制徹底解決此問題。