2012-03-07 8 views
2

Существует абстрактный класс под названием AbstractAgent, и в настоящее время существует 27 классов, которые расширяют этот класс.Наследование Java или статический метод

Я начал разработку некоторых агентов, и все мои 5 агентов расширяют класс AbstractAgent.

Теперь я заметил, что есть getFilePath(), который я копирую во всех моих агентах. Тогда я понял, что из существующих 27 классов также было много классов, у которых был этот метод. Я подумал, что было бы неплохо поместить этот метод в базовый класс AbstractAgent и позволить всем использовать этот метод. Но я не хочу, чтобы все существующие классы меняли свой код. Я изменил имя метода, чтобы каждый мог его использовать.

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

Я не уверен в его аргументе. Кто-то хочет передать свои мысли.

+1

imho, это плохой аргумент, я поддерживаю рефакторинг. –

ответ

3

Если метод getFilePath() точно так же для всех подклассов AbstractAgent «s, то все средства идут вперед и тянуть его до абстрактного класса (использовать инструменты рефакторинга вашего среды IDE), удалите его из подклассов затем запустить блок тесты (вы do имеют модульные тесты, верно?) и убедитесь, что все работает нормально.

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

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

Определение статического метода в классе полезности (скажем, FileUtil) имеет смысл только в том случае, если метод напрямую не связан с функциональностью классов Агента, или если метод может быть полезен в какой-либо другой части объекта иерархия, не связанная напрямую с агентами.

+0

Функция метода getFilePath() одинакова во всех классах – user977263

3

Добавление общей логики к родительскому классу является одной из сильных сторон абстрактных классов, и такое дополнение является перекрестно совместимым изменением. Если, конечно, вы не знаете о некоторых применениях этого класса, и ваш недавно добавленный метод имеет то же имя. Но даже тогда, если подкласс перезаписывает такой метод, будет вызываться его собственный метод, поэтому он по-прежнему является передовым совместимым изменением.

+0

Делает смысл. Это связано с моими мыслями. – user977263

+0

Не правда в целом. Разрешение перегрузки может быть легко проблемой и нарушить совместимость. «К сожалению, мы добавили функцию, и теперь ваш код вызывает неправильную функцию» - отличный способ подружиться с клиентами вашей библиотеки. – Voo

+0

+1 к этой линии мысли , Добавление перегруженного метода не должно нарушать совместимость. В худшем случае сценарий вы даете ему другое имя, а затем оно *** определенно *** не нарушает совместимость в обратном направлении. – Perception

5

В этом случае, поскольку AbstractAgent класса уже используются другими классами, и, как вы упомянули себя НЕ всех классы реализацией этого метода, то вы должны действительно НЕ изменить AbstractAgent. Однако вы можете расширить AbstractAgent в другом абстрактном подклассе, который называется «AbstractAgentWithFilePath», в котором объявляется этот дополнительный метод, а затем эти классы расширяют класс AbstractAgentWithFilePath.

+0

Это хорошее решение, но создавая еще одну иерархию классов только для одного метод не имеет смысла для меня. AbstractAgent - это нечто стандартное, и все будут расширять этот класс. Попросить их использовать AbstractAgentWithFilePath немного сложно. Но логично, что вы правы. – user977263

+1

Мне это нравится, за исключением того, что он может быть подвергнут критике за введение нового класса в иерархию, полностью основанную на том, что, вероятно, является незначительным методом полезности. Ну что ж. –

0

Если метод тесно связан с классами Агента, поместите его внутри абстрактного, это хороший вариант, но если это не так, поместите его в другой класс утилиты, который обрабатывает все действия, связанные с Файлом, будут приемлемыми.

0

Здесь нет правильного ответа.Только вы, ваши коллеги и ваша компания знаете, как и где используется AbstractAgent, и как его изменение влияет на различные команды, отделы или клиентов. Решения о том, где найти код, часто более политичны и социальны, чем обусловлены выбором «чистой комнаты».

С точки зрения сугубо кодов я поддерживаю радикальный рефакторинг: избавляйтесь от ВСЕХ дубликатов кода во всех подклассах ALLActent ALL и перемещайте всех в новый getFilePath() в AbstractAgent.

Но у вас может не быть полномочий для этого, и вы можете получить pushback. Или, может быть, getFilePath() иногда немного меняется (вы не совсем поняли об этом). В этом случае любой выбор, который вы делаете, кажется компромиссом. Ваш рецензент кода может отталкиваться от 'getFilePath2()' в AbstractAgent, потому что он проливает свет на проблему несовершенного повторного использования кода и чувствует, что он «загрязняет» суперкласс временным обходным путем тем, что действительно нужно решить, на сегодняшний день с действительно общим общим кодом в суперклассе. Кто знает.

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

Смежные вопросы