【发布时间】:2018-09-18 01:33:21
【问题描述】:
在下面的示例代码中,我希望每个car 对象都由brake_system 和engine_system 对象组成,它们作为属性存储在汽车上。
为了实现这一点,我将Car、BreakSystem 和EngineSystem 定义为抽象类。 Car 的每个子类都需要将其各自的BreakSystem 和EngineSystem 子类定义为类属性。
这种方法有什么潜在的问题吗?还是有其他更适合处理嵌套抽象的设计模式?
from abc import ABC, abstractmethod
class Car(ABC):
"""
every car object should have an Engine object and a BrakeSystem object
"""
def __init__(self):
self.engine_system = self._engine_type()
self.brake_system = self._brake_type()
@property
@abstractmethod
def _engine_type(self):
raise NotImplementedError()
@property
@abstractmethod
def _brake_type(self):
raise NotImplementedError()
class EngineSystem(ABC):
pass
class BrakeSystem(ABC):
pass
class FooBrakeSystem(BrakeSystem):
pass
class FooEngineSystem(EngineSystem):
pass
class FooCar(Car):
_engine_type = FooEngineSystem
_brake_type = FooBrakeSystem
if __name__ == '__main__':
obj = FooCar()
【问题讨论】:
-
这本身没有问题,但为什么要在这里使用 ABC?为什么通常用于记录公共 API 的 ABC 应该关注汽车的实现细节?引擎和刹车类型是公共 API 信息吗?
-
这不是 ABC 的典型用例吗?我们只希望
car类通过其子类进行初始化,因此我们将其设为 ABC。我还没有编写公共 API,但我仍然经常使用 ABC 来组织相关类的层次结构。 -
不,这不是典型的用途。 ABC 更常用于帮助第三方开发人员了解他们在实现特定“协议”时必须提供的内容,该协议是类上的一组方法,它们共同定义了一种行为模式。查看
collections.abc模块以了解 Python 容器行为的定义。Mapping类的内部实现是什么并不重要,只要它实现了 ABC 的抽象方法,其他代码就可以依赖它来拥有所有正确的方法。
标签: python-3.x oop design-patterns abstract-class