什么是工厂方法模式?
用子类来实例化对象,父类只是抽象出公共部分;
举个例子:
两个系统之间通信,需要一种加密方式用来传输数据,目前有两种算法A 和 B用来加密和解密,这样我们需要三个类
1. 用来数据加密传输的数据加密类;
2. 用来数据解密的数据解密类;
2. 用来选择数据加密方式并处理数据的管理类;
代码实现如下所示;
abstract Class DataEncript {
abstract function encript();
}
abstract AEncript extends DataEncript {
function encript(){
return "using A to encript data";
}
}
abstract BEncript extends DataEncript {
function encript(){
return "using B to encript data";
}
}
abstract Class DataDecript {
abstract function decript();
}
abstract ADecript extends DataDecript {
function encript(){
return "using A to decript data";
}
}
abstract BDecript extends DataDecript {
function encript(){
return "using B to decript data";
}
}
class DataManager {
private $mode = 1;
const A_ALGORITHM = 1;
const B_ALGORITHM = 2;
function __construct ($mode) {
$this->mode = $mode;
}
function ChooseEncriptMode ($this->mode) {
switch ($this->mode) {
case A_ALGORITHM :
return new AEncript();
case B_ALGORITHM :
return new BEncript();
default :
return AEncript();
}
}
function ChooseDecriptMode ($this->mode) {
switch ($this->mode) {
case A_ALGORITHM :
return new ADecript();
case B_ALGORITHM :
return new BDecript();
default :
return ADecript();
}
}
}
仔细来看,上面的代码有些冗余,如果不做修改并继续添加一些功能(如输出加密后的信息),重复的代码会越来越多,最终会变得越来越难以维护。
那么我们应该如何修改呢?
我们将数据管理类抽象出来,作为一个抽象父类,特定实现放到子类中实现;
修改后的代码如下所示:
abstract Class DataEncript {
abstract function encript();
}
abstract AEncript extends DataEncript {
function encript(){
return "using A to encript data";
}
}
abstract BEncript extends DataEncript {
function encript(){
return "using B to encript data";
}
}
abstract Class DataDecript {
abstract function decript();
}
abstract ADecript extends DataDecript {
function encript(){
return "using A to decript data";
}
}
abstract BDecript extends DataDecript {
function encript(){
return "using B to decript data";
}
}
abstract DataManager {
abstract function getDataEncript();
abstract function getDataDecript();
}
class ADataManager {
function getDataEncript() {
return new AEncript();
}
function getDataDecript() {
return new ADecript();
}
}
class BDataManager {
function getDataEncript() {
return new BEncript();
}
function getDataDecript() {
return new BDecript();
}
}
在《深入PHP 面向对象、模式与实践中》称DataManager为创造者,ADataManager/BDataManager为产品;
工厂方法模式把创造者类与要生产的产品类分离来。创造者是一个工厂类,其中定义了生成产品对象的类方法。如果没有提供默认实现,那么就有创造者类的子类来执行实例化。一般情况下,就是创造者类的每个子类实例化一个相应产品子类。