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

如何遵循开闭原则重构Python停车场Building类的__init__方法

解决方案

要实现符合开闭原则的设计,核心是把Size枚举与对应的Spot子类建立关联,让Building的初始化逻辑无需依赖硬编码的枚举判断。以下是两种可行的改造方式:

方式一:给Size枚举添加关联类属性

直接在枚举成员中绑定对应的Spot子类,通过自定义枚举的__new__方法让每个枚举实例携带车位类信息:

from enum import Enum

class Size(Enum):
    SMALL = 1, SmallSpot
    MEDIUM = 2, MediumSpot
    LARGE = 3, LargeSpot

    def __new__(cls, value, spot_class):
        obj = object.__new__(cls)
        obj._value_ = value
        obj.spot_class = spot_class  # 绑定对应的车位类
        return obj

class Spot:
    def __init__(self, id) -> None:
        self.id = id
        self.vehicle = None

class SmallSpot(Spot):
    pass  # 无额外逻辑可简化写法

class MediumSpot(Spot):
    pass

class LargeSpot(Spot):
    pass

class Building:
    def __init__(self, dic: dict[Size, int]) -> None:
        # 用统一字典存储所有类型的车位列表,避免零散的实例变量
        self.spot_groups = {}
        for size, count in dic.items():
            # 直接通过枚举获取对应车位类,生成实例列表
            self.spot_groups[size] = [size.spot_class(i) for i in range(count)]
        
        # 如果需要兼容原有代码的small_spot_list等属性,可额外赋值
        self.small_spot_list = self.spot_groups.get(Size.SMALL, [])
        self.medium_spot_list = self.spot_groups.get(Size.MEDIUM, [])
        self.large_spot_list = self.spot_groups.get(Size.LARGE, [])

方式二:维护枚举与车位类的映射字典

如果不想修改枚举的构造逻辑,可以单独维护一个映射字典,将Size枚举与Spot子类一一对应:

from enum import Enum

class Size(Enum):
    SMALL = 1
    MEDIUM = 2
    LARGE = 3

class Spot:
    def __init__(self, id) -> None:
        self.id = id
        self.vehicle = None

class SmallSpot(Spot):
    pass

class MediumSpot(Spot):
    pass

class LargeSpot(Spot):
    pass

# 维护枚举与车位类的映射,新增类型时只需在这里添加条目
SIZE_SPOT_MAP = {
    Size.SMALL: SmallSpot,
    Size.MEDIUM: MediumSpot,
    Size.LARGE: LargeSpot
}

class Building:
    def __init__(self, dic: dict[Size, int]) -> None:
        self.spot_groups = {}
        for size, count in dic.items():
            spot_class = SIZE_SPOT_MAP[size]
            self.spot_groups[size] = [spot_class(i) for i in range(count)]
        
        # 兼容原有属性(可选)
        self.small_spot_list = self.spot_groups.get(Size.SMALL, [])
        self.medium_spot_list = self.spot_groups.get(Size.MEDIUM, [])
        self.large_spot_list = self.spot_groups.get(Size.LARGE, [])

改造优势

  • 新增停车位类型时,只需要:
    1. 新增一个继承自Spot的子类(如XLargeSpot)
    2. 在Size枚举中添加对应成员(方式一),或在映射字典中添加条目(方式二)
  • 完全无需修改Building类的__init__方法,符合开闭原则(对扩展开放,对修改关闭)
  • 用统一字典管理车位列表,后续查询、操作不同类型车位时更灵活

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:16:11