Вызывать внешние (т.е. интерфейсные) функции также внутренне? - PullRequest
2 голосов
/ 13 апреля 2009

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

Под общедоступными функциями я подразумеваю все методы / функции, которые вы явно создали для вызова из других объектов, модулей и т. Д. Например, методы, которые вы обычно добавляете в определение интерфейса Java. Под внутренним вызовом я имею в виду тот же модуль, класс и т. Д.

Я всегда чувствовал об этом как о "неправильном использовании" публичных методов, хотя я не могу придумать какой-либо веской технической причины не делать этого.

Альтернативой может быть помещение тела функции в закрытую функцию / метод, который вы можете вызывать внутри. Тело открытого метода будет состоять из одного вызова закрытой функции.

Я представляю себе этот вопрос очень субъективно, но все же ... Есть мысли по этому поводу?

Ответы [ 2 ]

3 голосов
/ 13 апреля 2009

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

2 голосов
/ 13 апреля 2009

Да, вы можете сделать это, это хорошая практика, которая, однако, должна решительно рассматриваться в отношении ситуации.

Два примера:

  • Будьте осторожны, чтобы не вызывать методы в конструкторе класса: во время вызова ваш класс частично инициализируется, поэтому любой вызов методов (самого класса или унаследованных) может иметь плохие и трудные для отслеживания последствия. Как правило, конструктор должен быть «самодовольным» по отношению к классу.

  • Поскольку вы используете методы класса, у вас есть свободный доступ к его реализации. Задайте себе вопрос: «Хочу ли я получить доступ к классу через его интерфейс или через его реализацию?».

Чтобы лучше объяснить второй пункт, предположим, что у вас есть класс A с методами foo () и bar ().

Предположим, что foo () вызывает bar () в своем коде. В этом случае вы говорите с интерфейсом вашего объекта. Этот интерфейс не может быть тем, который вы ожидаете! Например, предположим, что класс был переопределен (класс B, производный от A) вами, а также пользователем вашего кода, и этот метод bar () был переопределен. Из-за наследования A :: foo () будет вызывать B :: bar () вместо A :: bar ().

Не используя вызов метода bar () и получая доступ к реализации , вы гарантируете, что ваша функция ведет себя одинаково даже для дочерних классов.

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

...