【設計模式】工廠方法模式

疯子丶pony發表於2024-03-07

1、定義

工廠方法模式是一種建立型的設計模式,其在父類中提供一個建立物件的方法,允許子類決定例項化物件的型別。其實就把產品物件的實際建立工作放到具體的子類工廠當中實現。

2、優缺點

  • 優點:
    • 可以避免建立者和具體產品之間的緊密耦合
    • 則。可以將產品建立程式碼放在程式的單一位置,從而使得程式碼更容易維護
    • 則。無需更改現有客戶端程式碼就可以在程式中引入新的產品型別
  • 缺點:
    • 每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,增加了系統的複雜度。

3、模式結構

  • 抽象工廠(Abstract Factory):提供一個建立產品的介面。呼叫者可以透過它訪問具體工廠的工廠方法。
  • 具體工廠(Concrete Factory):繼承自抽象工廠,並實現其建立物件的方法。
  • 抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能。
  • 具體產品(Concrete Product):實現了抽象產品中所定義的介面,由具體工廠來建立,與同具體工廠之間是一一對應的。

4、具體程式碼

1、抽象工廠(Abstract Factory):提供一個建立產品的介面。呼叫者可以透過它訪問具體工廠的工廠方法。

<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:55
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 抽象工廠類
 */
abstract class CarFactory
{
    abstract public function createCar(): Car;
}

2、具體工廠(Concrete Factory):繼承自抽象工廠,並實現其建立物件的方法。

<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:55
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 寶馬工廠
 *
 * 具體工廠類,繼承自抽象工廠
 */
class BmwFactory extends CarFactory
{

    public function createCar(): Car
    {
        // TODO: Implement createCar() method.
        return new Bmw();
    }
}
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:55
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 賓士工廠
 *
 * 具體工廠類,繼承自抽象工廠
 */
class BenzFactory extends CarFactory
{

    public function createCar(): Car
    {
        // TODO: Implement createCar() method.
        return new Benz();
    }
}

3、抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能。

<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:21
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 抽象產品類
 */
abstract class Car
{
    /**
     * 給汽車加油
     * 抽象方法,用於實現產品的功能
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/2/23 11:26
     */
    public abstract function refuel();

    /**
     * 駕駛汽車
     * 抽象方法,用於實現產品的功能
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/2/23 11:26
     */
    public abstract function drive();
}

4、具體產品(Concrete Product):實現了抽象產品中所定義的介面,由具體工廠來建立,與同具體工廠之間是一一對應的。

<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:22
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 具體產品類-寶馬汽車
 */
class Bmw extends Car
{

    public function refuel()
    {
        // TODO: Implement refuel() method.
        echo  "給寶馬車加油\n";
    }

    public function drive()
    {
        // TODO: Implement drive() method.
        echo  "駕駛寶馬車\n";
    }
}
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:22
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 具體產品類-賓士汽車
 */
class Benz extends Car
{

    public function refuel()
    {
        // TODO: Implement refuel() method.
        echo "給賓士車加油\n";
    }

    public function drive()
    {
        // TODO: Implement drive() method.
        echo "駕駛賓士車\n";
    }
}

5、呼叫方式

<?php
/**
 * 工廠方法模式
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:16
 */

namespace app\admin\controller\design_mode;

use app\admin\service\design_mode\factory_method\BenzFactory;
use app\admin\service\design_mode\factory_method\BmwFactory;

class FactoryMethodController
{
    /**
     * 呼叫工廠方法模式
     * @return void
     * @Author: fengzi
     * @Date: 2024/2/26 9:56
     */
    public function index()
    {
        //呼叫賓士方法
        $factory = new BenzFactory();
        $car = $factory->createCar();
        $car->refuel();
        $car->drive();

        //呼叫寶馬方法
        $factory = new BmwFactory();
        $car = $factory->createCar();
        $car->refuel();
        $car->drive();
    }
}

6、呼叫結果展示:

5、工廠方法模式的精簡版 - 簡單工廠模式

簡單工廠模式中的每個產品不用像工廠方法模式一樣每個產品都對應一個工廠類,只需要透過一個工廠方法來判斷性的建立對應產品。具體請看以下程式碼。

1、抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能。

<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:21
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 抽象產品類
 */
abstract class Car
{
    /**
     * 給汽車加油
     * 抽象方法,用於實現產品的功能
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/2/23 11:26
     */
    public abstract function refuel();

    /**
     * 駕駛汽車
     * 抽象方法,用於實現產品的功能
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/2/23 11:26
     */
    public abstract function drive();
}

2、具體產品(Concrete Product):實現了抽象產品中所定義的介面,由一個工廠方法來建立產品物件。

<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:22
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 具體產品類-賓士汽車
 */
class Benz extends Car
{

    public function refuel()
    {
        // TODO: Implement refuel() method.
        echo "給賓士車加油\n";
    }

    public function drive()
    {
        // TODO: Implement drive() method.
        echo "駕駛賓士車\n";
    }
}
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:22
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 具體產品類-寶馬汽車
 */
class Bmw extends Car
{

    public function refuel()
    {
        // TODO: Implement refuel() method.
        echo  "給寶馬車加油\n";
    }

    public function drive()
    {
        // TODO: Implement drive() method.
        echo  "駕駛寶馬車\n";
    }
}

3、簡單工廠的工廠類

<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/26
 * Time: 10:17
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 簡單工廠類
 */
class SimpleFactory
{
    /**
     * 簡單工廠模式
     * @param string $type  產品型別:benz賓士,bmw寶馬
     * @return string|void
     * @Author: fengzi
     * @Date: 2024/2/26 10:15
     */
    public function getProduct(string $type): Car
    {
        switch ($type)
        {
            case 'benz':
                return new Benz();
                break;
            case 'bmw':
                return new Bmw();
                break;
            default:
                return '';
        }
    }
}

4、呼叫方式

<?php
/**
 * 簡單工廠模式
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:16
 */

namespace app\admin\controller\design_mode;

use app\admin\service\design_mode\factory_method\SimpleFactory;

class FactoryMethodController
{
    /**
     * 簡單工廠模式
     * @Author: fengzi
     * @Date: 2024/2/26 10:15
     */
    public function simpleFactory()
    {
        $simpleFactory = new SimpleFactory();
        //呼叫賓士方法
        $benz = $simpleFactory->getProduct('benz');
        $benz->refuel();
        $benz->drive();

        //呼叫寶馬方法
        $bmw = $simpleFactory->getProduct('bmw');
        $bmw->refuel();
        $bmw->drive();
    }
}

5、呼叫結果展示

6、總結

  • 通常我們把被建立的物件稱之為【產品】
  • 建立【產品】的物件稱為【工廠】
  • 當產品比較固定且數量少的情況下,我們只需要一個工廠類就可以,這個模式下我們稱之為【簡單工廠】

相關文章