抽象工廠模式屬於創建型模式,提供「一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類」。它將具體工廠的實例化延遲到子類,客戶端只需面對抽象介面,即可創建一整族相關產品。
AbstractMessageFactory)。SqlMessageFactory, XmlMessageFactory)。AbstractMessage, AbstractMessageModel)。SqlMessage, SqlMessageModel 等)。Message 類別)。情境:系統需支援 SQL Server 與 XML 兩種資料存取方式,兩者各自包含 Message (操作類) 與 MessageModel (資料實體) 兩個相關物件,必須成對使用。
// 抽象資料實體
public abstract class AbstractMessageModel
{
public string Message { get; set; }
public DateTime PublishTime { get; set; }
public abstract string UserId { get; set; } // 強制子類實作,可加入加密/解密邏輯
protected AbstractMessageModel() { }
protected AbstractMessageModel(string msg, DateTime pt) { Message = msg; PublishTime = pt; }
}
// 抽象操作類
public abstract class AbstractMessage
{
public abstract string Insert(AbstractMessageModel model);
}
public class SqlMessageModel : AbstractMessageModel
{
private string _userId;
public override string UserId { get => _userId; set => _userId = value; }
public SqlMessageModel() : base() { }
public SqlMessageModel(string userId, string msg, DateTime pt) : base(msg, pt) { _userId = userId; }
}
public class SqlMessage : AbstractMessage
{
public override string Insert(AbstractMessageModel amm)
=> $"Sql方式插入Message。帳號:{amm.UserId};內容:{amm.Message};時間:{amm.PublishTime}";
}
public class XmlMessageModel : AbstractMessageModel
{
private string _userId;
public override string UserId
{
get => _userId; // 解密後的值
set => _userId = value; // 加密後的值
}
public XmlMessageModel() : base() { }
public XmlMessageModel(string userId, string msg, DateTime pt) : base(msg, pt) { _userId = userId; }
}
public class XmlMessage : AbstractMessage
{
public override string Insert(AbstractMessageModel amm)
=> $"Xml方式插入Message。帳號:{amm.UserId};內容:{amm.Message};時間:{amm.PublishTime}";
}
public abstract class AbstractMessageFactory
{
public abstract AbstractMessageModel CreateMessageModel();
public abstract AbstractMessage CreateMessage();
}
public class SqlMessageFactory : AbstractMessageFactory
{
public override AbstractMessageModel CreateMessageModel() => new SqlMessageModel();
public override AbstractMessage CreateMessage() => new SqlMessage();
}
public class XmlMessageFactory : AbstractMessageFactory
{
public override AbstractMessageModel CreateMessageModel() => new XmlMessageModel();
public override AbstractMessage CreateMessage() => new XmlMessage();
}
public class Message
{
private readonly AbstractMessage _insertMessage;
private readonly AbstractMessageModel _messageModel;
public Message(AbstractMessageFactory factory)
{
_insertMessage = factory.CreateMessage();
_messageModel = factory.CreateMessageModel();
}
public string Insert(string userId, string msg, DateTime pt)
{
_messageModel.UserId = userId;
_messageModel.Message = msg;
_messageModel.PublishTime = pt;
return _insertMessage.Insert(_messageModel);
}
}
public partial class AbstractFactory : Page
{
protected void Page_Load(object sender, EventArgs e)
{
// 使用 SQL 族群
AbstractMessageFactory factory = new SqlMessageFactory();
var msg = new Message(factory);
Response.Write(msg.Insert("admin", "Sql方式", DateTime.Now) + "<br />");
// 切換至 XML 族群
factory = new XmlMessageFactory();
msg = new Message(factory);
Response.Write(msg.Insert("user", "Xml方式", DateTime.Now));
}
}
Sql方式插入Message。帳號:admin;內容:Sql方式;時間:2007-5-3 22:04:56
Xml方式插入Message。帳號:user;內容:Xml方式;時間:2007-5-3 22:04:56
| 特性 | 工廠方法 | 抽象工廠 |
|---|---|---|
| 創建目標 | 單一產品 | 產品族 (多個相關產品) |
| 擴充方式 | 繼承並覆寫工廠方法 | 實作新的具體工廠介面 |
| 客戶端依賴 | 抽象產品 + 抽象工廠 | 抽象產品族 + 抽象工廠 |