工厂模式:
1. 特点:
工厂模式其实是一种类,为您提供一些创建对象的方法,通过该工厂可以,方便的创建不同的对象,不用去new,如果需要更改创建对象的类型,直接修改该工厂类即可,很好的遵循了开闭原则及单一责任原则等。
2. 分类:
根据抽象程度不同,分为,简单工厂模式、工厂方法模式、抽象工厂模式。
1)简单工厂模式(静态工厂方法模式)
a.类图
b. 代码案例:
/**
* 操作类
* 因为包含有抽象方法,所以类必须声明为抽象类
*/
abstract class Operation{
abstract public function getValue($num1,$num2);
}
/**
* 加法类
*/
class OperationAdd extends Operation {
public function getValue($num1,$num2){
return $num1+$num2;
}
}
/**
* 减法类
*/
class OperationSub extends Operation {
public function getValue($num1,$num2){
return $num1-$num2;
}
}
/**
* 乘法类
*/
class OperationMul extends Operation {
public function getValue($num1,$num2){
return $num1*$num2;
}
}
/**
* 除法类
*/
class OperationDiv extends Operation {
public function getValue($num1,$num2){
try {
if ($num2==0){
throw new Exception("除数不能为0");
}else {
return $num1/$num2;
}
}catch (Exception $e){
echo "错误信息:".$e->getMessage();
}
}
}
/**
* 工程类,主要用来创建对象
* 功能:根据输入的运算符号,工厂就能实例化出合适的对象
*
*/
class Factory{
public static function createObj($operate){
switch ($operate){
case '+':
return new OperationAdd();
break;
case '-':
return new OperationSub();
break;
case '*':
return new OperationSub();
break;
case '/':
return new OperationDiv();
break;
}
}
}
$test=Factory::createObj('/');
$result=$test->getValue(23,10);
echo $result;
c.适用情况:工厂类负责创建的对象较少, 客户只需知道创建对象时传入的参数,无需知道如何创建对象。
2)工厂方法模式:
a.类图
b代码示例:
/*
*定义一个创建对象的接口,让子类决定哪个类实例化。
*解决简单工厂模式中的封闭开放原则问题。
*/
abstract class Operation{
abstract public function getValue($num1,$num2);
}
/**
* 加法类
*/
class OperationAdd extends Operation {
public function getValue($num1,$num2){
return $num1+$num2;
}
}
/**
* 减法类
*/
class OperationSub extends Operation {
public function getValue($num1,$num2){
return $num1-$num2;
}
}
/**
* 乘法类
*/
class OperationMul extends Operation {
public function getValue($num1,$num2){
return $num1*$num2;
}
}
/**
* 除法类
*/
class OperationDiv extends Operation {
public function getValue($num1,$num2){
try {
if ($num2==0){
throw new Exception("除数不能为0");
}else {
return $num1/$num2;
}
}catch (Exception $e){
echo "错误信息:".$e->getMessage();
}
}
}
// 此时将对象的创建抽象成一个接口。
abstract class Factory {
abstract function create();
}
class FactoryAdd extends Factory{
function create() {
return new OperationAdd;
}
}
class FactorySub extends Factory {
function create() {
return new OperationSub;
}
}
class FactoryMul extends Factory{
function create(){
return new OperationMul;
}
}
class FactroyDiv extends Factory{
function create (){
return new OperationDiv;
}
}
//客户端代码测试
class Client {
// 简单工厂里的静态方法
function test() {
$Factory = new FactoryAdd;
$res = $Factory->create();
echo $res->getValue(19,23).'<br>';
$Factory = new FactroyDiv;
$res = $Factory->create();
echo $res->getValue(23,22).'<br>';
}
}
$f = new Client;
$f->test();
c.适用情况:当所创建的对象有较多,且将类的实例化交给子类实现。这种方式很好的符合了开闭原则。
3) 抽象工厂模式:
提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。该模式为一个产品族提供了 统一的创建接口。当需要这个产品族的某一系列的时候,可以为此系列的产品族创建一个具体的工厂类。
a.类图:
b.代码实现:
<?php
//抽象工厂
interface AnimalFactory {
public function createCat();
public function createDog();
}
//具体工厂
class BlackAnimalFactory implements AnimalFactory {
function createCat(){
return new BlackCat();
}
function createDog(){
return new BlackDog();
}
}
class WhiteAnimalFactory implements AnimalFactory {
function createCat(){
return new WhiteCat();
}
function createDog(){
return new WhiteDog();
}
}
//抽象产品
interface Cat {
function Voice();
}
interface Dog {
function Voice();
}
//具体产品
class BlackCat implements Cat {
function Voice(){
echo '黑猫喵喵……';
}
}
class WhiteCat implements Cat {
function Voice(){
echo '白猫喵喵……';
}
}
class BlackDog implements Dog {
function Voice(){
echo '黑狗汪汪……';
}
}
class WhiteDog implements Dog {
function Voice(){
echo '白狗汪汪……';
}
}
//test case
class Client {
public static function main() {
self::run(new BlackAnimalFactory());
self::run(new WhiteAnimalFactory());
}
public static function run(AnimalFactory $AnimalFactory){
$cat = $AnimalFactory->createCat();
$cat->Voice();
$dog = $AnimalFactory->createDog();
$dog->Voice();
}
}
Client::main();
?>
c.适用情况:
1>一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
2>这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
3> 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
4>系统提供一个产品类的库,所有的产品以同样的接口出现,从而使用客户端不依赖于实现
d.优缺点
好处:增加或替换产品族容易,分离了具体的类,利于产品的一致性。
不足:新的产品族扩展不易。