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

寻求100%类型严格的单/批量元素处理设计模式方案

100%类型严格的统一处理方案

要实现你想要的全程单一类型、无类型判断的调用方式,最优雅的做法是使用适配器模式,将原有单元素处理器适配到统一的批量处理接口上,同时让新的批量处理器直接实现这个统一接口。这样就能彻底消除类型分支,保持类型系统的严格性。

核心思路

我们需要定义一个统一的顶层接口,要求所有处理器都能接收list<Element>集合并返回字符串。对于原有只支持单元素处理的策略,我们用适配器类包裹它,把批量处理的逻辑转化为逐个调用原有单元素方法;新的批量处理器则直接实现这个统一接口,原生支持集合处理。

具体实现步骤

1. 定义统一的处理接口

这个接口是所有处理器的契约,明确要求处理list<Element>集合:

interface ElementProcessingStrategyInterface {
    /**
     * @param list<Element> $elements
     */
    public function process(array $elements): string;
}

2. 适配原有单元素处理器

创建适配器类,将原有ProcessingStrategyInterface的实现适配到新的统一接口。适配器内部会遍历元素集合,逐个调用原有单元素处理方法:

class SingleElementProcessorAdapter implements ElementProcessingStrategyInterface {
    public function __construct(
        private ProcessingStrategyInterface $singleProcessor
    ) {}

    /**
     * @param list<Element> $elements
     */
    public function process(array $elements): string {
        // 这里保持和你原有逻辑一致:逐个处理,保留最后一个结果
        $result = '';
        foreach ($elements as $element) {
            $result = $this->singleProcessor->process($element);
        }
        return $result;
    }
}

3. 让批量处理器实现统一接口

你的BatchProcessingStrategyInterface可以直接替换为实现统一接口(或者让它继承统一接口,保留原有方法名)。这里我们直接让批量处理器实现统一接口,保持调用一致性:

class ExampleBatchProcessor implements ElementProcessingStrategyInterface {
    /**
     * @param list<Element> $elements
     */
    public function process(array $elements): string {
        // 你的批量处理逻辑,比如一次性处理所有元素
        $processedValues = array_map(fn(Element $element) => $element->getContent(), $elements);
        return implode('|', $processedValues);
    }
}

4. 改造Listener,使用统一接口

现在Listener只需要持有统一接口的实例,完全不需要类型判断,直接调用统一的process方法:

class SomeListener {
    /**
     * @var array<string, ElementProcessingStrategyInterface>
     */
    protected array $processors;

    // 在依赖注入时完成适配器包装
    public function __construct(
        // 原有单元素处理器
        ProcessingStrategyInterface $legacySingleProcessor,
        // 新的批量处理器
        ElementProcessingStrategyInterface $batchProcessor
    ) {
        // 用适配器包装原有单元素处理器
        $this->processors['legacy-type'] = new SingleElementProcessorAdapter($legacySingleProcessor);
        // 批量处理器直接加入
        $this->processors['batch-type'] = $batchProcessor;
    }

    public function __invoke(DocumentContent $event) {
        /**
         * @var array<string, list<Element>> $elements
         */
        $elementGroups = $event->getDynamicElements();
        foreach ($elementGroups as $type => $elements) {
            $processor = $this->processors[$type];
            // 统一调用,完全类型安全
            $result = $processor->process($elements);
            
            // 后续处理$result的逻辑...
        }
    }
}

为什么这是类型严格的方案?

  • 所有处理器都实现同一个接口,$processors数组的类型提示完全精确,静态分析工具(如PHPStan、Psalm)不会报类型错误。
  • 调用时无需任何instanceof判断,完全符合你想要的统一调用方式。
  • 原有单元素处理器的逻辑被完整保留,通过适配器实现了逻辑复用,没有修改原有代码(开闭原则)。

内容的提问来源于stack exchange,提问作者Zoltán Fekete

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:53:38