摘要:工厂方法模式面向对象的设计强调抽象类高于实践,尽可能的将代码设计的一般化,而非特殊化也就是降低耦合,提升标准性。于是,前辈们便设计了特定类处理实例化的工厂方法。实现这个时候我们引入工厂方法模式,设置类创造者,类产品,。面向对象设计模式目录
工厂方法模式
面向对象的设计强调“抽象类高于实践”,尽可能的将代码设计的一般化,而非特殊化——也就是降低耦合,提升标准性。于是,前辈们便设计了“特定类处理实例化”的工厂方法。
问题Appointment类需要解析BloggsCal数据格式,在类内部,我们将数据格式写死为BloggsCal,这将会造成耦合,而且实际上,未来业务需求要面临更多的数据格式。
实现这个时候我们引入工厂方法模式,设置CommsManager类(创造者,creater)、ApptEncoder类(产品,Product)。
接下来,用户只需要调用CommsManager对象的getApptEncoder方法,就可以得到他们需要的对象,而无需关注这个对象到底是哪种数据格式。
abstract class ApptEncoder { abstract function encode(); } class BloggsApptEncoder extends ApptEncoder { function encode() { return "数据格式为BloggsCal。"; } } class MegaApptEncoder extends ApptEncoder { function encode() { return "数据格式为MegaCal。"; } } class CommsManager { const BLOGGS = 1; const MEGA = 2; private $mode = 1; function __construct( $mode ) { $this->mode = $mode; } function getApptEncoder() { switch ( $this->mode ) { case ( self::MEGA ) : return new MegaApptEncoder(); default: return new BloggsApptEncoder(); } } function getHeaderText() { switch ( $this->mode ) { case ( self::MEGA ): return "Mega格式的表头"; default: return "BloggsCal格式的表头"; } } function getFootText() { switch ( $this->mode ) { case ( self::MEGA ): return "Mega格式的脚页"; default: return "BloggsCal格式的脚页"; } } } $comms = new CommsManager( CommsManager::MEGA ); $apptEncoder = $comms->getApptEncoder(); echo $apptEncoder->encode();
注意到CommsManager类的三个getXXX方法了吗?
一旦数据格式增多、功能增加、数据格式间存在业务差异,就会造成一个新问题:大量的判断语句——包括我自己在内的一些人认为,这是代码腐烂的象征。
至少,当重复的代码开始蔓延,我们不应该感到乐观。(尽管下面的处理方法,在一定程度上也重复了这个错误)
面对上述难题,我们有了下列三条要求:
在代码运行时,才能了解我们要生成的对象类型(实时传参,注意那句:$comms = new CommsManager( CommsManager::MEGA ));
相对轻松的加入新数据格式(Product);
每个产品类型都能轻松加入订制化功能。
既然如此,我们干脆将 数据格式们 从CommsManager中剥离出来,形成多带带的子类。
// 产品抽象类、子类的代码,同上。 abstract class CommsManager { abstract function getApptEncoder(); abstract function getHeaderText(); abstract function getFooterText(); } class BloggsCommsManager extends CommsManager { function getApptEncoder() { return new BloggsApptEncoder(); } function getHeaderText() { return "BloggsCal格式的表头"; } function getFooterText() { return "BloggsCal格式的脚页"; } } class MegaCommsManager extends CommsManager { function getApptEncoder() { return new MegaApptEncoder(); } function getHeaderText() { return "MegaCal格式的表头"; } function getFooterText() { return "MegaCal格式的脚页"; } } $comms = new BloggsCommsManager(); $apptEncoder = $comms->getApptEncoder(); echo $apptEncoder->encode();结果
这样满足了上述的三个要求,可我想,聪明的你已经注意到了:一定程度上,创建者/产品们 产生了代码重复。而且,问题被转移到了工厂方法中,我们目前只是处理了Appointment功能,如果我们加入TodoList功能呢?
答案很明显,我们需要:可以同时处理一组相关实现的架构,解决之道就在下一篇文章:抽象工厂模式。
(面向对象设计模式 - 目录)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/22553.html
摘要:所以,也要慎用当你的项目中,产品越来越多,创建者的数量也随之臃肿,下一篇将介绍抽象工厂方法的变体原型模式,这种模式可以减少必须创建的类。 抽象工厂方法模式 在工厂方法模式中,我们通过中间件的方式,形成了以下格式的分离: 使用者 ↓创建者 ↓具体产品 问题 这样,我们无论怎样修正具体产品,都不会影响使用者。现在,我们可以做出来一群小工厂,他们有各自的产品,但形成了模式层面的重复,那么...
摘要:我们今天也来做一个万能遥控器设计模式适配器模式将一个类的接口转换成客户希望的另外一个接口。今天要介绍的仍然是创建型设计模式的一种建造者模式。设计模式的理论知识固然重要,但 计算机程序的思维逻辑 (54) - 剖析 Collections - 设计模式 上节我们提到,类 Collections 中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了...
摘要:原型模式平行的继承层次使用工厂模式在大型设计中,必须去维护大量的产品类。上文中,称之为特殊的耦合在这里我们介绍一种其抽象工厂模式的变体原型模式。面向对象设计模式目录 原型模式 平行的继承层次使用工厂模式在:大型设计中,必须去维护大量的产品类。(上文中,称之为特殊的耦合) 在这里我们介绍一种其抽象工厂模式的变体:原型模式。它使用clone关键词,来复制具体产品类,使得具体产品类能完成自我...
摘要:系列目录生成对象的模式面向对象的之模式单例面向对象的之模式工厂方法面向对象的之模式抽象工厂方法面向对象的之模式原型组合类对象的模式面向对象的之模式组合更新装饰模式 系列目录 生成对象的模式 【面向对象的PHP】之模式:单例 【面向对象的PHP】之模式:工厂方法 【面向对象的PHP】之模式:抽象工厂方法 【面向对象的PHP】之模式:原型 组合类/对象的模式 【面向对象的PHP】之模式...
阅读 4282·2021-10-13 09:39
阅读 483·2021-09-06 15:02
阅读 3230·2019-08-30 15:53
阅读 1042·2019-08-30 13:04
阅读 2036·2019-08-30 11:27
阅读 2013·2019-08-26 13:51
阅读 2096·2019-08-26 11:33
阅读 2904·2019-08-26 10:36