定義: 工廠方法模式:定義一個用於創建對象的介面,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。 代碼實例: 這裡還是接著上篇簡單工廠模式的那個例子,改成工廠方法模式。 1、創建一個抽象類 ApptEncoder /** * 抽象類 * Class ApptEncoder */ a ...
定義:
工廠方法模式:定義一個用於創建對象的介面,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。
代碼實例:
這裡還是接著上篇簡單工廠模式的那個例子,改成工廠方法模式。
1、創建一個抽象類 ApptEncoder
/** * 抽象類 * Class ApptEncoder */ abstract class ApptEncoder { abstract public function encode(); }
2、創建 BloggsCal 格式處理類
/** * BloggsCal 格式處理類 * Class BloggsApptEncoder */ class BloggsApptEncoder extends ApptEncoder { public function encode() { // TODO: Implement encode() method. return "Appointment data encoded in BloggsCal format\n"; } }
3、創建 MegaCal 格式處理類
/** * MegaCal 格式處理類 * Class MegaApptEncoder */ class MegaApptEncoder extends ApptEncoder { public function encode() { // TODO: Implement encode() method. return "Appointment data encoded in MegaCal format\n"; } }
4、創建工廠抽象類 CommsManager
/** * 工廠抽象類 * Class CommsManager */ abstract class CommsManager { abstract public function getHeaderText(); abstract public function getApptEncoder(); abstract public function getFooterText(); }
5、創建 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 getFooterText() { // TODO: Implement getFooterText() method. return "BloggsCal footer\n"; } }
6、創建 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 getFooterText() { // TODO: Implement getFooterText() method. return "MegaCal footer\n"; } }
7、調用:
// 如果要換成 MegaCal 格式處理,直接換成 $mar = new MegaCommsManager() 就可以了 $mgr = new BloggsCommsManager(); print $mgr->getHeaderText(); print $mgr->getApptEncoder()->encode(); print $mgr->getFooterText();
8、結果:
BloggsCal header Appointment data encoded in BloggsCal format BloggsCal footer
總結:
1、使用工廠方法模式,如果需要新增一種格式處理,就不需要修改原有的工廠類了,只需要為這些抽象類實現新的子類即可。這樣整個工廠和產品體系其實都沒有修改的變化,而只是擴展的變化,這就符合了“開放-封閉原則”。
2、工廠方法模式實現時,客戶端需要決定實例化哪一個工廠來實現,選擇判斷的問題還是存在的,也就是說,工廠方法把簡單工廠的內部邏輯判斷移到了客戶端代碼來進行。你想要加功能,本來修改工廠類,而現在是修改客戶端。
3、工廠方法模式的缺點是由於每加一個產品,就需要加一個產品工廠的類,增加了額外的開發量。