PHP之工廠模式

工廠方法模式依賴于繼承,因為對象創(chuàng)建 委托給 實現(xiàn)工廠方法創(chuàng)建對象 的子類

UML類圖

在上面的URL類圖中,Creator 需要 Product 對象的 Product1 類不直接實例化類。相反,它 Creator 指的是單獨 factoryMethod() 創(chuàng)建一個產(chǎn)品對象,這使得Creator獨立于哪個具體類被實例化。Creator可以重新定義要實例化的類的子類。在這個例子中,Creator1子類factoryMethod()通過實例化類來實現(xiàn)抽象Product1。

上面簡述一個工廠工作的流程,重點請看下面

1. 簡單工廠模式

  • 模式定義:
    簡單工廠模式(Simple Factory Pattern):又稱為靜態(tài)工廠方法(Static Factory Method)模式,之所以可以這么說,是因為簡單工廠模式是通過一個靜態(tài)方法來創(chuàng)建對象的。它屬于類創(chuàng)建型模式。在簡單工廠模式中,可以根據(jù)參數(shù)的不同返回返回不同類的實例。簡單工廠模式專門定義一個類來負責創(chuàng)建其他類的實例,被創(chuàng)建的實例通常都具有共同的父類。
  • 模式結(jié)構
  1. Factory:工廠角色

    工廠角色負責實現(xiàn)創(chuàng)建所有實例的內(nèi)部邏輯

  2. Product:抽象產(chǎn)品角色

    抽象產(chǎn)品角色是所創(chuàng)建的所有對象的父類,負責描述所有實例所共有的公共接口

  3. ConcreteProduct:具體產(chǎn)品角色

    具體產(chǎn)品角色是創(chuàng)建目標,所有創(chuàng)建的對象都充當這個角色的某個具體類的實例。

舉個栗子

我們想創(chuàng)建一個工廠,這個工廠呢可以生產(chǎn)貓和狗!通常情況下我們會怎么做呢

interface animals // 抽象產(chǎn)品角色
{
    public function animal();
}
class Cat implements animals // 具體產(chǎn)品角色
{
    public function animal()
    {
        return "貓貓";
    }
}
class Dog implements animals // 具體產(chǎn)品角色
{
    public function animal()
    {
        return "狗狗";
    }
}
class Factory // 工廠角色
{
    public static function createAnimal($param)
    {
        $result = null;
        switch($param)
        {
            case 'cat':
                $result = new Cat();
                break;
            case 'dog':
                $result = new Dog();
                break;
        }
        return $result;
    }
}
echo  Factory::createAnimal("cat")->animal(); // 貓貓
echo  Factory::createAnimal("dog")->animal(); // 狗狗

上面的例子中所講到的就是 簡單工廠(靜態(tài)工廠) <還請大佬批評>

簡單工廠適用環(huán)境

  • 工廠類負責創(chuàng)建的對象比較少:由于創(chuàng)建的對象較少,不會造成工廠方法中的業(yè)務邏輯太過復雜。
  • 客戶端只知道傳入工廠類的參數(shù),對于如何創(chuàng)建對象不關心:客戶端既不需要關心創(chuàng)建細節(jié),甚至連類名都不需要記住,只需要知道類型所對應的參數(shù)。

2. 工廠方法模式

工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多態(tài)工廠(Polymorphic Factory)模式,它屬于類創(chuàng)建型模式。在工廠方法模式中,工廠父類負責定義創(chuàng)建產(chǎn)品對象的公共接口,而工廠子類則負責生成具體的產(chǎn)品對象,這樣做的目的是將產(chǎn)品類的實例化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該實例化哪一個具體產(chǎn)品類。

舉個栗子:

abstract class animals // 抽象產(chǎn)品類
{
    abstract public function animal();
}
class Cat extends animals // 具體產(chǎn)品類
{
    public function animal()
    {
        return "貓貓";
    }
}
class Dog extends animals // 具體產(chǎn)品類
{
    public function animal()
    {
        return "狗狗";
    }
}
interface Factory   // 抽象工廠類, 將對象的創(chuàng)建抽象成一個接口
{
    public function create();
}
class CatFactory implements Factory  // 繼承工廠類, 用于實例化產(chǎn)品
{
    public function create()
    {
        return new Cat();
    }
}
class DogFactory implements Factory  // 繼承工廠類, 用于實例化產(chǎn)品
{
    public function create()
    {
        return new Dog();
    }
}

class Client    // 具體操作類
{
    public function test()
    {
        $catResult = new CatFactory();
        echo $catResult->create()->animal();

        $DogResult = new DogFactory();
        echo $DogResult->create()->animal();
    }
}

$lala = new Client();
$lala->test(); //  貓貓狗狗

定義一個用于創(chuàng)建對象的接口,讓子類決定哪個類實例化。 他可以解決簡單工廠模式中的封閉開放原則問題。

【工廠方法模式與簡單工廠模式】

  • 工廠方法模式與簡單工廠模式再結(jié)構上的不同不是很明顯。工廠方法類的核心是一個抽象工廠類,而簡單工廠模式把核心放在一個具體類上。
  • 工廠方法模式之所以有一個別名叫多態(tài)性工廠模式是因為具體工廠類都有共同的接口,或者有共同的抽象父類。
  • 當系統(tǒng)擴展需要添加新的產(chǎn)品對象時,僅僅需要添加一個具體對象以及一個具體工廠對象,原有工廠對象不需要進行任何修改,也不需要修改客戶端,很好的符合了”開放-封閉”原則。而簡單工廠模式在添加新產(chǎn)品對象后不得不修改工廠方法,擴展性不好。
  • 工廠方法模式退化后可以演變成簡單工廠模式。

3. 抽象工廠模式

抽象工廠模式(Abstract Factory Pattern):提供一個創(chuàng)建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬于對象創(chuàng)建型模式。

interface AnimalsFactory // 抽象工廠
{
    public function createCat(); // 生產(chǎn)一尾貓
    public function createDog(); // 生產(chǎn)一頭狗 -_-
}

abstract class Cat  // 貓抽象
{
    abstract function getCat();
}
class ForeignCat extends Cat // 貓具體
{
    public function getCat()
    {
        return "外國布偶貓".PHP_EOL;
    }
}
class ChineseCat extends Cat
{
    public function getCat()
    {
        return "華夏貓".PHP_EOL;
    }
}

abstract class Dog
{
    abstract function getDog();
}
class ChineseDog extends Dog
{
    public function getDog()
    {
        return "中華國犬".PHP_EOL;
    }
}
class ForeignDog extends Dog
{
    public function getDog()
    {
        return "外國哈士奇".PHP_EOL;
    }
}

class CreateChineseAnimalFactory implements AnimalsFactory 
{
    public function createCat()
    {
        return new ChineseCat();
    }
    public function createDog()
    {
        return new ChineseDog();
    }
}
class CreateForeignAnimalFactory implements AnimalsFactory
{
    public function createCat()
    {
        return new ForeignCat();
    }
    public function createDog()
    {
        return new ForeignDog();
    }
}

$result = new CreateForeignAnimalFactory();
$ForeignCat = $result->createCat();
echo $ForeignCat->getCat(); // 布偶貓

$ForeignDog = $result->createDog();
echo $ForeignDog->getDog(); // 哈士奇

總結(jié)

區(qū)別

  1. 簡單工廠模式(靜態(tài)方法工廠模式) : 用來生產(chǎn)同一等級結(jié)構中的任意產(chǎn)品。(不能增加新的產(chǎn)品)

  2. 工廠模式 :用來生產(chǎn)同一等級結(jié)構中的固定產(chǎn)品。(支持增加任意產(chǎn)品)

  3. 抽象工廠 :用來生產(chǎn)不同產(chǎn)品種類的全部產(chǎn)品。(不能增加新的產(chǎn)品,支持增加產(chǎn)品種類)

結(jié)語

使用工廠模式的好時機并不總是顯而易見的。不要強制這樣做,只有在構建復雜系統(tǒng)時才需要進行大量的抽象。你只要知道什么是抽象工廠,遲早你會發(fā)現(xiàn)一個真正的用例。good luck!

寫于2018年5月25日

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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