PHP设计模式—工厂模式之工厂方法模式
程序员文章站
2022-04-23 21:49:26
定义: 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 代码实例: 这里还是接着上篇简单工厂模式的那个例子,改成工厂方法模式。 1、创建一个抽象类 ApptEncoder /** * 抽象类 * Class ApptEncoder */ a ......
定义:
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
代码实例:
这里还是接着上篇简单工厂模式的那个例子,改成工厂方法模式。
1、创建一个抽象类 apptencoder
/** * 抽象类 * class apptencoder */ abstract class apptencoder { abstract public function encode(); }
2、创建 bloggscal 格式处理类
/** * bloggscal 格式处理类 * class bloggsapptencoder */ class bloggsapptencoder extends apptencoder { public function encode() { // todo: implement encode() method. return "appointment data encoded in bloggscal format\n"; } }
3、创建 megacal 格式处理类
/** * megacal 格式处理类 * class megaapptencoder */ class megaapptencoder extends apptencoder { public function encode() { // todo: implement encode() method. return "appointment data encoded in megacal format\n"; } }
4、创建工厂抽象类 commsmanager
/** * 工厂抽象类 * class commsmanager */ abstract class commsmanager { abstract public function getheadertext(); abstract public function getapptencoder(); abstract public function getfootertext(); }
5、创建 bloggscal 工厂类
/** * bloggscal 工厂类 * class bloggscommsmanager */ class bloggscommsmanager extends commsmanager { public function getheadertext() { // todo: implement getheadertext() method. return "bloggscal header\n"; } public function getapptencoder() { // todo: implement getapptencoder() method. return new bloggsapptencoder(); } public function getfootertext() { // todo: implement getfootertext() method. return "bloggscal footer\n"; } }
6、创建 megacal 工厂类
/** * megacal 工厂类 * class megacommsmanager */ class megacommsmanager extends commsmanager { public function getheadertext() { // todo: implement getheadertext() method. return "megacal header\n"; } public function getapptencoder() { // todo: implement getapptencoder() method. return new megaapptencoder(); } public function getfootertext() { // todo: implement getfootertext() method. return "megacal footer\n"; } }
7、调用:
// 如果要换成 megacal 格式处理,直接换成 $mar = new megacommsmanager() 就可以了 $mgr = new bloggscommsmanager(); print $mgr->getheadertext(); print $mgr->getapptencoder()->encode(); print $mgr->getfootertext();
8、结果:
bloggscal header appointment data encoded in bloggscal format bloggscal footer
总结:
1、使用工厂方法模式,如果需要新增一种格式处理,就不需要修改原有的工厂类了,只需要为这些抽象类实现新的子类即可。这样整个工厂和产品体系其实都没有修改的变化,而只是扩展的变化,这就符合了“开放-封闭原则”。
2、工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要加功能,本来修改工厂类,而现在是修改客户端。
3、工厂方法模式的缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。