ThinkPHP框架使用工厂模式对接多个物流公司下单接口架构示例(php7.0及以上)

对接多个物流公司下单接口和获取物流支持目的地接口,用ThinkPHP框架使用工厂模式写了一个示例,包括如何创建目录及文件命名方式。

首先,我们需要定义一个物流公司的接口(Interface):

// application/Interfaces/LogisticsCompany.php
namespace app\Interfaces;interface LogisticsCompany
{public function placeOrder($orderInfo);public function getSupportedDestinations();
}

然后,为每个具体的物流公司实现这个接口:

// application/Service/Logistics/CompanyA.php
namespace app\Service\Logistics;use app\Interfaces\LogisticsCompany;class CompanyA implements LogisticsCompany
{// 实现下单方法public function placeOrder($orderInfo){// 具体的下单逻辑...}// 实现获取支持目的地方法public function getSupportedDestinations(){// 具体的获取目的地逻辑...}
}// 同样方式为其他物流公司创建类,例如:CompanyB, CompanyC 等

接下来,创建物流服务工厂:

// application/Service/LogisticsFactory.php
namespace app\Service;class LogisticsFactory
{private static $companies = ['company_a' => '\\app\\Service\\Logistics\\CompanyA','company_b' => '\\app\\Service\\Logistics\\CompanyB',// 更多物流公司...];public static function create(string $name): LogisticsCompany{if (!isset(self::$companies[$name])) {throw new \InvalidArgumentException("Invalid logistics company: {$name}");}return new self::$companies[$name]();}
}

最后,在控制器或其他需要调用的地方使用工厂:

// application/controller/YourController.php
namespace app\controller;use app\Interfaces\LogisticsCompany;
use app\Service\LogisticsFactory;class YourController
{public function placeOrderAction(){$logisticsCompany = LogisticsFactory::create('company_a');$orderInfo = []; // 假设这是订单信息$logisticsCompany->placeOrder($orderInfo);// 获取支持的目的地$destinations = $logisticsCompany->getSupportedDestinations();}
}

关于目录及文件命名方式,以上代码已经体现出来了:

  • 应用的核心接口存放于 application/Interfaces 目录下。
  • 物流公司服务的具体实现位于 application/Service/Logistics 目录下,每个物流公司对应一个类文件,如 CompanyA.php、CompanyB.php 等。
  • 工厂类 LogisticsFactory.php 放置于 application/Service 目录下。

为什么interface LogisticsCompany要分开目录?
将 LogisticsCompany 接口放在单独的目录(例如 application/Interfaces)中是为了更好地遵循单一职责原则(SRP)和高内聚低耦合的设计原则。这样做的好处包括:

  1. 代码组织清晰
    接口通常是定义公共契约的地方,它们代表了一组必须实现的方法,但并不涉及具体实现细节。将其与服务的具体实现分开放置,有助于提高代码的可读性和可维护性。
  2. 更好的模块化
    通过将接口单独抽离,可以方便地在不同的模块、层或包之间共享和复用这些接口,而无需关心具体的实现类。这对于大型项目尤其重要,可以减少不同组件之间的直接依赖。
  3. 易于扩展和替换
    当有新的物流公司加入时,只需创建一个新类去实现 LogisticsCompany 接口,并在工厂类中添加相应的映射即可。这使得系统更易于扩展,并且更容易进行单元测试。

当然,在实际项目中,根据项目的规模、团队规范和个人喜好,您完全可以选择将接口放在 Service 目录下,或者使用其他符合团队约定的结构组织代码。关键在于保持代码结构清晰,易读易维护。如果项目较小,接口数量不多,也可以考虑将接口文件置于同一目录,如 application/Service/Interfaces 下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/687072.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速实现用户认证:使用Python和Flask配合PyJWT生成与解密Token的教程及示例代码

生成token 与解密 token 和 拦截器 #学习交流 访问 # https://v.iiar.cnimport jwt import datetime from models import XUser from flask import request, jsonify from functools import wrapsSECRET_KEY XPay# 创建token def generate_token(user_id):try:payload {exp:…

如何在多头自注意力机制的交叉学习中引入对于物理、生理、心理世界客观规律的对照验证...

要在多头自注意力机制的交叉学习中引入对于物理世界客观规律的对照验证,可以考虑以下方法: 1、引入物理模型 首先,建立一个物理模型,该模型能够描述物理世界中的客观规律。这个模型可以是已知的科学理论,也可以是通过实…

Nginx静态内容和反向代理

文章目录 一、Nginx介绍1. 简介2. 相关网站3. 配置文件 二、location说明1. 匹配规则2. 替换匹配部分 三、Nginx代理1. Spring服务代理2. MySQL代理3. MinIO代理 一、Nginx介绍 1. 简介 Nginx(读作“engine x”)是一个高性能的开源HTTP和反向代理服务器…

(2.2w字)前端单元测试之Jest详解篇

Jest Jest 概述 Jest是一个领先的JavaScript测试框架,特别适用于React和Node.js环境。由Facebook开发,它以简单的配置、高效的性能和易用性而闻名。Jest支持多种类型的测试,包括单元测试、集成测试和快照测试,后者用于捕获组件或…

阿里云轻量应用服务器和ECS云服务器区别(官方文档)

阿里云轻量应用服务器和ECS云服务器有啥区别?轻量应用服务器是轻量级服务器,轻量适合个人开发者或中小企业使用,清理使用简单、可视化运维更容易上手;ECS云服务器专业级服务器,适合企业级应用,通用型、计算…

python 将普通文件转换为ts文件,用udp-ts 发送

将普通文件转换为TS文件并使用UDP发送是一个相对复杂的过程,因为你需要遵循TS流的格式来封装原始数据。TS流通常用于封装视频和音频数据,包含固定的包头和负载数据。对于简单的文本或二进制文件,将其转换为TS流并不常见,因为TS是为…

Math--API

Math 数学工具类,提供一些对数据进行操作的静态方法 Math类常用API 方法名说明public static int abs(int a)获取参数绝对值public static double ceil(double a)向上取整public static double floor(double a)向下取整public static int round(f…

Rust 学习笔记 - 注释全解

前言 和其他编程语言一样,Rust 也提供了代码注释的功能,注释用于解释代码的作用和目的,帮助开发者理解代码的行为,编译器在编译时会忽略它们。 单行注释 单行注释以两个斜杠 (//) 开始,只影响它们后面直到行末的内容…

如何在 Angular 中使用 Flex 布局

介绍 Flex Layout 是一个组件引擎,允许您使用 CSS Flexbox 创建页面布局,并提供一组指令供您在模板中使用。 该库是用纯 TypeScript 编写的,因此不需要外部样式表。它还提供了一种在不同断点上指定不同指令以创建响应式布局的方法。 在本教…

多数据源支持

平台倡导分布数据库,最简单的分库逻辑是按业务领域,例如人力资源系统一个库,客户关系管理一个库(举个例子而已,在平台正式的系统中,人力资源系统又细分为核心库、绩效管理库、薪资管理库等)。一…

springboot/ssm公司进销存系统Java商品销售出入库系统

springboot/ssm公司进销存系统Java商品销售出入库系统 开发语言:Java 框架:springboot(可改ssm) vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.7&#x…

基于PPNSA+扰动算子的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于PPNSA扰动算子的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图和优化收敛曲线。 2.测试软件版本以及运行结果展示 MATLAB2022a版本运行…

【JavaScript】面试手写题精讲之数组(上)

专题缘由 该专题主要是讲解我们在面试的时候碰到一些JS的手写题, 确实这种手写题还是比较恶心的。有些时候好不容易把题目写出来了,突然面试官冷不丁来一句有没有更优的解法,直接让我们僵在原地。为了解决兄弟们的这些困扰,这个专题于是就诞…

python入门:常用模块—jsonpickle模块

什么叫序列化? 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes 为什么要序列化? 你打游戏过程中,打累了,停下来,关掉…

随想录刷题笔记 —二叉树篇6 513找树左下角的值 112路径总和 106中序后序构造二叉树

513找树左下角的值 找出该二叉树的 最底层 最左边 节点的值 解法一&#xff1a;队列——层次遍历 class Solution {public int findBottomLeftValue(TreeNode root) {Queue<TreeNode> treeNodes new LinkedList<>();treeNodes.offer(root);int count 1;int re…

贪心算法之合并区间

“任世界多宽广&#xff0c;停泊在这港口~” 区间问题&#xff0c;涉及到最多的就是 取交集 和 并集的概念。我们使用C排序算法后&#xff0c;其默认规则就是按照 “左排序”进行的。因而&#xff0c;我们实质上注意的是每一个区间的 右端点&#xff0c;根据题目要求&#xff…

蓝桥杯:C++模运算、快速幂

模运算 模运算是大数运算中的常用操作。如果一个数太大&#xff0c;无法直接输出&#xff0c;或者不需要直接输出&#xff0c;则可以对它取模&#xff0c;缩小数值再输出。取模可以防止溢出&#xff0c;这是常见的操作。 模是英文mod的音译&#xff0c;取模实际上是求余。 取…

表达式 副作用 序列点

语句分类 标号语句(标签&#xff0c;常与goto配合使用)复合语句(块)表达式语句(赋值表达式语句、函数表达式语句等)选择语句迭代语句(循环)跳转语句(return,break,continue) 其中复合语句(块)可视为单个语句。因此while和for循环之后加的是单个语句(简单语句、复合语句、空语…

树莓派:使用mdadm为重要数据做RAID 1保护

树莓派作为个人服务器可玩性还是有点的。说到服务器&#xff0c;在企业的生成环境中为了保护数据&#xff0c;基本上都会用到RAID技术。比如&#xff0c;服务器两块小容量但高性能的盘做个RAID-1按装操作系统&#xff0c;余下的大容量中性能磁盘做个RAID-5或者RAID-6存放数据。…

网络原理(HTTP篇)

网络原理HTTP 前言HTTPHTTP的工作流程抓包工具抓取HTTP报文HTTP报文格式 请求报文具体细节首行URLURL的基本格式URL encode 方法 报头(header)HostContent-Length 和 Content-TypeUser-Agent&#xff08;UA&#xff09;RefererCookie&#xff08;重要&#xff09; 前言 如图&a…