如何用OOP将多组异构API响应数组转换为统一标准格式?
使用OOP统一不同API响应数组格式的实现方案
这是个非常典型的异构数据归一化场景,用OOP的适配器模式来处理再合适不过了——既可以把每个API的转换逻辑封装得整整齐齐,又能轻松扩展新的API,还能避免写一堆杂乱的if-else判断。下面给你具体的实现步骤(以PHP为例,匹配你给出的数组风格):
第一步:定义统一的转换接口
先创建一个接口,确保所有转换器都遵循相同的方法约定,这样调用方不需要关心具体实现细节:
interface BrandDataConverterInterface { /** * 将原始API响应数组转换为统一格式 * @param array $rawData 原始API返回的数组 * @return array 统一格式的数组:['brand' => string, 'cnt' => int] */ public function convert(array $rawData): array; }
第二步:为每个API实现对应的适配器
针对你给出的三种API响应格式,分别创建独立的适配器类,每个类只负责处理一种格式的转换:
处理Adidas风格的响应(brand_name + item_count)
class AdidasApiConverter implements BrandDataConverterInterface { public function convert(array $rawData): array { return [ 'brand' => $rawData['brand_name'] ?? '', 'cnt' => $rawData['item_count'] ?? 0 ]; } }
处理Nike风格的响应(brand_name + count_item)
class NikeApiConverter implements BrandDataConverterInterface { public function convert(array $rawData): array { return [ 'brand' => $rawData['brand_name'] ?? '', 'cnt' => $rawData['count_item'] ?? 0 ]; } }
处理Reebok风格的响应(name + count_all)
class ReebokApiConverter implements BrandDataConverterInterface { public function convert(array $rawData): array { return [ 'brand' => $rawData['name'] ?? '', 'cnt' => $rawData['count_all'] ?? 0 ]; } }
第三步:(可选)创建工厂类简化调用
如果需要根据API类型自动获取对应的转换器,可以加一个工厂类,这样调用方不用手动实例化各个适配器,代码更简洁:
class ConverterFactory { public static function getConverter(string $apiType): BrandDataConverterInterface { return match($apiType) { 'adidas' => new AdidasApiConverter(), 'nike' => new NikeApiConverter(), 'reebok' => new ReebokApiConverter(), default => throw new InvalidArgumentException("Unsupported API type: $apiType") }; } }
第四步:实际使用示例
// 模拟不同API的返回数据 $adidasData = ['brand_name' => 'Adidas', 'item_count' => 24]; $nikeData = ['brand_name' => 'Nike', 'count_item' => 254]; $reebokData = ['name' => 'Reebok', 'count_all' => 342]; // 使用工厂获取转换器并转换 $normalizedAdidas = ConverterFactory::getConverter('adidas')->convert($adidasData); // 输出:['brand' => 'Adidas', 'cnt' => 24] $normalizedNike = ConverterFactory::getConverter('nike')->convert($nikeData); // 输出:['brand' => 'Nike', 'cnt' => 254] $normalizedReebok = ConverterFactory::getConverter('reebok')->convert($reebokData); // 输出:['brand' => 'Reebok', 'cnt' => 342]
为什么这个方案好用?
- 单一职责:每个适配器只负责处理一种API格式的转换,逻辑清晰,出问题了也好定位。
- 扩展性强:如果以后新增一个API,只需要新增一个实现
BrandDataConverterInterface的适配器类,再在工厂类里加一行匹配规则即可,完全不用修改现有代码(符合开闭原则)。 - 可读性高:调用方只需要知道API类型,就能拿到统一格式的数据,不用关心底层的键名映射细节。
内容的提问来源于stack exchange,提问作者Dr. Alexander
相关产品推荐
相关产品推荐

