Шаблоны проектирования Python: вложенные абстрактные классы - PullRequest
0 голосов
/ 18 сентября 2018

В следующем примере кода я хочу, чтобы каждый объект 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()

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Я хочу, чтобы каждый объект автомобиля состоял из brake_system и engine_system объектов

У вас есть абстрактные классы для систем

class EngineSystem(ABC):
    pass

class BrakeSystem(ABC):
    pass

Автомобиль должен состоять из двух систем:

class Car:

    def __init__(self, engine: EngineSystem, brake: BrakeSystem):
        self._engine_system = engine
        self._brake_system = brake

    @property
    def engine_type(self) -> EngineSystem:
        return self._engine_system

    @property
    def brake_type(self) -> BrakeSystem:
        return self._engine_system

А теперь, если вам нужно создать конкретную машину

tesla = Car(ElectroEngine(), Disks())

# or even 
class Tesla(Car):
    def __init__(self):
        super().__init__(ElectroEngine(), Disks())

tesla = Tesla()

Этот подход позволяет вам создать car как композицию его систем.

0 голосов
/ 19 сентября 2018

Я новичок в python.

Отвечая на ваш вопрос на основе концепций ОО, прекрасно иметь вложенную абстракцию, чтобы заставить реализатор определить, какой внешний класс инкапсулируется.И я не вижу никаких потенциальных проблем в этой структуре.

В вашем примере Car имеет BreakSystem и EngineSystem имеет смысл, когда нужно симулировать сущности реальных слов как программное обеспечение, и в то же время все они очень универсальны, поэтому приемлемо иметь их как абстрактные ипозволяя разработчику определить детали в конкретных классах.

Это также может быть смоделировано, если у вас есть композиция, Пример можно использовать Building и Room в качестве абстрактных типов (где Building состоит из Rooms), и с помощью Flat / House это можно реализовать, если в House / Flat есть такие комнаты, как DiningRoom и / или DrawingRoom и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...