定義:
簡單工廠模式:將呼叫者和創建者分離,實作解耦,呼叫者直接向工廠請求,通過工廠去選擇需要實體化的物件,用一個單獨的類來做這個創建實體的程序,
代碼實體:
問題:假設一個關于個人事務管理的專案中有許多型別的物件,其中一個是 Appointment 物件,現在需要通過一種稱為 BloggsCal 的格式進行預約資料的互動,后面可能還需要處理更多的資料格式,比如 MegaCal 格式,
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 */ class CommsManager { const BLOGGS = 1; const MEGA = 2; private $model; /** * CommsManager constructor. * @param $model */ public function __construct($model) { $this->model = $model; } /** * 通過工廠去選擇需要實體化的物件 */ public function getApptEncoder() { switch ($this->model) { case (self::BLOGGS): return new BloggsApptEncoder(); default: return new MegaApptEncoder(); } } }
5、呼叫:
$man = new CommsManager(CommsManager::BLOGGS); print $man->getApptEncoder()->encode(); $man = new CommsManager(CommsManager::MEGA); print $man->getApptEncoder()->encode();
6、結果:
Appointment data encoded in BloggsCal format
Appointment data encoded in MegaCal format
如果后面需要新增一種格式處理,則需要新增一個相應的格式處理類,再到工廠類中增加相應的實體化呼叫就可以了,
總結:
簡單工廠模式的最大優點在于工廠類中包含了必要的邏輯判斷,根據客戶端的選擇條件動態實體化相關的類,對于客戶端來說,去除了與具體產品的依賴,
但剛才也說了,如果新增一種格式處理,是要修改工廠類的,這就等于說,我們不但對擴展開放了,對修改也開放了,因此違背了“開放-封閉原則”,這時可以使用工廠方法模式,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/19652.html
標籤:設計模式
