工厂模式:负责生成其他类的对象。(常用的模式有,一个类通过本身的静态方法来实例化一个类并返回对象)
概要:工厂模式可以将对象的生产从直接new 一个对象,改成通过调用一个工厂方法生产。这样的封装,代码若需修改new的对象时,不需修改多处new语句,只需更改生产对象方法。
下面是一个计算器的例子
// 抽象运算类
abstract class Operation
{
abstract public function getVal($i, $j); // 抽象方法不能包含方法体
}
// 加法类
class OperationAdd extends Operation
{
public function getVal($i, $j)
{
return $i + $j;
}
}
// 减法类
class OperationSub extends Operation
{
public function getVal($i, $j)
{
return $i - $j;
}
}
//计数器工厂
class CounterFactor
{
private static $operation;
// 工厂生产特定类对象方法
public static function createOperation(string $operation)
{
switch ($operation) {
case '+': self::$operation = new OperationAdd;
break;
case '-': self::$operation = new OperationSub;
break;
}
return self::$operation;
}
}
$counter = CounterFactor::createOperation('+');
echo $counter->getVal(1, 2);
缺点:若是再增加一个乘法运算,除了增加一个乘法运算类之外,还得去工厂生产方法里面添加对应的case代码,违反了开放-封闭原则。
解决方法(1):通过传入指定类名
// 计算器工厂
class CounterFactor
{
// 工厂生产特定类对象方法
public static function createOperation(string $operation)
{
return new $operation;
}
}
class OperationMul extends Operation
{
public function getVal($i, $j)
{
return $i * $j;
}
}
$counter = CounterFactor::createOperation('OperationMul');
解决方法(2):通过抽象工厂模式
// 抽象运算类
abstract class Operation
{
abstract public function getVal($i, $j); //抽象方法不能包含方法体
}
// 加法类
class OperationAdd extends Operation
{
public function getVal($i, $j)
{
return $i + $j;
}
}
// 乘法类
class OperationMul extends Operation
{
public function getVal($i, $j){
return $i * $j;
}
}
// 抽象工厂类
abstract class Factor
{
abstract static function getInstance();
}
// 加法器生产工厂
class AddFactor extends Factor
{
// 工厂生产特定类对象方法
public static function getInstance()
{
return new OperationAdd;
}
}
// 减法器生产工厂
class MulFactor extends Factor
{
public static function getInstance()
{
return new OperationMul;
}
}
// 文本输入器生产工厂
class TextFactor extends Factor
{
public static function getInstance() {}
}
$mul = MulFactor::getInstance();
echo $mul->getVal(1, 2);
第一种方法,是个典型的工厂模式,在整个代码中,只有一个工厂,在这个工厂中,可以根据你的需要,生成需要的对象并返回使用。第二种方法,它是有多个工厂,但是每个工厂只负责生成自己的对象,和第一个种方法不同,但是结果是异曲同工的。