關(guān)于三種工廠模式的總結(jié)

工廠模式分為簡單工廠模式刚陡,工廠方法模式和抽象工廠模式陆盘,它們都屬于設(shè)計模式中的創(chuàng)建型模式舷蟀。其主要功能都是幫助我們把對象的實例化部分抽取了出來恤磷,目的是降低系統(tǒng)中代碼耦合度,并且增強了系統(tǒng)的擴展性野宜。本文對這三種模式進行了介紹并且分析它們之間的區(qū)別扫步。

簡單工廠模式

簡單工廠模式最大的優(yōu)點在于實現(xiàn)對象的創(chuàng)建和對象的使用分離,將對象的創(chuàng)建交給專門的工廠類負責(zé)匈子,但是其最大的缺點在于工廠類不夠靈活河胎,增加新的具體產(chǎn)品需要修改工廠類的判斷邏輯代碼,而且產(chǎn)品較多時虎敦,工廠方法代碼邏輯將會非常復(fù)雜游岳。

<?php

//簡單工廠方法

interface People
{
    public function say();

}

class Man implements People
{
    public function say()
    {
        echo 'this is a man ';
    }
}

class Women implements People
{
    public function say()
    {
        echo 'this is a women';
    }
}

class SimpleFactory
{
    public static function create($name)
    {
    if ($name == 'man') {
            return new Man();
        } elseif ($name == 'women') {
            return new Women();
        }
    }

}

//具體調(diào)用
$man = SimpleFactory::create('man');
$man->say();
$women = SimpleFactory::create('women');
$women->say();

簡單工廠模式最大的優(yōu)點在于實現(xiàn)對象的創(chuàng)建和對象的使用分離,將對象的創(chuàng)建交給專門的工廠類負責(zé)其徙,但是其最大的缺點在于工廠類不夠靈活胚迫,增加新的具體產(chǎn)品需要修改工廠類的判斷邏輯代碼,而且產(chǎn)品較多時唾那,工廠方法代碼將會非常復(fù)雜访锻。

工廠方法模式

此模式中,通過定義一個抽象的核心工廠類通贞,并定義創(chuàng)建產(chǎn)品對象的接口朗若,創(chuàng)建具體產(chǎn)品實例的工作延遲到其工廠子類去完成。這樣做的好處是核心類只關(guān)注工廠類的接口定義昌罩,而具體的產(chǎn)品實例交給具體的工廠子類去創(chuàng)建哭懈。當系統(tǒng)需要新增一個產(chǎn)品是,無需修改現(xiàn)有系統(tǒng)代碼茎用,只需要添加一個具體產(chǎn)品類和其對應(yīng)的工廠子類遣总,使系統(tǒng)的擴展性變得很好睬罗,符合面向?qū)ο缶幊痰拈_閉原則。體代碼如下:

<?php
//工廠方法模式

interface People
{
    public function say();
}

class Man implements People
{
    public function say()
    {
        echo 'this is a man';
    }
}

class Women implements People
{
    public function say()
    {
        echo 'this is a women';
    }
}

//與簡單工廠模式相比旭斥。區(qū)別在于容达,此處將對象的創(chuàng)建抽象成一個接口
interface CreatePeople
{
    public function create();
}

class FactoryMan implements CreatePeople
{
    public function create()
    {
        return new Man();
    }

}

class FactoryWomen implements CreatePeople
{
    public function create()
    {
        return new Women();
    }
}

class  Client
{
    // 具體生產(chǎn)對象并執(zhí)行對象方法測試
    public function test() {
        $factory = new FactoryMan();
        $man = $factory->create();
        $man->say();

        $factory = new FactoryWomen();
        $man = $factory->create();
        $man->say();
    }
}

// 執(zhí)行
$demo = new Client();
$demo->test();

工廠方法模式是簡單工廠模式的進一步抽象和推廣。由于使用了面向?qū)ο蟮亩鄳B(tài)性垂券,工廠方法模式保持了簡單工廠模式的優(yōu)點花盐,而且克服了它的缺點。在工廠方法模式中菇爪,核心的工廠類不再負責(zé)所有產(chǎn)品的創(chuàng)建算芯,而是將具體創(chuàng)建工作交給子類去做。這個核心類僅僅負責(zé)給出具體工廠必須實現(xiàn)的接口凳宙,而不負責(zé)產(chǎn)品類被實例化這種細節(jié)熙揍,這使得工廠方法模式可以允許系統(tǒng)在不修改工廠角色的情況下引進新產(chǎn)品。

抽象工廠模式

提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口氏涩,而無須指定它們具體的類届囚。抽象工廠模式又稱為Kit模式,屬于對象創(chuàng)建型模式是尖。

此模式是對工廠方法模式的進一步擴展意系。在工廠方法模式中,一個具體的工廠負責(zé)生產(chǎn)一類具體的產(chǎn)品析砸,即一對一的關(guān)系昔字,但是,如果需要一個具體的工廠生產(chǎn)多種產(chǎn)品對象首繁,那么就需要用到抽象工廠模式了。

<?php 

interface TV{
  public function open();
  public function watch();
}

class HaierTv implements TV
{
  public function open()
  {
      echo "Open Haier TV <br>";
  }

  public function watch()
  {
      echo "I'm watching TV <br>";
  }
}

interface PC{
  public function work();
  public function play();
}

class LenovoPc implements PC
{
  public function work()
  {
      echo "I'm working on a Lenovo computer <br>";
  }
  public function play()
  {
      echo "Lenovo computers can be used to play games <br>";
  }
}

abstract class Factory{
  abstract public static function createPc();
  abstract public static function createTv();
}

class ProductFactory extends Factory
{
  public static function createTV()
  {
      return new HaierTv();
  }
  public static function createPc()
  {
      return new LenovoPc();
  }
}

$newTv = ProductFactory::createTV();
$newTv->open();
$newTv->watch();

$newPc = ProductFactory::createPc();
$newPc->work();
$newPc->play();

在上面的Factory抽象類中陨囊,定義了兩個抽象方法弦疮,這兩個抽象方法分別用來生產(chǎn)不同的產(chǎn)品(即由不同類實例化的對象)。

工廠方法模式和抽象工廠模式對比

通過以上代碼:我們來對比一下工廠方法模式和抽象工廠模式:

  • 工廠方法模式中

當我需要多生產(chǎn)一種新的產(chǎn)品蜘醋,比如factoryKid這個產(chǎn)品胁塞,我需要專門再設(shè)一個factoryKid的工廠,即添加如下代碼:

class Kid implements People{
    public function say()
    {
        echo 'this is a kid';
    }
}

class FactoryKid implements CreatePeople
{
    public function create()
    {
        return new Kid();
    }
}
  • 抽象工廠模式中

同樣當我需要多生產(chǎn)一種新的產(chǎn)品压语,比如生產(chǎn)一個iphone,此時我需要修改工廠父類里的接口啸罢,并且在具體工廠類ProductFactory這個工廠里增加一條createPhone生產(chǎn)線(即類里面的方法),所需添加的代碼如下:

interface Phone{
  public function work();
  public function sms();
}

class IPhone implements Phone
{
  public function work()
  {
      echo "I'm iphone <br>";
  }
  public function sms()
  {
      echo "this is an iphone <br>";
  }
}
//在原來的抽象工廠類中添加方法聲明
abstract class Factory{
    abstract public static function createPc();
    abstract public static function createTv();
    abstract public static function createPhone();
}

//在原來的工廠類里添加一個方法
class ProductFactory extends Factory
{
  public static function createTV()
  {
      return new HaierTv();
  }
  public static function createPc()
  {
      return new LenovoPc();
  }
  public static function createPhone()
  {
      return new IPhone();
  }
}

從上面的分析可以看出胎食,要生產(chǎn)一個新的產(chǎn)品扰才,抽象工廠模式并不比工廠方法模式更為便捷,那么抽象工廠模式的好處在哪呢?它優(yōu)點就是在于是增加固定類型產(chǎn)品的不同具體工廠比較方便厕怜,比如我要增加一個生產(chǎn)同樣類型產(chǎn)品的具體工廠Product2Factory衩匣,那么就再建一個Product2Factory類繼承Factory就可以了蕾总。

最后的最后,總結(jié)一下工廠方法模式和抽象工廠模式的核心區(qū)別
  • 工廠方法模式利用繼承琅捏,抽象工廠模式利用組合
  • 工廠方法模式產(chǎn)生一個對象生百,抽象工廠模式產(chǎn)生一族對象
  • 工廠方法模式利用子類創(chuàng)造對象,抽象工廠模式利用接口的實現(xiàn)創(chuàng)造對象
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末柄延,一起剝皮案震驚了整個濱河市蚀浆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌搜吧,老刑警劉巖蜡坊,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赎败,居然都是意外死亡秕衙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門僵刮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來据忘,“玉大人,你說我怎么就攤上這事搞糕∮碌酰” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵窍仰,是天一觀的道長汉规。 經(jīng)常有香客問我,道長驹吮,這世上最難降的妖魔是什么针史? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮碟狞,結(jié)果婚禮上啄枕,老公的妹妹穿的比我還像新娘。我一直安慰自己族沃,他們只是感情好频祝,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著脆淹,像睡著了一般常空。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盖溺,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天漓糙,我揣著相機與錄音,去河邊找鬼咐柜。 笑死兼蜈,一個胖子當著我的面吹牛攘残,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播为狸,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼歼郭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辐棒?” 一聲冷哼從身側(cè)響起病曾,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漾根,沒想到半個月后泰涂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡辐怕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年逼蒙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寄疏。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡是牢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出陕截,到底是詐尸還是另有隱情驳棱,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布农曲,位于F島的核電站社搅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏乳规。R本人自食惡果不足惜形葬,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驯妄。 院中可真熱鬧荷并,春花似錦、人聲如沸青扔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽微猖。三九已至,卻和暖如春缘屹,著一層夾襖步出監(jiān)牢的瞬間凛剥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工轻姿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留犁珠,地道東北人逻炊。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像犁享,于是被迫代替她去往敵國和親余素。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計原則時需要注意以下幾點:a) 高內(nèi)聚炊昆、低耦合和單一職能的“沖突”實際上,這兩者...
    彥幀閱讀 3,734評論 0 14
  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用瓶竭、多...
    MinoyJet閱讀 3,903評論 1 15
  • 工廠模式是我們最常用的實例化對象模式了男摧,是用工廠方法代替new操作的一種模式。通常我們所說的工廠模式是指工廠方法模...
    zfylin閱讀 1,309評論 0 7
  • 首先添加一個redView和一個greenView敢茁,其中g(shù)reenView是添加到redView上面佑淀。 UIVie...
    愁云閱讀 130評論 0 0
  • 在11月中旬時,有人問我彰檬,這一年還有一個月就結(jié)束了伸刃,你有什么收獲?我一愣僧叉,因為回想17年過去的11個月奕枝,我感覺自己...
    遇柒ML閱讀 296評論 1 3