1. 程式人生 > >初識設計模式——工廠模式

初識設計模式——工廠模式

由於簡單工廠模式違反了設計模式六大原則中的“開閉原則”,所以產生了工廠模式,工廠模式定義一個建立物件的介面,讓子類決定例項化那一個類。工廠方法使一個類的例項化延遲到子類。以之前的簡單工廠模式所實現的功能為例,工廠模式的程式碼如下。

工廠介面

<?php

include './Claculator.php';
include './claculator/Add.php';
include './claculator/Divide.php';
include './claculator/Tract.php';
include './claculator/Ride.php';

interface Factory
{
    static function createClaculator();
}

加法工廠

<?php

class AddFactory implements Factory
{
    public static function createClaculator()
    {
        return new Add();
    }
}

減法工廠

<?php

class TractFactory implements Factory
{
    public static function createClaculator()
    {
        return new Tract();
    }
}

乘法工廠

<?php

class RideFactory implements Factory
{
    public static function createClaculator()
    {
        return new Ride();
    }
}

除法工廠

<?php

class DivideFactory implements Factory
{
    public static function createClaculator()
    {
        return new Divide();
    }
}

計算介面

<?php

Interface Claculator
{
    function evaluate($numberA, $numberB);
}

加法計算類

<?php

class Add implements Claculator
{
    public function evaluate($numberA, $numberB)
    {
        return $numberA+$numberB;
    }
}

減法計算類

<?php

class Tract implements Claculator
{
    public function evaluate($numberA, $numberB)
    {
        return $numberA-$numberB;
    }
}

乘法計算類

<?php

class Ride implements Claculator
{
    public function evaluate($numberA, $numberB)
    {
        return $numberA*$numberB;
    }
}

除法計算類

<?php

class Divide implements Claculator
{
    public function evaluate($numberA, $numberB)
    {
        if ($numberB==0)
            return null;
        return $numberA/$numberB;
    }
}

客戶端程式碼

<?php

$numberA = isset($_GET['a'])?$_GET['a']:0;
$numberB = isset($_GET['b'])?$_GET['b']:0;
$type = isset($_GET['type'])?$_GET['type']:'+';

include './Factory.php';
include './factory/DivideFactory.php';
include './factory/AddFactory.php';
include './factory/TractFactory.php';
include './factory/RideFactory.php';

switch ($type) {
    case '+':
        $server = AddFactory::createClaculator();
        break;
    case '-':
        $server = TractFactory::createClaculator();
        break;
    case '*':
        $server = RideFactory::createClaculator();
        break;
    case '/':
        $server = DivideFactory::createClaculator();
        break;
    case '':
        $server = null;
        break;
}
if (empty($server))
    $result = 0;
else
    $result = $server->evaluate($numberA, $numberB);

var_dump($result);

UML類圖

UML類圖類似於這個圖,這是從《大話設計模式》中擷取的圖片,只不過是類名稱需要變化一下,體現的內容大同小異。

簡單工廠模式VS工廠模式

工廠模式克服了簡單工廠模式中違反了“開閉原則”的缺點,又保持了封裝物件建立過程的優點。但工廠模式僅僅只為建立一個物件,就生成了2倍的類檔案,個人感覺有點浪費。

簡單工廠模式最大的優點在於工廠類中包含了必要的邏輯判斷,根據客戶端的選擇條件動態選擇例項化的類,對於客戶端來說,去除了與具體產品的依賴,符合“迪米特原則”。