Реализация простого дизайна ООП с композицией классов (Python) - PullRequest
0 голосов
/ 13 февраля 2019

Я изучаю шаблоны проектирования и лучшие практики , особенно по состав класса ( см. Мой старый вопрос ).У меня есть конкретный пример , где мне было очень сложно реализовать хороший ООП проект для.


Простой (?) Пример:

Произнесите концепцию гаража, в котором находятся автомобили, и позвоните во внешнюю службу, чей ответ дает информацию о каждом автомобиле, имеющемся в гараже.

Это пример ответа, который я хочу записать и создать классы для:

[{'carID': '1x148i-36y5-5rt2',
          'carDimensions': {'top': 275,
                            'left': 279,
                            'width': 75,
                            'height': 75},
          'carAttributes': {'weight': {'weightLevel': 'medium',
                                       'value': 1.6},
                            'topSpeed': {'sppedLevel': 'good',
                                      'value': 0.7},
                            'noise': {'noiseLevel': 'low',
                                      'value': 0.32},
                            'accessories': [{'optionsLevel': 'poor',
                                             'quality': 2.8}]}},
  {'carID': '223a3-33e5-4ea3',
          'carDimensions': {'top': 241,
                            'left': 234,
                            'width': 71,
                            'height': 65},
          'carAttributes': {'weight': {'weightLevel': 'light',
                                       'value': 1.1},
                            'topSpeed': {'sppedLevel': 'great',
                                      'value': 1.6},
                            'noise': {'noiseLevel': 'high',
                                      'value': 0.97},
                            'accessories': [{'optionsLevel': 'great',
                                             'quality': 3.2}]}}]

Ниже приведен мой подход к проектированию классов.

Я попытался создать класс Carкоторый извлекает каждое поле следующим образом:

class `Car`:

    def __init__(self, car_response_dictionary):
        self.car = car_response_dictionary

    def get_carID(self):
        return self.car.get("carID")

    # etc.

и другой класс для обработки некоторых вычислений на основе carDimensions:

class Size:

    def __init__(self, top, left, width, height):
        self.top = top
        self.left = left
        self.width = width
        self.height = height

    def get_coordinates(self):
        bottom = self.left + self.height
        right = self.top + self.width
        return (self.left, self.top), (bottom, right)

и класс для захвата концепции гаража, которыйсодержит список Car объектов:

class Garage:

    def __init__(self, datestamp, cars):
        self.datestamp = datestamp
        self.cars = cars

    # do stuff based on cars

Итак, моя идея состоит в том, чтобы создать экземпляр Garage и получить список ответов в cars, я пытаюсь распаковать каждую машину какCar объект экземпляра путем итерации по списку cars словарей и -использования композиции класса - создайте экземпляр Car для каждого автомобиля.

На данный момент я считаю невозможным реализовать свой дизайн на Python иЯ думаю, что, возможно, виноват подход в моем дизайне или мое плохое понимание состава классов.

Если бы кто-то мог предоставить простую реализацию кода для приведенного выше примера, это было бы очень полезно для меня,Даже если это означает, что предлагается новый дизайн (например, я собирался создать класс Response).

1 Ответ

0 голосов
/ 13 февраля 2019

Ниже приведены несколько классов и «основной», который использует композицию (используя класс Size в качестве элемента данных класса Car).

#
# Note that the code does not use 'dict' as an argument for the Car __init__
# but it can be easily modified and use dict as input
#
class Car:
    def __init__(self, id, weight, top_speed, noise, size):
        self.id = id
        self.weight = weight
        self.top_speed = top_speed
        self.noise = noise
        self.size = size

    def get_id(self):
        return self.id

    def __str__(self):
        return 'id: {} weight: {} top speed: {}  noise: {} size: {}'.format(self.id, self.weight, self.top_speed,
                                                                        self.noise,
                                                                        self.size)


class Size:
    def __init__(self, top, left, width, height):
        self.top = top
        self.left = left
        self.width = width
        self.height = height

    def get_coordinates(self):
        bottom = self.left + self.height
        right = self.top + self.width
       return (self.left, self.top), (bottom, right)

    def __str__(self):
        return '[top: {} left: {} width: {} height: {}]'.format(self.top, self.left, self.width, self.height)


class Garage:
    def __init__(self):
       self.cars_holder = {}

    def add_car(self, car):
        self.cars_holder[car.get_id()] = car

    def remove_car(self, car_id):
        del self.cars_holder[car_id]

    def show_cars(self):
        for car in self.cars_holder.values():
            print(car)


GARAGE_AS_DICT = [{'id': '1x148i-36y5-5rt2',
                   'dimensions': {'top': 275,
                                  'left': 279,
                                  'width': 75,
                                  'height': 75},
                   'attrs': {'weight': 12,
                             'top_speed': 0.7,
                             'noise': 0.45
                             }},
                  {'id': '223a3-33e5-4ea3',
                   'dimensions': {'top': 241,
                                  'left': 234,
                                  'width': 71,
                                  'height': 65},
                   'attrs': {'weight': 12,
                             'top_speed': 0.74,
                             'noise': 0.4345
                             }
                   }]

if __name__ == "__main__":
    garage = Garage()
    for dict_car in GARAGE_AS_DICT:
        attrs = dict_car['attrs']
        dimensions = dict_car['dimensions']
        garage.add_car(Car(dict_car['id'], attrs['weight'], attrs['top_speed'], attrs['noise'],
                       Size(dimensions['top'], dimensions['left'], dimensions['width'], dimensions['height'])))

    garage.show_cars()

Вывод:

id: 223a3-33e5-4ea3 weight: 12 top speed: 0.74  noise: 0.4345 size: [top: 241 left: 234 width: 71 height: 65]
id: 1x148i-36y5-5rt2 weight: 12 top speed: 0.7  noise: 0.45 size: [top: 275 left: 279 width: 75 height: 75]
...