摘要:工廠方法模式面向?qū)ο蟮脑O計強調(diào)抽象類高于實踐,盡可能的將代碼設計的一般化,而非特殊化也就是降低耦合,提升標準性。于是,前輩們便設計了特定類處理實例化的工廠方法。實現(xiàn)這個時候我們引入工廠方法模式,設置類創(chuàng)造者,類產(chǎn)品,。面向?qū)ο笤O計模式目錄
工廠方法模式
面向?qū)ο蟮脑O計強調(diào)“抽象類高于實踐”,盡可能的將代碼設計的一般化,而非特殊化——也就是降低耦合,提升標準性。于是,前輩們便設計了“特定類處理實例化”的工廠方法。
問題Appointment類需要解析BloggsCal數(shù)據(jù)格式,在類內(nèi)部,我們將數(shù)據(jù)格式寫死為BloggsCal,這將會造成耦合,而且實際上,未來業(yè)務需求要面臨更多的數(shù)據(jù)格式。
實現(xiàn)這個時候我們引入工廠方法模式,設置CommsManager類(創(chuàng)造者,creater)、ApptEncoder類(產(chǎn)品,Product)。
接下來,用戶只需要調(diào)用CommsManager對象的getApptEncoder方法,就可以得到他們需要的對象,而無需關注這個對象到底是哪種數(shù)據(jù)格式。
abstract class ApptEncoder { abstract function encode(); } class BloggsApptEncoder extends ApptEncoder { function encode() { return "數(shù)據(jù)格式為BloggsCal。"; } } class MegaApptEncoder extends ApptEncoder { function encode() { return "數(shù)據(jù)格式為MegaCal。"; } } class CommsManager { const BLOGGS = 1; const MEGA = 2; private $mode = 1; function __construct( $mode ) { $this->mode = $mode; } function getApptEncoder() { switch ( $this->mode ) { case ( self::MEGA ) : return new MegaApptEncoder(); default: return new BloggsApptEncoder(); } } function getHeaderText() { switch ( $this->mode ) { case ( self::MEGA ): return "Mega格式的表頭"; default: return "BloggsCal格式的表頭"; } } function getFootText() { switch ( $this->mode ) { case ( self::MEGA ): return "Mega格式的腳頁"; default: return "BloggsCal格式的腳頁"; } } } $comms = new CommsManager( CommsManager::MEGA ); $apptEncoder = $comms->getApptEncoder(); echo $apptEncoder->encode();
注意到CommsManager類的三個getXXX方法了嗎?
一旦數(shù)據(jù)格式增多、功能增加、數(shù)據(jù)格式間存在業(yè)務差異,就會造成一個新問題:大量的判斷語句——包括我自己在內(nèi)的一些人認為,這是代碼腐爛的象征。
至少,當重復的代碼開始蔓延,我們不應該感到樂觀。(盡管下面的處理方法,在一定程度上也重復了這個錯誤)
面對上述難題,我們有了下列三條要求:
在代碼運行時,才能了解我們要生成的對象類型(實時傳參,注意那句:$comms = new CommsManager( CommsManager::MEGA ));
相對輕松的加入新數(shù)據(jù)格式(Product);
每個產(chǎn)品類型都能輕松加入訂制化功能。
既然如此,我們干脆將 數(shù)據(jù)格式們 從CommsManager中剝離出來,形成多帶帶的子類。
// 產(chǎn)品抽象類、子類的代碼,同上。 abstract class CommsManager { abstract function getApptEncoder(); abstract function getHeaderText(); abstract function getFooterText(); } class BloggsCommsManager extends CommsManager { function getApptEncoder() { return new BloggsApptEncoder(); } function getHeaderText() { return "BloggsCal格式的表頭"; } function getFooterText() { return "BloggsCal格式的腳頁"; } } class MegaCommsManager extends CommsManager { function getApptEncoder() { return new MegaApptEncoder(); } function getHeaderText() { return "MegaCal格式的表頭"; } function getFooterText() { return "MegaCal格式的腳頁"; } } $comms = new BloggsCommsManager(); $apptEncoder = $comms->getApptEncoder(); echo $apptEncoder->encode();結果
這樣滿足了上述的三個要求,可我想,聰明的你已經(jīng)注意到了:一定程度上,創(chuàng)建者/產(chǎn)品們 產(chǎn)生了代碼重復。而且,問題被轉移到了工廠方法中,我們目前只是處理了Appointment功能,如果我們加入TodoList功能呢?
答案很明顯,我們需要:可以同時處理一組相關實現(xiàn)的架構,解決之道就在下一篇文章:抽象工廠模式。
(面向?qū)ο笤O計模式 - 目錄)
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/22553.html
摘要:所以,也要慎用當你的項目中,產(chǎn)品越來越多,創(chuàng)建者的數(shù)量也隨之臃腫,下一篇將介紹抽象工廠方法的變體原型模式,這種模式可以減少必須創(chuàng)建的類。 抽象工廠方法模式 在工廠方法模式中,我們通過中間件的方式,形成了以下格式的分離: 使用者 ↓創(chuàng)建者 ↓具體產(chǎn)品 問題 這樣,我們無論怎樣修正具體產(chǎn)品,都不會影響使用者。現(xiàn)在,我們可以做出來一群小工廠,他們有各自的產(chǎn)品,但形成了模式層面的重復,那么...
摘要:我們今天也來做一個萬能遙控器設計模式適配器模式將一個類的接口轉換成客戶希望的另外一個接口。今天要介紹的仍然是創(chuàng)建型設計模式的一種建造者模式。設計模式的理論知識固然重要,但 計算機程序的思維邏輯 (54) - 剖析 Collections - 設計模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對容器接口對象進行操作,第二類是返回一個容器接口對象,上節(jié)我們介紹了...
摘要:原型模式平行的繼承層次使用工廠模式在大型設計中,必須去維護大量的產(chǎn)品類。上文中,稱之為特殊的耦合在這里我們介紹一種其抽象工廠模式的變體原型模式。面向?qū)ο笤O計模式目錄 原型模式 平行的繼承層次使用工廠模式在:大型設計中,必須去維護大量的產(chǎn)品類。(上文中,稱之為特殊的耦合) 在這里我們介紹一種其抽象工廠模式的變體:原型模式。它使用clone關鍵詞,來復制具體產(chǎn)品類,使得具體產(chǎn)品類能完成自我...
摘要:系列目錄生成對象的模式面向?qū)ο蟮闹J絾卫嫦驅(qū)ο蟮闹J焦S方法面向?qū)ο蟮闹J匠橄蠊S方法面向?qū)ο蟮闹J皆徒M合類對象的模式面向?qū)ο蟮闹J浇M合更新裝飾模式 系列目錄 生成對象的模式 【面向?qū)ο蟮腜HP】之模式:單例 【面向?qū)ο蟮腜HP】之模式:工廠方法 【面向?qū)ο蟮腜HP】之模式:抽象工廠方法 【面向?qū)ο蟮腜HP】之模式:原型 組合類/對象的模式 【面向?qū)ο蟮腜HP】之模式...
閱讀 4278·2021-10-13 09:39
閱讀 482·2021-09-06 15:02
閱讀 3229·2019-08-30 15:53
閱讀 1040·2019-08-30 13:04
閱讀 2029·2019-08-30 11:27
閱讀 2010·2019-08-26 13:51
閱讀 2092·2019-08-26 11:33
閱讀 2902·2019-08-26 10:36