You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PieClass与ClassModel场景中应用适配器模式?

用适配器模式解决PieClass与ClassModel的数据格式兼容问题

咱们先把问题拆解清楚:

  • PieClass::setData() 要求传入的 $data 是每个元素都带id属性的对象数组,它会把这些对象按id作为键重新整理成数组。
  • ClassModel::data() 返回的是依赖注入的模型查询结果,这个结果的格式大概率和PieClass要求的不匹配(比如可能是Eloquent集合、关联数组,或者是没有id属性的自定义对象)。

适配器模式的核心就是做一个"格式转换器",把ClassModel的输出转换成PieClass能识别的格式,同时不用修改原有两个类的代码(符合开闭原则)。下面是具体实现步骤:

1. 定义适配器接口(可选但推荐)

先定义一个统一的适配器接口,规范适配器需要提供的功能,方便后续扩展不同类型的模型适配器:

interface PieDataAdapterInterface
{
    /**
     * 返回PieClass能接受的格式化数据
     * @return object[] 每个元素带id属性的对象数组
     */
    public function getFormattedData(): array;
}

2. 实现具体的模型适配器

创建一个针对ClassModel的适配器类,它接收ClassModel实例,负责把模型查询结果转换成PieClass需要的格式。这里假设ClassModel返回的是关联数组(如果是其他格式,调整转换逻辑即可):

class ClassModelToPieAdapter implements PieDataAdapterInterface
{
    private $classModel;

    public function __construct(ClassModel $classModel)
    {
        $this->classModel = $classModel;
    }

    public function getFormattedData(): array
    {
        // 先获取ClassModel的原始数据
        $rawData = $this->classModel->data();
        
        // 把原始数据转换成PieClass需要的带id属性的对象数组
        $formattedData = [];
        foreach ($rawData as $item) {
            // 如果原始是关联数组,转成stdClass对象;如果是对象但没有id,就给它加id属性
            $obj = is_array($item) ? (object)$item : $item;
            
            // 确保对象有id属性(如果原始数据的id字段叫其他名字,比如'uid',这里可以映射)
            if (!property_exists($obj, 'id')) {
                $obj->id = $obj->uid; // 示例:如果原始id字段是uid,这里做映射
            }
            
            $formattedData[] = $obj;
        }

        return $formattedData;
    }
}

3. 实际使用适配器

现在就可以通过适配器把ClassModel的数据传给PieClass了,完全不用修改原有两个类的代码:

// 1. 实例化模型(比如Eloquent模型)
$userModel = new UserModel(); // 假设这是依赖注入的任意模型

// 2. 实例化ClassModel
$classModel = new ClassModel($userModel);

// 3. 用适配器转换格式
$adapter = new ClassModelToPieAdapter($classModel);
$formattedData = $adapter->getFormattedData();

// 4. 传给PieClass的setData方法
$pieClass = new PieClass();
$pieClass->setData($formattedData);

为什么这是适配器模式?

  • 目标接口:PieClass的setData方法要求的数据格式就是我们的目标。
  • 适配者:ClassModel是我们需要适配的现有类,它的输出不符合目标要求。
  • 适配器:ClassModelToPieAdapter就是中间层,把适配者的输出转换成目标接口能接受的格式。

这种方式的好处是:如果后续换了其他模型,只需要新增对应的适配器类实现PieDataAdapterInterface即可,原有代码完全不用改动,扩展性很强。

内容的提问来源于stack exchange,提问作者Karabah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:02:02