工厂设计模式与常规抽象类实现的差异咨询
两段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
相关产品推荐
相关产品推荐

