php开发的设计模式,PHP进阶教程-设计模式之抽象工厂模式
php开发的设计模式,PHP进阶教程-设计模式之抽象工厂模式产品结构图表格描述例如:工厂方法模式就是一家公司只生产一种产品,抽象工厂模式一家公司生产多种产品。抽象工厂模式中存在四种角色,分别是抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。在本文例子表示从接口上来看跟工厂方法模式是不是有点像呢?没错他们就是很像,只不过工厂方法一个工厂仅针对一个产品,而抽象工厂模式一个工厂对应多个产品。
抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构;而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。
UML图
该模式中包含的角色及其职责
抽象工厂模式中存在四种角色,分别是抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。
- 抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
- 具体工厂角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
- 抽象产品角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
- 具体产品角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
在本文例子表示
从接口上来看跟工厂方法模式是不是有点像呢?没错他们就是很像,只不过工厂方法一个工厂仅针对一个产品,而抽象工厂模式一个工厂对应多个产品。
例如:工厂方法模式就是一家公司只生产一种产品,抽象工厂模式一家公司生产多种产品。
产品结构图表格描述
在这里阿里和腾讯分别是两家不同的公司,但是他们都有拥有多个产品。
主要解决的问题
抽象工厂模式的一个主要功能是它能够隔离要生成的具体产品类, 由于这些类的实际类名部被隐藏在工厂内部,因此客户端根本不需要关心如何对它们进行实例化的细节。每种设计模式都是针对特定问题的解决方案,而抽象工厂模式面临的问题则是当涉及到有多个产品等级结构寸,如何更好地进行软件体系结构的设计。
优缺点
优点
- 具体产品在应用层代码隔离,调用者无需知道具体实现,只要知道工厂和产品接口就可以了
- 将一个系列的产品统一到一起创建
- 分离具体实现类,调用者通过抽象类或者接口操作实例。
缺点
- 难以支持新种类的产品,规定了所有可能被创建的产品集合,如果工厂接口,或者产品接口改变所有涉及到的类都需要进行修改
- 增加了系统的抽象性和理解难度
- 代码过于臃肿,如果产品过多需要添加很多类文件
使用场景
- 一个系统要独立于它的产品的创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 需要强调一系列相关的产品对象的设计以便进行联合使用时。
- 提供一个产品类库,而只想显示它们的接口而不是实现时。
- 适合使用在产品不常变比较固定的情况。
- 支付接口SDK开发,把多家api接口统一成自己的SDK方法。
- 跨平台应用皮肤适配,在Windows一套样式、Mac一套样式。
示例代码
CompanyInterface.php
interface CompanyInterface
{
public function Pay();
public function Im();
}
Alibaba.php
class Alibaba implements CompanyInterface
{
public function Pay()
{
return new Alipay();
}
public function Im()
{
return new Wangwang();
}
}
Tencent.php
class Tencent implements CompanyInterface
{
public function Pay()
{
return new WechatPay();
}
public function Im()
{
return new Wechat();
}
}
PayInterface.php
interface PayInterface
{
public function paying();
public function transfer();
}
Alipay.php
class Alipay implements PayInterface
{
public function paying()
{
echo "使用支付宝付款\n";
}
public function transfer()
{
echo "使用支付宝转账\n";
}
}
WechatPay.php
class WechatPay implements PayInterface
{
public function paying()
{
echo "使用微信付款\n";
}
public function transfer()
{
echo "使用微信转账\n";
}
}
ImInterface.php
interface ImInterface
{
public function text();
public function video();
}
Wangwang.php
class Wangwang implements ImInterface
{
public function text()
{
echo "使用旺旺发送文本消息\n";
}
public function video()
{
echo "使用旺旺发送视频消息\n";
}
}
Wechat.php
class Wechat implements ImInterface
{
public function text()
{
echo "使用微信发送文本消息\n";
}
public function video()
{
echo "使用微信发送视频消息\n";
}
}
调用代码:
$alibaba = new Alibaba();
$alibaba->Pay()->paying();//调用支付宝付款方法
$alibaba->Pay()->transfer();//调用支付宝转账方法
$alibaba->Im()->text();//调用旺旺文本聊天方法
$alibaba->Im()->video();//调用旺旺视频聊天方法
echo "--------------华丽分割线--------------\n";
$tencent = new Tencent();
$tencent->Pay()->paying();//调用微信支付付款方法
$tencent->Pay()->transfer();//调用微信支付转账方法
$tencent->Im()->text();//调用微信文本聊天方法
$tencent->Im()->video();//调用微信视频聊天方法
输出内容:
使用支付宝付款
使用支付宝转账
使用旺旺发送文本消息
使用旺旺发送视频消息
--------------华丽分割线--------------
使用微信付款
使用微信转账
使用微信发送文本消息
使用微信发送视频消息
文章看再多不如亲手敲代码,只有自己写过多代码才是吸取精髓。
如果觉得文章还不错,请把文章分享给更多的人学习,在文章中发现有误的地方也希望各位指出更正。现有误的地方也希望各位指出更正。
IT不是挨踢