Доступ по умолчанию не делает модификатор частного доступа избыточным.
Позиция языковых дизайнеров отражена в официальном учебном пособии « Управление доступом к членам класса», и она достаточно ясна (для вашего удобства соответствующее утверждение в цитате выделено жирным шрифтом ):
Советы по выбору уровня доступа:
Если другие программисты используют ваш класс, вы хотите, чтобы ошибки от неправильного использования не возникали. Уровни доступа могут помочь вам сделать это.
- Используйте наиболее ограниченный уровень доступа, который имеет смысл для конкретного члена. Используйте личное, если у вас нет веских причин не делать этого.
- Избегайте открытых полей, кроме констант. (Во многих примерах из учебника используются открытые поля. Это может помочь в сжатой иллюстрации некоторых моментов, но не рекомендуется для производственного кода.) Открытые поля имеют тенденцию связывать вас с конкретной реализацией и ограничивают вашу гибкость при изменении кода.
Ваше обращение к тестируемости как к оправданию полного отказа от частного модификатора неверно, о чем свидетельствуют, например, ответы в разделе « Новое в TDD». Должен ли я избегать частных методов сейчас?
Конечно, вы можете иметь частные методы, и, конечно, вы можете проверить их.
Или есть какой - то способ , чтобы получить частный метод для запуска, в этом случае вы можете проверить это , что путь, или нет нет способа , чтобы получить частные бежать, и в этом случае: почему, черт возьми , вы пытаетесь проверить это, просто удалить эту чертову вещь ...
Позиция разработчиков языков в отношении цели и использования доступа на уровне пакетов объясняется в другом официальном учебном пособии « Создание и использование пакетов», и она не имеет ничего общего с идеей отбрасывания частных модификаторов (для вашего удобства соответствующее утверждение в цитате выделено жирным шрифтом ) :
Вы должны связать эти классы и интерфейс в пакет по нескольким причинам, включая следующие:
- Вы и другие программисты можете легко определить, что эти типы связаны ...
- Вы можете разрешить типам в пакете иметь неограниченный доступ друг к другу, но по-прежнему ограничивать доступ для типов вне пакета ...
<rant "Мне кажется, я услышал достаточно скуля. Думаю, пришло время сказать громко и ясно ...">
Частные методы полезны для модульного тестирования.
Примечание ниже предполагает, что вы знакомы с покрытием кода . Если нет, потратьте время на изучение, так как это весьма полезно для тех, кто заинтересован в модульном тестировании и вообще в тестировании.
Итак, у меня есть этот частный метод и модульные тесты, и анализ покрытия говорит мне, что есть пробел, мой частный метод не покрывается тестами. В настоящее время...
Что я получу от сохранения конфиденциальности
Так как метод является закрытым, единственный способ продолжить - изучить код, чтобы узнать, как он используется через не приватный API. Как правило, такое исследование показывает, что причиной разрыва является то, что в тестах отсутствует конкретный сценарий использования.
void nonPrivateMethod(boolean condition) {
if (condition) {
privateMethod();
}
// other code...
}
// unit tests don't invoke nonPrivateMethod(true)
// => privateMethod isn't covered.
Для полноты, другими (менее частыми) причинами таких пробелов в покрытии могут быть ошибки в спецификации / дизайне. Я не буду углубляться в это здесь, чтобы все было просто; Достаточно сказать, что если вы ослабите ограничение доступа «просто для того, чтобы сделать метод тестируемым», вы упустите шанс узнать, что эти ошибки существуют вообще.
Хорошо, чтобы исправить разрыв, я добавляю модульное тестирование для пропущенного сценария, повторяю анализ покрытия и проверяю, что разрыв пропал. Что у меня сейчас? У меня есть новый модульный тест для конкретного использования не закрытого API.
Новый тест гарантирует, что ожидаемое поведение для этого использования не изменится без уведомления, так как если оно изменится, тест не пройдёт.
Внешний читатель может заглянуть в этот тест и узнать, как он должен использовать и вести себя (здесь внешний читатель включает в себя мое будущее Я, так как я склонен забывать код через месяц или два после того, как я закончу с ним).
Новый тест устойчив к рефакторингу (я делаю рефакторинг частных методов? Вы держите пари!) Что бы я ни делал privateMethod
, я всегда хочу тестировать nonPrivateMethod(true)
. Независимо от того, что я делаю privateMethod
, не нужно будет изменять test, потому что метод не вызывается напрямую.
Неплохо? Вы ставите.
Что я теряю от ослабления ограничения доступа
Теперь представьте, что вместо вышеупомянутого я просто ослабляю ограничение доступа. Я пропускаю изучение кода, который использует метод, и приступаю прямо к тесту, который вызывает мой exPrivateMethod
. Большой? Не!
Получу ли я тест для конкретного использования не частного API, упомянутого выше? Нет: nonPrivateMethod(true)
раньше не было никакого теста , и сейчас такого теста нет.
Получают ли сторонние читатели шанс лучше понять использование класса? Нет. - Эй, какова цель метода, проверенного здесь? - Забудь об этом, он предназначен исключительно для внутреннего использования. - Упс.
Это терпимо к рефакторингу? Ни в коем случае: что бы я ни изменил exPrivateMethod
, скорее всего, это сломает тест. Переименуйте, объединитесь с другим методом, измените аргументы, и test просто прекратит компиляцию. Головная боль? Вы держите пари!
Подводя итог , придерживаясь частного метода, я получаю полезное и надежное улучшение в модульных тестах. Напротив, ослабление ограничений доступа «для тестируемости» только дает мне неясный, трудный для понимания фрагмент тестового кода, который дополнительно подвергается постоянному риску быть нарушенным любым незначительным рефакторингом; Честно говоря, то, что я получаю, выглядит подозрительно, как технический долг .
</ Декламация>