PHP設計模式(八):工廠模式

原文地址:PHP設計模式(八):工廠模式php

Introduction

PHP設計模式(七):設計模式分類中咱們提到過建立設計模式(Creation patterns),建立設計模式專一於設計對象(Object)和實例(Instance)的建立過程。
建立設計模式包括下面五種設計模式:程序員

  1. 抽象工廠設計模式(Abstract Factory)設計模式

  2. 生成器模式(Builder)架構

  3. 工廠設計模式(Factory Method)函數

  4. 原型設計模式(Prototype Method)ui

  5. 單例設計模式(Singleton)this

當程序逐漸擴展的時候,須要更多的新對象,新對象的建立不該該依賴於建立者,換句話說,新對象的建立過程,不該該依賴調用建立函數的對象。爲了減小冗餘,增長拓展性,工廠模式就是一種建立新對象時使用的設計模式。設計

工廠模式

工廠模式,也是五種設計模式中惟一的類的設計模式(Class patterns),即在類中就能實現的設計模式。
聽起來挺抽象?對比原型設計模式,這是一種對象設計模式(Object patterns),經過對象的__clone()方法來實現的設計模式。
在工廠模式中,新建立的對象/產品並不依賴於生產它的對象/工廠,新對象和調用者之間是低耦合狀態。一般調用者和工廠交互,由工廠來生成新對象,新對象只和工廠有關。code

什麼時候使用工廠模式?

簡單來講,當需求對類的個數不明確的時候,可使用工廠模式,如:
你須要建立一個在線博物館,但你並不確切的知道究竟有多少文物,你不可能無限的增長新的文物類,同時對於損毀的文物,你不可能無限的去清理這些類。
反過來講,若是你確切的知道類的總量,那麼你就沒有必要使用工程模式,直接經過繼承的方式就能實現好的設計。對象

Example

仍是使用咱們慣用的鯨魚和鯉魚的例子,如今咱們想實現一個海洋館,目前咱們並不肯定究竟有多少海洋生物。
先是一個抽象的工廠類:

<?php
abstract class Factory {
  protected abstract function create();
  public function factoryStart() {
    return $this->create();
  }
}
?>

而後是兩個工廠:鯨魚工廠和鯉魚工廠

<?php
class WhaleFactory extends Factory {
  protected function create() {
    $whale = new Whale();
    return $whale->create();
  }
}
class CarpFactory extends Factory {
  protected function create() {
    $carp = new Carp();
    return $carp->create();
  }
}
?>

而後是抽象的動物接口:

<?php
interface Animal {
  public function create();
}
?>

而後是具體的動物類:鯨魚類和鯉魚類

<?php
class Whale implements Animal {
  private $name;
  public function create() {
    $this->name = "Whale";
    return $this->name . " is created.\n";
  }
}
class Carp implements Animal {
  private $name;
  public function create() {
    $this->name = "Carp";
    return $this->name . " is created.\n";
  }
}
?>

下面給出使用工廠建立鯨魚和鯉魚的代碼:

<?php
$whaleFactory = new WhaleFactory();
echo $whaleFactory->factoryStart();
$carpFactory = new CarpFactory();
echo $carpFactory->factoryStart();
?>

運行一下:

Whale is created.
Carp is created.

到這裏你是否是以爲,其實直接生成兩個類就好了,何須搞這麼複雜?彆着急,好戲在後面。

修改類的方法

因爲Interface的限制,修改類的方法被限定在了create()方法中,所以能夠避免偷懶的程序員新增長的不合理函數。
簡單修改一下:

<?php
class Whale implements Animal {
  private $name;
  public function create() {
    $this->name = "Whale";
    return $this->name . " is created. Whale eats fish.\n";
  }
}
class Carp implements Animal {
  private $name;
  public function create() {
    $this->name = "Carp";
    return $this->name . " is created. Carp eats moss.\n";
  }
}
?>

因爲對象是由工廠造出來的,外部不可能直接調用或者修改類的實現,類的修改被限定在了類的對外接口上。這樣的架構易於擴展。

一個工廠

工廠模式的靈活,在於能夠只擁有一個工廠,卻能生產多個類/產品。
修改咱們的抽象工廠,給create()方法增長animal接口:

<?php
abstract class Factory {
  protected abstract function create(Animal $animal);
  public function factoryStart($animal) {
    return $this->create($animal);
  }
}
?>

而後合併以前的鯨魚工廠和鯉魚工廠:

<?php
class AnimalFactory extends Factory {
  protected function create(Animal $animal) {
    return $animal->create();
  }
}
?>

修改使用工廠建立鯨魚和鯉魚的代碼:

<?php
$animalFactory = new AnimalFactory();
echo $animalFactory->factoryStart(new Whale());
echo $animalFactory->factoryStart(new Carp());
?>

運行一下:

Whale is created. Whale eats fish.
Carp is created. Carp eats moss.

鯨魚類和鯉魚類源源不斷的從一個工廠中被建立出來了。經過這種設計模式,類的建立過程統一經過一個接口來實現,接口外部並不須要關心類是如何被建立出來的,而接口內部實現也獲得了很好的拓展性。

Summary

本文介紹了工廠設計模式,使用這種設計模式,可讓你經過一個或多個工廠的接口,建立無數新類,調用任意類的方法。因爲接口嚴格定義了新類/產品的形態,所以在維護和拓展的時候,能夠省去很多力氣。

相關文章
相關標籤/搜索