如何运用OOP思想避免产品类型判断中的if/else与switch语句
重构实现方案
核心借助面向对象的多态特性替换分支判断:把不同产品的差异化展示逻辑拆分到独立的产品类中,对外暴露统一的调用入口,从根源上移除针对产品类型的if/switch判断。
1. 定义统一产品接口
先给所有产品约定统一的行为规范,保证不管是什么类型的产品,对外都提供相同的方法供外部调用,调用方不需要感知具体产品类型。
<?php interface Product { // 强制所有产品类实现属性渲染方法 public function renderAttribute(): string; }
2. 编写各类型产品的具体实现类
每个产品类独立维护自己的属性拼接、渲染逻辑,类之间完全解耦。后续新增产品类型时只需要新增对应的类,不需要修改已有代码,符合开闭原则。
<?php // DVD产品类 class DVD implements Product { private float $size; // 传入原始产品数据初始化实例 public function __construct(array $productRaw) { $this->size = $productRaw['size']; } public function renderAttribute(): string { return "<p>Size: {$this->size}MB</p>"; } } // 家具产品类 class Furniture implements Product { private string $dimentions; public function __construct(array $productRaw) { $this->dimentions = $productRaw['dimentions']; } public function renderAttribute(): string { return "<p>Dimentions: {$this->dimentions}</p>"; } } // 书籍产品类 class Book implements Product { private float $weight; public function __construct(array $productRaw) { $this->weight = $productRaw['weight']; } public function renderAttribute(): string { return "<p>Weight: {$this->weight}Kg</p>"; } }
3. 编写无分支的产品实例工厂
用数组映射代替条件判断,维护产品类型标识和对应类名的映射关系,传入产品类型直接匹配对应的类实例化,全程没有if/switch语句。
<?php class ProductFactory { // 产品类型和类名的映射表,新增产品仅需在此追加配置 private const TYPE_CLASS_MAP = [ 'DVD' => DVD::class, 'Furniture' => Furniture::class, 'Book' => Book::class, ]; public static function build(array $productRaw): Product { $className = self::TYPE_CLASS_MAP[$productRaw['product_type']]; return new $className($productRaw); } }
4. 业务层调用
最终业务调用逻辑非常简洁,没有任何针对产品类型的条件判断:
<?php // $product 为原始的产品数据数组 $productInstance = ProductFactory::build($product); echo $productInstance->renderAttribute();
方案优势
- 完全满足要求:针对产品类型的处理逻辑全程没有使用if/else、switch等条件分支语句
- 易维护:新增产品类型不需要修改现有业务逻辑,仅需新增对应产品类、在工厂映射表追加一行配置即可,不会影响原有功能
- 低耦合:每个产品类只负责自身的属性渲染逻辑,职责边界清晰
内容的提问来源于stack exchange,提问作者Asifur Rahman
相关产品推荐
相关产品推荐

