工廠模式分為簡單工廠模式刚陡,工廠方法模式和抽象工廠模式陆盘,它們都屬于設(shè)計模式中的創(chuàng)建型模式舷蟀。其主要功能都是幫助我們把對象的實例化部分抽取了出來恤磷,目的是降低系統(tǒng)中代碼耦合度,并且增強了系統(tǒng)的擴展性野宜。本文對這三種模式進行了介紹并且分析它們之間的區(qū)別扫步。
簡單工廠模式
簡單工廠模式最大的優(yōu)點在于實現(xiàn)對象的創(chuàng)建和對象的使用分離,將對象的創(chuàng)建交給專門的工廠類負責(zé)匈子,但是其最大的缺點在于工廠類不夠靈活河胎,增加新的具體產(chǎn)品需要修改工廠類的判斷邏輯代碼,而且產(chǎn)品較多時虎敦,工廠方法代碼邏輯將會非常復(fù)雜游岳。
<?php
//簡單工廠方法
interface People
{
public function say();
}
class Man implements People
{
public function say()
{
echo 'this is a man ';
}
}
class Women implements People
{
public function say()
{
echo 'this is a women';
}
}
class SimpleFactory
{
public static function create($name)
{
if ($name == 'man') {
return new Man();
} elseif ($name == 'women') {
return new Women();
}
}
}
//具體調(diào)用
$man = SimpleFactory::create('man');
$man->say();
$women = SimpleFactory::create('women');
$women->say();
簡單工廠模式最大的優(yōu)點在于實現(xiàn)對象的創(chuàng)建和對象的使用分離,將對象的創(chuàng)建交給專門的工廠類負責(zé)其徙,但是其最大的缺點在于工廠類不夠靈活胚迫,增加新的具體產(chǎn)品需要修改工廠類的判斷邏輯代碼,而且產(chǎn)品較多時唾那,工廠方法代碼將會非常復(fù)雜访锻。
工廠方法模式
此模式中,通過定義一個抽象的核心工廠類通贞,并定義創(chuàng)建產(chǎn)品對象的接口朗若,創(chuàng)建具體產(chǎn)品實例的工作延遲到其工廠子類去完成。這樣做的好處是核心類只關(guān)注工廠類的接口定義昌罩,而具體的產(chǎn)品實例交給具體的工廠子類去創(chuàng)建哭懈。當系統(tǒng)需要新增一個產(chǎn)品是,無需修改現(xiàn)有系統(tǒng)代碼茎用,只需要添加一個具體產(chǎn)品類和其對應(yīng)的工廠子類遣总,使系統(tǒng)的擴展性變得很好睬罗,符合面向?qū)ο缶幊痰拈_閉原則。體代碼如下:
<?php
//工廠方法模式
interface People
{
public function say();
}
class Man implements People
{
public function say()
{
echo 'this is a man';
}
}
class Women implements People
{
public function say()
{
echo 'this is a women';
}
}
//與簡單工廠模式相比旭斥。區(qū)別在于容达,此處將對象的創(chuàng)建抽象成一個接口
interface CreatePeople
{
public function create();
}
class FactoryMan implements CreatePeople
{
public function create()
{
return new Man();
}
}
class FactoryWomen implements CreatePeople
{
public function create()
{
return new Women();
}
}
class Client
{
// 具體生產(chǎn)對象并執(zhí)行對象方法測試
public function test() {
$factory = new FactoryMan();
$man = $factory->create();
$man->say();
$factory = new FactoryWomen();
$man = $factory->create();
$man->say();
}
}
// 執(zhí)行
$demo = new Client();
$demo->test();
工廠方法模式是簡單工廠模式的進一步抽象和推廣。由于使用了面向?qū)ο蟮亩鄳B(tài)性垂券,工廠方法模式保持了簡單工廠模式的優(yōu)點花盐,而且克服了它的缺點。在工廠方法模式中菇爪,核心的工廠類不再負責(zé)所有產(chǎn)品的創(chuàng)建算芯,而是將具體創(chuàng)建工作交給子類去做。這個核心類僅僅負責(zé)給出具體工廠必須實現(xiàn)的接口凳宙,而不負責(zé)產(chǎn)品類被實例化這種細節(jié)熙揍,這使得工廠方法模式可以允許系統(tǒng)在不修改工廠角色的情況下引進新產(chǎn)品。
抽象工廠模式
提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口氏涩,而無須指定它們具體的類届囚。抽象工廠模式又稱為Kit模式,屬于對象創(chuàng)建型模式是尖。
此模式是對工廠方法模式的進一步擴展意系。在工廠方法模式中,一個具體的工廠負責(zé)生產(chǎn)一類具體的產(chǎn)品析砸,即一對一的關(guān)系昔字,但是,如果需要一個具體的工廠生產(chǎn)多種產(chǎn)品對象首繁,那么就需要用到抽象工廠模式了。
<?php
interface TV{
public function open();
public function watch();
}
class HaierTv implements TV
{
public function open()
{
echo "Open Haier TV <br>";
}
public function watch()
{
echo "I'm watching TV <br>";
}
}
interface PC{
public function work();
public function play();
}
class LenovoPc implements PC
{
public function work()
{
echo "I'm working on a Lenovo computer <br>";
}
public function play()
{
echo "Lenovo computers can be used to play games <br>";
}
}
abstract class Factory{
abstract public static function createPc();
abstract public static function createTv();
}
class ProductFactory extends Factory
{
public static function createTV()
{
return new HaierTv();
}
public static function createPc()
{
return new LenovoPc();
}
}
$newTv = ProductFactory::createTV();
$newTv->open();
$newTv->watch();
$newPc = ProductFactory::createPc();
$newPc->work();
$newPc->play();
在上面的Factory抽象類中陨囊,定義了兩個抽象方法弦疮,這兩個抽象方法分別用來生產(chǎn)不同的產(chǎn)品(即由不同類實例化的對象)。
工廠方法模式和抽象工廠模式對比
通過以上代碼:我們來對比一下工廠方法模式和抽象工廠模式:
- 工廠方法模式中
當我需要多生產(chǎn)一種新的產(chǎn)品蜘醋,比如factoryKid這個產(chǎn)品胁塞,我需要專門再設(shè)一個factoryKid的工廠,即添加如下代碼:
class Kid implements People{
public function say()
{
echo 'this is a kid';
}
}
class FactoryKid implements CreatePeople
{
public function create()
{
return new Kid();
}
}
- 抽象工廠模式中
同樣當我需要多生產(chǎn)一種新的產(chǎn)品压语,比如生產(chǎn)一個iphone,此時我需要修改工廠父類里的接口啸罢,并且在具體工廠類ProductFactory這個工廠里增加一條createPhone生產(chǎn)線(即類里面的方法),所需添加的代碼如下:
interface Phone{
public function work();
public function sms();
}
class IPhone implements Phone
{
public function work()
{
echo "I'm iphone <br>";
}
public function sms()
{
echo "this is an iphone <br>";
}
}
//在原來的抽象工廠類中添加方法聲明
abstract class Factory{
abstract public static function createPc();
abstract public static function createTv();
abstract public static function createPhone();
}
//在原來的工廠類里添加一個方法
class ProductFactory extends Factory
{
public static function createTV()
{
return new HaierTv();
}
public static function createPc()
{
return new LenovoPc();
}
public static function createPhone()
{
return new IPhone();
}
}
從上面的分析可以看出胎食,要生產(chǎn)一個新的產(chǎn)品扰才,抽象工廠模式并不比工廠方法模式更為便捷,那么抽象工廠模式的好處在哪呢?它優(yōu)點就是在于是增加固定類型產(chǎn)品的不同具體工廠比較方便厕怜,比如我要增加一個生產(chǎn)同樣類型產(chǎn)品的具體工廠Product2Factory衩匣,那么就再建一個Product2Factory類繼承Factory就可以了蕾总。
最后的最后,總結(jié)一下工廠方法模式和抽象工廠模式的核心區(qū)別
- 工廠方法模式利用繼承琅捏,抽象工廠模式利用組合
- 工廠方法模式產(chǎn)生一個對象生百,抽象工廠模式產(chǎn)生一族對象
- 工廠方法模式利用子類創(chuàng)造對象,抽象工廠模式利用接口的實現(xiàn)創(chuàng)造對象