PHP实战中知识总结 / 设计模式 - 工厂模式
一、简单工厂模式
又叫静态工厂方法模式
(1)无法灵活的拓展和维护,添加新的功能需要修改原有的代码。
(2)工厂类负责创建的对象较少,客户只知道传入工厂类的参数,对于如何创建对象不关心。
(3)并未严格遵循设计模式的开闭原则,当需要增加新产品时也需要修改工厂代码。
<?php
class AppleDrink{
function getDrinkName()
{
echo '苹果饮料';
}
}
class BananaDrink{
function getDrinkName()
{
echo '香蕉饮料';
}
}
class FruitFactory{
public static function makeDrink($fruit){
if ($fruit == 'apple'){
return new AppleDrink();
}elseif ($fruit == 'banana'){
return new BananaDrink();
}
}
}
$factory = new FruitFactory();
$apple = $factory->makeDrink('apple');
$apple->getDrinkName();
$banana = $factory->makeDrink('banana');
$banana->getDrinkName();
$apple1 = $factory->makeDrink('apple');
$apple1->getDrinkName();
$banana1 = $factory->makeDrink('banana');
$banana1->getDrinkName();
二、工厂方法模式
工厂模式,属于创建型模式,它提供了创建对象的最佳方式,在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
定义一个创建对象的接口,让子类自己决定去实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
工厂模式是一种类,它具有为您创建对象的某些方法,可以使用工厂类创建对象,而不直接使用new,如果需要更改所创建的对象类型,只需要修改工厂类即可。
<?php
interface Drink{
function getDrinkName();
}
class AppleDrink implements Drink{
function getDrinkName()
{
echo '苹果味饮料';
}
}
class BananaDrink implements Drink{
function getDrinkName()
{
echo '香蕉味饮料';
}
}
interface FruitFactory{
function makeDrink();
}
class AppleFactory implements FruitFactory{
function makeDrink()
{
return new AppleDrink();
}
}
class BananaFactory implements FruitFactory{
function makeDrink()
{
return new BananaDrink();
}
}
$appleFactory = new AppleFactory();
$apple = $appleFactory->makeDrink();
$apple->getDrinkName();
$bananaFactory = new BananaFactory();
$banana = $bananaFactory->makeDrink();
$banana->getDrinkName();
当需要增加新的产品时,只需要添加新的工厂类即可,不需要改动原来的代码。
工厂模式,它是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现开闭原则,实现了对扩展开放,对更改关闭。其次实现更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式是对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
三、抽象工厂模式
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
所谓抽象工厂模式就是我们的抽象工厂约定了可以生产的产品,这些产品都包含多种规格,然后我们可以从抽象工厂为每一种规格派生出具体工厂类,然后让这些具体工厂类生产具体的产品。
抽象工厂模式包含如下角色:
(1)AbstractFactory:抽象工厂
(2)ConcreteFactory:具体工厂
(3)AbstractProduct:抽象产品
(4)Product:具体产品
<?php
abstract class AbstractProductA //抽象产品类
{
abstract public function use();
}
class ProductA1 extends AbstractProductA //具体产品类
{
public function use(){
var_dump('productA1');
}
}
abstract class AbstractFactory //抽象工厂类
{
abstract public function createProductA();
}
class ConcreteFactory1 extends AbstractFactory //具体工厂类
{
public function createProductA()
{
return new ProductA1();
}
}
$a=new ConcreteFactory1();
$b=$a->createProductA();
$b->use(); // 打印出string(9) "productA1"
?>
四、三者区别和适用范围
1、区别
(1)简单工厂模式:用来生产同一等级结构中的任意产品。对与增加新的产品,无能为力。
(2)工厂模式:用来生产同一等级结构中的固定产品。(支持增加任意产品)
(3)抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法
2、适用范围
(1)简单工厂模式:工厂类负责创建的对象较少,客户只知道传入工厂类的参数,对于如何创建对象不关心。
(2)工厂方法模式:当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中得某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法模式。
(3)抽象工厂模式:一个系统不应当依赖于产品类实例何如被创建,组合和表达的细节,这对于所有形态的工厂模式都是重要的。这个系统有多于一个的产品族,而系统只消费其 中某一产品族。同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从 而使客户端不依赖于实现。