Проектирование архитектуры классов с различной логикой в разных местах?

Привет, читающим.

Заголовок вопроса немного непонятный, сейчас объясню подробнее.


Есть класс Bullet. У него много разных методов связанных с разными свойствами пули. Возможная траектория падения, определенная логика попадания, определенное поведение в определенный момент времени, разное возможное реагирование на другие пули. И каждое такое свойство довольно сильно может различаться от класса к классу. К сожалению, я сделал все через наследование, т.е. если класс хотел изменить 2 свойства, то он наследовал от главного и изменял их.


После разростания архитектуры появилось довольно много разновидностей Bullet и тут стала очевидна проблема такого подхода. Допустим MagicBullet наследует от Bullet и изменяет логику попадания и взрыва. Есть еще класс SuperBullet наследующий от Bullet и изменяющий только траекторию. А теперь мне потребовался класс, в котором я хочу логику попадания из MagicBullet и логику траектории из SuperBullet. Возникает проблема дублирования кода, ибо Java не поддерживает множественного наследования.


Вопрос такой, как бы должна была выглядеть архитектура в таком случае? Подвопрос — как будет наиболее безболезненно исправить текущую архитектуру?


По поводу первого вопроса у меня пока есть 2 варианта:

1. Использовать стратегии для каждого из отдельных свойств. Вроде бы вариант не плохой, однако он сильно ограничивает логику тем, что по-идее, каждая из стратегий не должна ничего знать о других стратегиях, а часто случается так, что 2 измененных свойства находятся в тесной связи и возможные связи также могут отличаться от случая к случаю.

2. Использовать один класс Bullet и много разных декораторов. Однако, опять же остается вопрос связи разных свойств.
  • Вопрос задан
  • 4153 просмотра
Решения вопроса 1
Zayaz
@Zayaz
Если вы хотите, чтобы наследники класса были независимыми, вам придется сделать их независимыми, даже нарушая DRY.

Если у вас нельзя иерархически выделить подтипы класса Bullet, из которых уже можно сделать потомков с необходимыми свойствами (т.е. сделать, например ExplosiveBullet с разрывом пули и MagicExplosiveBullet, SniperExplosiveBullet, etc — уже с конкретными реализациями), то вам тут никак на Java красиво не выкрутиться.

Если вам просто очень необходимо уйти от текущей реализации, но избавиться от дублирования кода, можете использовать паттерн Mixin, вроде я видел реализацию на Java.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
VenomBlood
@VenomBlood
Выделить специфичное поведение для каждого аспекта в отдельные классы (траектории в одну группу классов, логику попадания в другую, и т.д.), а в классах наследниках bullet просто использовать логику из них.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы