定义:
定义一个用于创建对象的接口,让子类决定实例化哪一个类, Factory Method 使一个类的实例化延迟到子类。
工厂方法的解决思路很有意思,就是不解决,采取无为而治的方式。
功能:让父类不知道的情况下,完成自身的功能调用;而具体的实现延迟到子类来实现。
实现成抽象类
实现成具体类
工厂方法的参数和返回
谁在使用工厂方法创建对象:
应该是Creator的其他方法在使用工厂方法创建的对象,虽然也可以其创建的对象提供给外部,但工厂方法模式的本意是由Creator对象内部的方法来使用工厂方法创建的对象。
也就是说,工厂方法一般不提供给Creator外部使用。
1.客户端使用Creator对象的情况
abstract class Creator {
abstract function facotryMethod();
/**提供给外部使用的方法*/
public function someOpreration() {
//这里使用工厂方法
$p = $this->facotryMethod();
}
}
2. 客户端使用Creator创建出来的对象
小结:该模式里面,客户端要么使用Creator对象,要么使用Creator创建的对象,一般客户端不直接使用工厂方法。当然了可以暴露,但一般不这么做。
例子:
interface ExportFileApi { public function export($data); } class ExportTextFile implements ExportFileApi { public function export($data) { } } class ExportDbtFile implements ExportFileApi { public function export($data) { } } abstract class ExportOperate { function export($data) { $api = $this->factoryMethod(); $api->exprot($data); } abstract function factoryMethod(); } class ExportTxtFileOprate extends ExportOperate { function factoryMethod() { return new ExportTxtFile(); } } class ExportDBOprate extends ExportOperate { function factoryMethod() { return new ExportDbFile(); } } class Client { public static function main() { $operate = new ExportDBOprate; $operate->export('测试数据'); } }
工厂方法与IoC/DI
ioc 控制反转
DI 依赖注入
工厂方法模式和 IOC/DI 的思想是一样的,都是主动变被动,进行了主从换位。从而获得了灵活的程序结构;
优点:
1.可在不知情的情况下编程
2.更容易扩展对象的新版本
3.连接平行的类层次
缺点:
增加了耦合性
如下情况可以选用工厂方法:
1. 在一个类需要创建某个接口的对象,但是又不知道具体的实现,把创建对象的工作延迟到子类去。
2. 如果一个类本身就是希望由它的子类来创建所需的对象的时候。