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

工廠模式分為簡(jiǎn)單工廠模式,工廠方法模式和抽象工廠模式,它們都屬于設(shè)計(jì)模式中的創(chuàng)建型模式。其主要功能都是幫助我們把對(duì)象的實(shí)例化部分抽取了出來(lái),目的是降低系統(tǒng)中代碼耦合度,并且增強(qiáng)了系統(tǒng)的擴(kuò)展性。本文對(duì)這三種模式進(jìn)行了介紹并且分析它們之間的區(qū)別。

簡(jiǎn)單工廠模式

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

<?php

//簡(jiǎn)單工廠方法

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();

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

工廠方法模式

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

<?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';
    }
}

//與簡(jiǎn)單工廠模式相比。區(qū)別在于,此處將對(duì)象的創(chuàng)建抽象成一個(gè)接口
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)對(duì)象并執(zhí)行對(duì)象方法測(cè)試
    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();

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

抽象工廠模式

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

此模式是對(duì)工廠方法模式的進(jìn)一步擴(kuò)展。在工廠方法模式中,一個(gè)具體的工廠負(fù)責(zé)生產(chǎn)一類具體的產(chǎn)品,即一對(duì)一的關(guān)系,但是,如果需要一個(gè)具體的工廠生產(chǎn)多種產(chǎn)品對(duì)象,那么就需要用到抽象工廠模式了。

<?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抽象類中,定義了兩個(gè)抽象方法,這兩個(gè)抽象方法分別用來(lái)生產(chǎn)不同的產(chǎn)品(即由不同類實(shí)例化的對(duì)象)。

工廠方法模式和抽象工廠模式對(duì)比

通過(guò)以上代碼:我們來(lái)對(duì)比一下工廠方法模式和抽象工廠模式:

  • 工廠方法模式中

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

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

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

同樣當(dāng)我需要多生產(chǎn)一種新的產(chǎn)品,比如生產(chǎn)一個(gè)iphone,此時(shí)我需要修改工廠父類里的接口,并且在具體工廠類ProductFactory這個(gè)工廠里增加一條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>";
  }
}
//在原來(lái)的抽象工廠類中添加方法聲明
abstract class Factory{
    abstract public static function createPc();
    abstract public static function createTv();
    abstract public static function createPhone();
}

//在原來(lái)的工廠類里添加一個(gè)方法
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)一個(gè)新的產(chǎn)品,抽象工廠模式并不比工廠方法模式更為便捷,那么抽象工廠模式的好處在哪呢?它優(yōu)點(diǎn)就是在于是增加固定類型產(chǎn)品的不同具體工廠比較方便,比如我要增加一個(gè)生產(chǎn)同樣類型產(chǎn)品的具體工廠Product2Factory,那么就再建一個(gè)Product2Factory類繼承Factory就可以了。

最后的最后,總結(jié)一下工廠方法模式和抽象工廠模式的核心區(qū)別
  • 工廠方法模式利用繼承,抽象工廠模式利用組合
  • 工廠方法模式產(chǎn)生一個(gè)對(duì)象,抽象工廠模式產(chǎn)生一族對(duì)象
  • 工廠方法模式利用子類創(chuàng)造對(duì)象,抽象工廠模式利用接口的實(shí)現(xiàn)創(chuàng)造對(duì)象
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚、低耦合和單一職能的“沖突”實(shí)際上,這兩者...
    彥幀閱讀 3,873評(píng)論 0 14
  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,073評(píng)論 1 15
  • 工廠模式是我們最常用的實(shí)例化對(duì)象模式了,是用工廠方法代替new操作的一種模式。通常我們所說(shuō)的工廠模式是指工廠方法模...
    zfylin閱讀 1,403評(píng)論 0 7
  • 首先添加一個(gè)redView和一個(gè)greenView,其中g(shù)reenView是添加到redView上面。 UIVie...
    愁云閱讀 164評(píng)論 0 0
  • 在11月中旬時(shí),有人問(wèn)我,這一年還有一個(gè)月就結(jié)束了,你有什么收獲?我一愣,因?yàn)榛叵?7年過(guò)去的11個(gè)月,我感覺(jué)自己...
    遇柒ML閱讀 406評(píng)論 1 3

友情鏈接更多精彩內(nèi)容