-
简单工厂模式
定义
定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法
需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道其实现过程
缺点
系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,同样破坏了“开闭原则”;在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
适用环境
- 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
- 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
<?php
/**
* 简单工厂模式
*/
//Factory(工厂类):核心部分,负责实现创建所有People的内部逻辑,工厂类可以被外界直接调用,创建所需对象
//People (抽象产品类):工厂类所创建的所有对象的父类,封装了People对象的公共方法,所有的具体People为其子类对象
//Man、Women(具体产品类):简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象People中声明的抽象方法(有关抽象类)
interface OperationInterface
{
function getVal($a,$b);
}
class OperationAdd implements OperationInterface
{
public function getVal($a, $b)
{
// TODO: Implement getVal() method.
return $a + $b;
}
}
class OperationSub implements OperationInterface
{
public function getVal($a, $b)
{
// TODO: Implement getVal() method.
return $a - $b;
}
}
class Factory
{
private static $instance;
static function operation($op)
{
switch ($op) {
case '+':
self::$instance = new OperationAdd();
break;
case '-':
self::$instance = new OperationSub();
break;
}
return self::$instance;
}
}
$factory = Factory::operation('+');
echo $factory->getVal(1,2);
缺点:若是再增加一个乘法运算,除了增加一个乘法运算类之外,还得去工厂生产方法里面添加对应的case代码,违反了开放-封闭原则。
-
工厂方法模式
<?php
/**
* 工厂方法模式
*/
interface OperationInterface
{
function getVal($a, $b);
}
class OperationAdd implements OperationInterface
{
public function getVal($a, $b)
{
// TODO: Implement getVal() method.
return $a + $b;
}
}
class OperationSub implements OperationInterface
{
public function getVal($a, $b)
{
// TODO: Implement getVal() method.
return $a - $b;
}
}
interface FactoryInterface
{
public function operation();
}
class FactoryAdd implements FactoryInterface
{
public function operation()
{
return new OperationAdd();
}
}
class FactorySub implements FactoryInterface
{
public function operation()
{
return new OperationSub();
}
}
$addFactory = new FactoryAdd();
$add = $addFactory->operation();
echo $add->getVal(1,2);
- 抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂
<?php
/**
* 抽象工厂方法
* 提供一个创建一系列相关或相互依赖对象的接口。
* 注意:这里和工厂方法的区别是:一系列,而工厂方法则是一个。
* 那么,我们是否就可以想到在接口create里再增加创建“一系列”对象的方法呢?
*/
interface PeopleInterface
{
// 走路
function walk();
}
class ManStrong implements PeopleInterface
{
function walk()
{
// TODO: Implement Walk() method.
echo 'ManStrong: walk';
}
}
class ManThin implements PeopleInterface
{
function walk()
{
// TODO: Implement Walk() method.
echo 'Man: walk';
}
}
class WomenStrong implements PeopleInterface
{
function walk()
{
// TODO: Implement walk() method.
echo "WomenStrong: walk";
}
}
class WomenThin implements PeopleInterface
{
function walk()
{
// TODO: Implement walk() method.
echo "WomenThin: walk";
}
}
// 将对象的创建抽象成一个接口。
interface AbstractFactory
{
function createStrong();
function createThin();
}
class FactoryMan implements AbstractFactory
{
function createStrong()
{
return new ManStrong();
}
function createThin()
{
return new ManThin();
}
}
class FactoryWoman implements AbstractFactory
{
function createStrong()
{
return new WomenStrong();
}
function createThin()
{
return new WomenThin();
}
}
$factory = new FactoryMan();
$man = $factory->createStrong();
$man->walk();
区别:
简单工厂模式:用来生产同一等级结构中的任意产品。对与增加新的产品,无能为力
工厂模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法
适用范围:
简单工厂模式:
工厂类负责创建的对象较少,客户只知道传入工厂类的参数,对于如何创建对象不关心。
工厂方法模式:
当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中得某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法模式。
抽象工厂模式:
一个系统不应当依赖于产品类实例何如被创建,组合和表达的细节,这对于所有形态的工厂模式都是重要的。这个系统有多于一个的产品族,而系统只消费其 中某一产品族。同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从 而使客户端不依赖于实现。
无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。究竟用哪种设计模式更适合,这要根据具体的业务需求来决定。
-