Как это сделать без множественного наследования - PullRequest
7 голосов
/ 02 января 2012

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

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

Есть ли лучшая практика для этогов Java?

Я рассматривал промежуточный слой из трех абстрактных классов, между основным абстрактным классом и детьми.Каждый из трех наследует основной абстрактный класс и реализует данный метод.Тогда дети наследуют эти три.Но что мне не нравится в этом, так это то, что если другой метод сопровождается аналогичным поведением «группировки», и он не соответствует трем классам «среднего уровня»?Это было бы ужасно

Есть ли в этом смысл?Я пишу в спешке ...

РЕДАКТИРОВАТЬ: Итак, через 24 часа после того, как задать свой вопрос, я получил около полудюжины шаблонов для расследования.Я еще не уверен, что все они являются официальными именами шаблонов дизайна.Но я собираюсь изучить каждый из них, а затем доложить (и выбрать правильный ответ).До сих пор паттены предлагали:

* Delegation

* Bridge

* Strategy

* Composition

* Decorator (if I was choosing on name alone, I choose this one)

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

Ответы [ 5 ]

7 голосов
/ 02 января 2012

На самом деле, я чувствую запах стратегии здесь.

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

Это, как говорится, здесь есть дополнительные запахи, даже с моим предложенным решением. Возможно, вы захотите думать на более высоком уровне с интерфейсами (как упоминалось другими решениями) и композицией только без наследования. Со временем я пришел к выводу, что наследство НЕ моего друга. В настоящее время я избегаю этого, где это возможно.

6 голосов
/ 02 января 2012

Используйте делегирование, а не наследование.Пусть все классы одной группы делегируются общему вспомогательному объекту для реализации их метода.

3 голосов
/ 02 января 2012

Если вы настаиваете на решении этой проблемы с помощью наследования, здесь может помочь шаблон моста из книги GoF (он может или не может быть идеально подходящим, в зависимости от того, какие проблемы домена приводят к разделению на три реализации). ). Лично я, скорее всего, просто помещу три реализации метода во вспомогательный класс и перенаправлю вызовы методов из классов (то, что JB Nizet правильно называет делегированием).

1 голос
/ 02 января 2012

Сначала рассмотрим замену абстрактного класса интерфейсом.Я не знаю, возможно ли это в вашем случае.

Во-вторых, вы можете удалить функциональность вашего метода "группировки" в другой класс (разработчик).Создайте 3 разных класса с реализацией метода (или только 3 разных метода в некотором классе) и при необходимости вызывайте их из дочерних классов.

Таким образом, метод «группировки» будет определен в каждом дочернем классе, но онпросто явно вызовет одного из 3 возможных разработчиков.

1 голос
/ 02 января 2012

Простое решение для быстрого запуска без использования наследования состояло бы в том, чтобы абстрагировать 3 «общих метода» в другое место, а затем просто повторить вызов метода.

Если вы хотите сделать это хорошим OO способом,затем взгляните на шаблон декоратора, который вполне может помочь: создайте 3 стандартных класса, которые реализуют три выбранных вами метода, а затем «украсьте» их другими классами.

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