青岛网站建站公司,网址转短链接,培训心得体会2000字,太原做网站的鸣蝉公司引言
在日常开发中#xff0c;我们一些业务场景需要用到发送短信通知。然而实际情况考虑到不同厂商之间的价格、实效性、可能会出现的情况等 我们的业务场景往往会接入多个短信厂商来保证我们业务的正常运行#xff0c;而不同的短信厂商#xff08;如阿里云短信、腾讯云短信…引言
在日常开发中我们一些业务场景需要用到发送短信通知。然而实际情况考虑到不同厂商之间的价格、实效性、可能会出现的情况等 我们的业务场景往往会接入多个短信厂商来保证我们业务的正常运行而不同的短信厂商如阿里云短信、腾讯云短信等提供了不同的接口如果我们要支持多个短信厂商代码中就会充斥着各种 new 操作来创建不同的短信服务实例。
假设在不使用设计模式的情况下我们的代码可能会这样写
?php
// 如果要发送阿里云短信
$aliSms new AliSms();
$aliSms-send($phoneNumber, $message);// 如果要发送腾讯云短信
$tenSms new TencentSms();
$tenSms-send($phoneNumber, $message);这样做的问题是显而易见的
代码耦合度高 每当需要引入新的短信厂商代码中都必须手动创建该厂商的实例导致代码与具体厂商类的耦合度非常高不易维护。扩展性差 如果要增加或替换短信厂商就需要在每个发送短信的地方都修改代码。这不仅增加了出错的风险还降低了代码的可扩展性。不符合开闭原则 代码应该是对扩展开放、对修改封闭的。而上述代码违背了这一原则因为每次增加新厂商时都需要修改已有代码。
为了解决这些问题我们可以引入工厂模式通过一个工厂类来负责短信服务的创建从而实现代码的解耦和易扩展。
工厂模式
工厂模式Factory Pattern是一种创建型设计模式它通过定义一个接口或抽象类将对象的创建过程封装在工厂类中而不是直接在代码中实例化对象。工厂模式的核心思想是通过工厂类来决定实例化哪一个具体类从而使客户端代码不需要关心对象的创建逻辑。
工厂模式的原理
工厂模式的原理是将对象的创建过程封装在一个独立的工厂类中。工厂类通常根据传入的参数或配置信息决定返回哪个具体的类实例。这样一来客户端代码只需要调用工厂类提供的创建方法而不需要直接调用构造函数从而实现对象的创建与客户端的分离。 工厂模式的实现一般包含以下几部分
产品接口或抽象类定义所需的产品类型所有的具体产品类都要实现该接口或继承该抽象类。具体产品类实现或继承产品接口或抽象类代表具体的产品。工厂类封装创建对象的逻辑根据客户端的需求生成并返回对应的产品实例。 工厂模式的示意图
工厂模式的结构通常如下
客户端 —— 工厂类 —— 产品接口/抽象类 —— 具体产品类
这种结构将对象的创建过程从客户端代码中移除交由工厂类处理从而实现了创建与使用的解耦。 工厂模式的适用场景
工厂模式适用于以下几种场景
需要生成多个具有相似特征的对象 如果一个系统中需要创建多个相似的对象且这些对象具有相同的接口或抽象类工厂模式可以将对象的创建集中管理方便后期的扩展。系统的扩展性要求较高 如果一个系统可能会频繁地扩展新功能需要新增类型的对象工厂模式能使新产品的引入变得简单。新增产品时只需要增加一个具体产品类和相应的工厂逻辑而不需要修改原有的客户端代码。隐藏对象的创建逻辑 如果对象的创建过程比较复杂不希望让客户端了解创建细节通过工厂模式可以将创建逻辑封装在工厂类中让客户端只关心如何使用对象而不关心如何创建对象。 工厂模式的实际业务应用场景
多渠道通知发送 在消息通知系统中可能需要支持多种通知渠道比如短信、邮件、微信、Push 推送等。工厂模式可以用于创建不同的通知服务实例帮助根据不同渠道自动生成相应的通知对象使得系统可以方便地切换或扩展新渠道。支付渠道对接 支付系统中通常需要对接多个支付渠道如支付宝、微信支付、PayPal 等。工厂模式可以根据用户的选择或系统配置创建相应的支付实例从而使系统更加灵活方便地接入新支付渠道。数据库连接管理 在复杂应用中可能需要使用多种数据库例如 MySQL、MongoDB、Redis 等来处理不同的数据存储需求。工厂模式可以根据需求创建不同的数据库连接实例使代码解耦并方便地切换或扩展数据库支持。文件解析 系统中需要解析多种文件格式如 JSON、XML、CSV 等时可以使用工厂模式创建对应的解析器对象。例如创建 JSON 解析器或 CSV 解析器按需解析不同格式的文件。日志系统 日志系统中可能会使用多种输出方式比如文件、数据库、远程服务器等。工厂模式可以根据配置创建不同的日志对象以支持多种日志写入方式并能灵活地调整日志输出策略。用户权限管理 对于复杂权限管理系统不同角色可能需要不同的权限实例。工厂模式可以用于根据用户角色创建对应的权限管理对象从而更好地管理和维护权限规则。多语言支持 在多语言应用中不同语言的翻译方式可能不同。工厂模式可以根据语言代码生成对应的翻译服务实例以便于按需加载不同的翻译逻辑。图表生成 在数据可视化系统中可能会支持多种图表类型如柱状图、折线图、饼图等。工厂模式可以用于根据用户选择生成不同的图表对象以便动态生成所需的图表类型。 在代码中使用工厂模式的好处
使用工厂模式带来了多个显著的好处使得代码更加灵活、易维护和可扩展
解耦创建和使用 工厂模式将对象的创建和使用分离使客户端代码无需关心对象的具体实现类也不需要直接创建实例。这种解耦使得代码更灵活便于在不同的情况下切换不同的实现。提高代码的可维护性 工厂模式将对象的创建逻辑集中在工厂类中客户端代码只与工厂类交互。当需要添加新的对象类型或修改对象的创建逻辑时只需更改工厂类而无需修改客户端代码大大减少了出错的风险。符合开闭原则 工厂模式使代码更符合开闭原则对扩展开放对修改封闭。如果需要添加新的产品类只需在工厂类中增加对应的创建逻辑而无需修改现有的客户端代码或其他产品类代码减少了代码的修改需求。增强代码的可扩展性 当需要增加新的产品类型时只需创建一个新的产品类并在工厂类中定义相应的创建逻辑。工厂模式使得扩展新产品变得简单而不需要更改已有代码结构。简化客户端代码 工厂模式将对象创建逻辑封装起来简化了客户端代码使其专注于如何使用对象而不是关心如何创建对象。这使得代码更加清晰和易于理解。
通过这些好处工厂模式让代码具备了更好的结构和维护性尤其适用于需要频繁创建和扩展对象的场景。 工厂模式的类型
在工厂模式中根据需求的不同常见的有三种主要变体简单工厂模式、工厂方法模式和抽象工厂模式。这些模式的主要目标都是将对象的创建与使用解耦但在设计和使用场景上各有不同。
1. 简单工厂模式
简单工厂模式Simple Factory Pattern是工厂模式的基础实现通过一个工厂类的静态方法根据传入的参数来创建并返回不同的产品对象。这种模式使用简单便于理解。
特点通过一个静态方法来创建对象工厂类负责所有产品实例的创建。适用场景适用于产品种类较少、对象创建逻辑简单的场景。缺点违反开闭原则当新增产品时必须修改工厂类系统扩展性较低。
示例代码
class SmsFactory {public static function create($type) {switch ($type) {case Ali:return new AliSms();case Tencent:return new TencentSms();default:throw new Exception(未知短信类型);}}
}2. 工厂方法模式
工厂方法模式Factory Method Pattern为每个产品提供一个具体的工厂类通过实现一个工厂接口负责创建各自的产品。这种方式将工厂类分离符合开闭原则。
特点每个产品类都有一个对应的工厂类通过实现工厂接口来创建具体产品。适用场景适合产品种类多、频繁扩展新产品的情况便于维护。缺点增加了系统的复杂度特别是当产品种类较多时会有大量工厂类。
示例代码
interface SmsFactory {public function create();
}class AliSmsFactory implements SmsFactory {public function create() {return new AliSms();}
}class TencentSmsFactory implements SmsFactory {public function create() {return new TencentSms();}
}3. 抽象工厂模式
抽象工厂模式Abstract Factory Pattern是一种更为复杂的工厂模式用于创建多个相关的产品对象即产品族。每个具体工厂负责创建一组相关的对象从而保证产品族的一致性。
特点可以创建一组相关或相互依赖的对象产品族每个具体工厂实现多个工厂接口负责创建整个产品族。适用场景当系统需要多个相互关联的对象组合时例如支持多平台的 UI 组件库。缺点扩展新产品族较为复杂需要修改或增加多个类。
示例代码
interface SmsAbstractFactory {public function createSms();public function createTemplate();
}class AliSmsFactory implements SmsAbstractFactory {public function createSms() {return new AliSms();}public function createTemplate() {return new AliTemplate();}
}class TencentSmsFactory implements SmsAbstractFactory {public function createSms() {return new TencentSms();}public function createTemplate() {return new TencentTemplate();}
}工厂模式类型的区别与适用场景总结
工厂模式类型特点适用场景缺点简单工厂模式单一工厂类通过静态方法创建对象产品种类少、扩展性需求低不符合开闭原则扩展性差工厂方法模式每个产品对应一个工厂类符合开闭原则产品种类多需支持系统扩展性增加系统复杂度工厂类较多抽象工厂模式可以创建多个相关对象产品族满足复杂对象创建需求需要创建一组相关对象组合产品族扩展复杂类结构较复杂
通过这种对比表格和示例代码读者可以更清晰地了解不同工厂模式的特点与适用场景并能根据项目需求选择合适的工厂模式类型。 回到开头 为了更好地管理多种短信厂商的集成我们可以选择使用工厂模式来设计短信发送逻辑。这样一来我们可以轻松地根据需求切换或添加新的短信厂商而无需修改客户端代码。
设计步骤 定义一个短信接口创建一个 SmsServiceInterface定义发送短信的基本方法比如 send($phoneNumber, $message)。所有的具体短信服务如阿里云、腾讯云都将实现这个接口。 interface SmsServiceInterface {public function send($phoneNumber, $message);
}创建具体的短信服务类为每个短信厂商创建具体实现类比如 AliSmsService 和 TencentSmsService。每个类都实现 SmsServiceInterface 接口包含具体的发送逻辑。 class AliSmsService implements SmsServiceInterface {public function send($phoneNumber, $message) {// 实现阿里云短信的发送逻辑}
}class TencentSmsService implements SmsServiceInterface {public function send($phoneNumber, $message) {// 实现腾讯云短信的发送逻辑}
}创建短信工厂类创建 SmsFactory 类根据传入的厂商类型来决定返回的短信服务实例。这样一来客户端代码就不需要直接实例化具体的短信类而是通过工厂类来获取相应的实例。 class SmsFactory {public static function create($type) {switch ($type) {case Ali:return new AliSmsService();case Tencent:return new TencentSmsService();default:throw new Exception(未知短信类型);}}
}使用工厂类发送短信客户端代码只需调用工厂类的 create() 方法来获取对应的短信实例然后调用 send() 方法即可。这样客户端代码无需关心具体的实现只需使用统一的接口。 $smsService SmsFactory::create(Ali);
$smsService-send($phoneNumber, $message);这样设计的好处
降低耦合性 客户端代码与具体的短信实现解耦通过 SmsFactory 工厂类统一管理不同厂商的实例创建客户端只需知道接口而不需要知道具体实现。提高扩展性 使用工厂模式后如果要接入新的短信厂商如华为云只需增加一个新的实现类如 HuaweiSmsService并在工厂类中添加对应的实例创建逻辑而无需修改客户端代码。符合开闭原则 工厂模式允许我们在不修改客户端代码的情况下扩展新功能增强了代码的灵活性和稳定性。通过简单扩展工厂类我们便可以支持新的厂商或新的短信逻辑。简化维护 所有短信实例的创建都集中在 SmsFactory 中便于管理。若有修改需求例如调整具体厂商的实现逻辑我们只需修改对应的实现类而不必在各处重复更改。
通过这种设计工厂模式让短信发送逻辑更加灵活、可扩展且便于维护为系统增加新的厂商支持变得轻松简单。这不仅提升了代码质量也提高了系统的稳定性。 最后
通过工厂模式我们有效地将对象的创建过程与使用逻辑解耦使系统的扩展性和维护性得到了显著提升。在多厂商短信发送的场景中工厂模式使得不同厂商的短信服务可以通过统一的接口进行调用简化了代码结构。同时工厂模式还符合开闭原则让我们能够在不修改已有代码的前提下轻松地接入新的厂商支持。这样的设计不仅提高了代码的灵活性和可读性也降低了系统的耦合度使项目更易于维护和拓展。
工厂模式在实际开发中应用广泛尤其适用于需要动态生成对象且对象种类较多的场景。通过合理运用工厂模式我们可以更有效地应对业务需求的变化让系统保持稳定、可扩展的同时具备更高的质量。