定義: 抽象工廠模式:提供一個創建一系列相關或相互依賴對象的介面,而無需指定他們的具體類。抽象工廠模式主要解決涉及到多個產品系列的問題。 代碼實例: 先回顧上一篇中工廠方法模式的例子,該示例以 BloggsCal 和 MegaCal 兩種格式管理編碼。如果增加更多的編碼格式,這種類結構會橫向增長,但 ...
定義:
抽象工廠模式:提供一個創建一系列相關或相互依賴對象的介面,而無需指定他們的具體類。抽象工廠模式主要解決涉及到多個產品系列的問題。
代碼實例:
先回顧上一篇中工廠方法模式的例子,該示例以 BloggsCal 和 MegaCal 兩種格式管理編碼。如果增加更多的編碼格式,這種類結構會橫向增長,但如何為不同類型的 PIM 對象加入編碼器,使類結構“縱向”增長呢?
這裡將會用到三個相似的類層次結構,分別是預約(Appt)、待辦事項(Ttd)以及聯繫人(Contact)。
1、創建Appt 抽象類
/** * Appt 抽象類 * Class ApptEncoder */ abstract class ApptEncoder { abstract public function encode(); }
2、創建Ttd 抽象類
/** * Ttd 抽象類 * Class TtdEncoder */ abstract class TtdEncoder { abstract public function encode(); }
3、創建Contact 抽象類
/** * Contact 抽象類 * Class ContactEncoder */ abstract class ContactEncoder { abstract public function encode(); }
4、創建BloggsCal Appt 格式處理類
/** * BloggsCal Appt 格式處理類 * Class BloggsApptEncoder */ class BloggsApptEncoder extends ApptEncoder { public function encode() { // TODO: Implement encode() method. return "Appointment data encoded in BloggsCal format\n"; } }
5、創建BloggsCal Ttd 格式處理類
/** * BloggsCal Ttd 格式處理類 * Class BloggsTtdEncoder */ class BloggsTtdEncoder extends TtdEncoder { public function encode() { // TODO: Implement encode() method. return "Ttd data encoded in BloggsCal format\n"; } }
6、創建BloggsCal Contact 格式處理類
/** * BloggsCal Contact 格式處理類 * Class BloggsContactEncoder */ class BloggsContactEncoder extends ContactEncoder { public function encode() { // TODO: Implement encode() method. return "Contact data encoded in BloggsCal format\n"; } }
7、創建MegaCal Appt 格式處理類
/** * MegaCal Appt 格式處理類 * Class MegaApptEncoder */ class MegaApptEncoder extends ApptEncoder { public function encode() { // TODO: Implement encode() method. return "Appointment data encoded in MegaCal format\n"; } }
8、創建MegaCal Ttd 格式處理類
/** * MegaCal Ttd 格式處理類 * Class MegaTtdEncoder */ class MegaTtdEncoder extends TtdEncoder { public function encode() { // TODO: Implement encode() method. return "Ttd data encoded in MegaCal format\n"; } }
9、創建MegaCal Contact 格式處理類
/** * MegaCal Contact 格式處理類 * Class MegaContactEncoder */ class MegaContactEncoder extends ContactEncoder { public function encode() { // TODO: Implement encode() method. return "Contact data encoded in MegaCal format\n"; } }
10、創建BloggsCal 工廠類
/** * BloggsCal 工廠類 * Class BloggsCommsManager */ class BloggsCommsManager extends CommsManager { public function getHeaderText() { // TODO: Implement getHeaderText() method. return "BloggsCal header\n"; } public function getApptEncoder() { // TODO: Implement getApptEncoder() method. return new BloggsApptEncoder(); } public function getTtdEncoder() { // TODO: Implement getTtdEncoder() method. return new BloggsTtdEncoder(); } public function getContractEncoder() { // TODO: Implement getContractEncoder() method. return new BloggsContactEncoder(); } public function getFooterText() { // TODO: Implement getFooterText() method. return "BloggsCal footer\n"; } }
11、創建MegaCal 工廠類
/** * MegaCal 工廠類 * Class MegaCommsManager */ class MegaCommsManager extends CommsManager { public function getHeaderText() { // TODO: Implement getHeaderText() method. return "MegaCal header\n"; } public function getApptEncoder() { // TODO: Implement getApptEncoder() method. return new MegaApptEncoder(); } public function getTtdEncoder() { // TODO: Implement getTtdEncoder() method. return new MegaTtdEncoder(); } public function getContractEncoder() { // TODO: Implement getContractEncoder() method. return new MegaContactEncoder(); } public function getFooterText() { // TODO: Implement getFooterText() method. return "MegaCal footer\n"; } }
12、調用
$mgr = new BloggsCommsManager(); print $mgr->getHeaderText(); print $mgr->getApptEncoder()->encode(); print $mgr->getTtdEncoder()->encode(); print $mgr->getContractEncoder()->encode(); print $mgr->getFooterText(); $mega = new MegaCommsManager(); print $mega->getHeaderText(); print $mega->getApptEncoder()->encode(); print $mega->getTtdEncoder()->encode(); print $mega->getContractEncoder()->encode(); print $mega->getFooterText();
13、結果
BloggsCal header Appointment data encoded in BloggsCal format Ttd data encoded in BloggsCal format Contact data encoded in BloggsCal format BloggsCal footer MegaCal header Appointment data encoded in MegaCal format Ttd data encoded in MegaCal format Contact data encoded in MegaCal format MegaCal footer
總結:
1、解除了系統與實現細節間的耦合。我們可以在示常式序中添加或移除任何數量的編碼類型,而不會對系統造成任何影響。
2、我們組合了系統中功能相關的元素。因此,BloggsCommsManager 可以確保只使用與 BloggsCal 格式相關的類。
3、添加新產品會非常痛苦,這是因為我們不僅需要創建新產品的實現類,還需要修改抽象創建者及其所有的實現類來支持這個新產品。