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

工厂设计模式与常规抽象类实现的差异咨询

两段PHP代码的差异解析(涉及抽象类、接口与设计模式)

你正在学习工厂设计模式、抽象类与接口时遇到了两段功能看似类似的PHP代码,下面详细解析它们的核心差异:

第一段代码:工厂方法模式实现

这段代码是工厂方法模式的典型实现,用于封装对象的创建逻辑:

<?php

abstract class AbstractClass {
    abstract public function from(): Product;

    function callClass(){
        return $this->from()->operation();
    }
}

class ClassA extends AbstractClass {
    public function from(): Product{
        return new ProductA();
    }
}

class ClassB extends AbstractClass {
   public function from(): Product{
        // 注:此处应为new ProductB(),属于代码笔误
        return new ProductA();
    }
}

interface Product {
    function operation(): string;
}

class ProductA implements Product {
    function operation(): string{
        return 'from product A';
    }
}

class ProductB implements Product {
    function operation(): string{
        return 'from product B';
    }
}

class ClientCode {
    function operate(AbstractClass $abstractClass){
        return $abstractClass->callClass();
    }
}

$code = new ClientCode();
$classA = new ClassA();
$c = $code->operate(new ClassB());
echo $c;

核心逻辑

  • 定义Product接口规范所有产品的行为;
  • 抽象类AbstractClass作为抽象工厂,声明创建产品的抽象方法from(),同时提供通用方法callClass()调用产品的业务逻辑;
  • 具体工厂类ClassA/ClassB负责实例化具体产品;
  • 客户端依赖抽象工厂,通过工厂间接获取并使用产品,无需直接实例化产品类。

第二段代码:模板方法模式简化实现

这段代码是模板方法模式的简化实现,用于固定流程、复用逻辑:

<?php

abstract class AbstractClass1 {
    abstract protected function getValue();

    function printValue(){
        echo $this->getValue();
    }
}

class ConCreteClassA extends AbstractClass1 {
    function getValue(){
        return 'from Concrete Class A';
    }
}

class ConCreteClassB extends AbstractClass1 {
    function getValue(){
        return 'from Concrete Class B';
    }
}

class ClientCode {
    function doSomething(AbstractClass1 $abs){
        return $abs->printValue();
    }
}

$clientCode = new ClientCode();
$result = $clientCode->doSomething(new ConCreteClassB());
echo $result;

核心逻辑

  • 抽象类AbstractClass1定义了流程骨架printValue()(模板方法),同时声明可变步骤的抽象方法getValue();
  • 具体子类ConCreteClassA/ConCreteClassB只需要实现getValue()提供具体数据;
  • 客户端依赖抽象类,调用模板方法即可执行完整流程,流程逻辑由抽象类统一控制。

两者的核心差异

1. 所属设计模式类型不同

  • 第一段:创建型模式,核心目标是封装对象的创建过程,将产品实例化的逻辑延迟到子类,解耦对象创建与使用;
  • 第二段:行为型模式,核心目标是固定算法/流程的骨架,让子类填充可变步骤,复用流程逻辑。

2. 依赖结构与职责划分不同

  • 第一段:包含两层抽象(抽象工厂类+产品接口),工厂类专注于创建产品,产品类专注于业务操作,职责分离清晰;
  • 第二段:只有一层抽象(抽象类),抽象类既定义流程骨架,又依赖子类实现细节,更侧重于流程复用。

3. 使用场景不同

  • 第一段:适用于需要动态切换产品实例的场景,比如不同业务场景需要不同的产品实现,新增产品只需添加对应工厂类和产品类,符合开闭原则;
  • 第二段:适用于流程固定但步骤细节可变的场景,比如报表生成、数据导出等流程固定,但具体数据来源不同的场景,子类只需修改特定步骤即可复用整个流程。

4. 抽象机制的使用不同

  • 第一段:同时使用抽象类(定义工厂规范)和接口(定义产品规范),严格区分工厂与产品的职责边界;
  • 第二段:仅使用抽象类,没有接口,抽象方法为protected,仅用于子类给父类提供数据,不对外暴露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:34:56