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

在上面的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é)構
- Factory:工廠角色
工廠角色負責實現(xiàn)創(chuàng)建所有實例的內(nèi)部邏輯
- Product:抽象產(chǎn)品角色
抽象產(chǎn)品角色是所創(chuàng)建的所有對象的父類,負責描述所有實例所共有的公共接口
- 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ū)別
簡單工廠模式(靜態(tài)方法工廠模式) : 用來生產(chǎn)同一等級結(jié)構中的任意產(chǎn)品。(不能增加新的產(chǎn)品)
工廠模式 :用來生產(chǎn)同一等級結(jié)構中的固定產(chǎn)品。(支持增加任意產(chǎn)品)
抽象工廠 :用來生產(chǎn)不同產(chǎn)品種類的全部產(chǎn)品。(不能增加新的產(chǎn)品,支持增加產(chǎn)品種類)
結(jié)語
使用工廠模式的好時機并不總是顯而易見的。不要強制這樣做,只有在構建復雜系統(tǒng)時才需要進行大量的抽象。你只要知道什么是抽象工廠,遲早你會發(fā)現(xiàn)一個真正的用例。good luck!
寫于2018年5月25日