Рекомендации ООП, когда один объект нуждается в изменении другого

(это среда, похожая на C) Скажем, у меня есть два экземпляра объекта, автомобиль и bodyShop. Автомобиль имеет цветной iVar и соответствующие аксессуары. В bodyShop есть метод с именем "paintCar", который принимает объект автомобиля и меняет его цвет.

Что касается реализации, то для того, чтобы bodyShop мог реально изменять цвет объекта автомобиля, я вижу два способа сделать это.

  1. Используйте оператор "&", чтобы передать указатель на автомобиль. Затем bodyShop может либо сказать машине, чтобы она выполняла какой-то метод, чтобы он изменил цвет, либо он может напрямую использовать принадлежность автомобиля.

  2. Передайте объект car по значению, сделайте то же самое, чтобы изменить цвет, затем попросите метод вернуть объект car с новым цветом. Затем назначьте оригинальный автомобильный объект новому автомобильному объекту.

Вариант 1 кажется мне более простым, но мне интересно, соответствует ли он лучшим методикам ООП. В общем случае для "максимального ООП" оператор "&" хорош или плох? Или, может быть, я полностью упускаю лучший вариант, который сделал бы этот супер OOPer. Пожалуйста, порекомендуйте:)

8 ответов

Вариант 1 является предпочтительным:

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

Еще лучше... создать интерфейс IPaintable. У Автомобиля реализовать IPaintable. Пусть BodyShop зависит от IPaintable вместо Car. Преимущества этого:

  • Теперь BodyShop может рисовать все, что реализует IPaintable (Автомобили, Лодки, Самолеты, Скутеры)
  • BodyShop больше не тесно связан с автомобилем.
  • BodyShop имеет более тестируемый дизайн.

Я бы предположил, что ответственность BodyShop состоит в том, чтобы модифицировать автомобильные объекты, поэтому #1 кажется правильным путем для меня. Я никогда не использовал язык, где необходим оператор "&". Обычно мой объект bodyShop будет вызывать car.setColor(newColor), и это будет так. Таким образом, вам не нужно беспокоиться об остальных атрибутах оригинального автомобиля, включая проблемы с сохранением - вы просто оставляете их в покое.

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

Учитывая это, вариант 2 менее желателен, так как вы не можете определить, какие другие объекты содержат ссылки на исходный автомобиль или, что еще хуже, содержат автомобиль. Короче говоря, вы нарушаете ограничение идентичности, поскольку два объекта в системе могут иметь разные представления о состоянии автомобиля. Вы рискуете сделать всю систему несовместимой.

Конечно, ваша конкретная среда может этого избежать, но, безусловно, было бы лучше избегать этого.

Последний пункт, имеет ли ваш объект bodyShop состояние; поведение и личность? Я понимаю, что вы объяснили только необходимый минимум, но, возможно, bodyShop на самом деле не является объектом.


Функциональные подходы

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

Это может звучать как полное излишество, но оно имеет некоторые интересные последствия для доказательства правильности кода и параллелизма.

Вариант 1 выигрывает для меня. Оператор & неявно присутствует во многих ОО-языках (таких как Java, Python и т. Д.). В этих языках часто не используется "передача по значению" - таким образом передаются только примитивные типы.

Вариант 2 сопряжен с несколькими проблемами: у вас может быть коллекция автомобилей, и некоторые функции, не подозревая об этом, могут отправить автомобиль в bodyShop для покраски, получить новую машину взамен и не обновлять вашу коллекцию автомобилей. Увидеть? И с более идеологической точки зрения - вы не создаете новый объект каждый раз, когда хотите изменить его в реальном мире, - почему вы должны делать это в виртуальном? Это приведет к путанице, потому что это просто нелогично.:-)

Я не уверен, что означает это "C-подобное окружение". В C вам нужно это:

int paintCar(const bodyShop_t *bs, car_t *car);

где вы изменяете содержание, указанное автомобилем. Для большой структуры в C вы всегда должны передавать указатель, а не значение в функцию. Итак, используйте решение 1 (если под "&" вы подразумеваете оператор C).

Я тоже согласен с первым 1. Я не могу сказать, что это лучшая практика, потому что я никогда не уверен, что такое лучшая практика в умах других людей... Я могу сказать вам, что лучшая практика в моем уме - это самый простой метод, который работает на работу. Я также видел этот подход, принятый в API-интерфейсе winspell win и других c-ish api, которые мне приходилось использовать. Так что да, я согласен со Скоттом.

http://hunspell.sourceforge.net/

// на всякий случай, если вы заинтересованы в просмотре кода других людей

Это зависит от того, может ли метод кузовного цеха выйти из строя и оставить машину в неопределенном состоянии. В этом случае вам лучше работать с копией автомобиля или копией всех соответствующих атрибутов автомобиля. Затем, только когда операция прошла успешно, вы копируете эти значения в машину. Таким образом, вы заканчиваете тем, что присваиваете новый автомобиль старому в рамках метода кузовного цеха. Правильное выполнение этого необходимо для обеспечения безопасности исключений в C++ и может стать неприятным.

Также возможно, а иногда желательно использовать другой шаблон - возвращение нового объекта при модификации. Это полезно для интерактивных систем, которые требуют Undo/Redo, поиска с возвратом назад, и для всего, что связано с моделированием, как система объектов развивается с течением времени.

В дополнение к другим вариантам, опция 1 позволяет методу paintCar возвращать код завершения, который указывает, успешно ли автомобиль изменил цвет или были проблемы с ним

Другие вопросы по тегам