-
Notifications
You must be signed in to change notification settings - Fork 3
Encapsulation
Хороший модуль должен скрывать детали реализации и API. Ваши классы и должны взаимодействовать только через API, при этом не должно быть важно, что происходит внутри.
Подобный подход(разделение) поможет вам, при необходимости, изменить реализацию определенного компонента, не нарушив работы системы. Как пишет Блох - главное правило заключается в том, чтобы сделать каждый класс или член максимально недоступным.
Если класс можно сделать доступным только в пакете - лучше сделать его таковым. В таком случае такой класс перестанет быть частью API, ведь он не будет public, он станет частью реализации пакета. При этом если вы когда-либо удалите или измените такой класс, вы не сломаете ничего у других, кто его использует(у клиентов), а если оставить его открытым, то необходимо будет поддерживать работоспособность такого класса, поддерживать совместимость и т.д.
В Java существует 4 модификатора доступа:
- Private - мое и только мое
- Package - доступ всем в пределах пакета
- Protected - доступ у всех наследников и доступ из любого класса в пакете, где объявлен класс с таким полем!
- Public - доступ отовсюду
Отсюда понятно, почему при переопределении метода у класса наследника, мы не можем сделать модификатор доступа более узким, например, если метод public, то в классе наследнике не получится сделать его private. Это сделано для того, чтобы гарантировать, что объект класса наследника мы можем использовать везде, где можно было бы использовать объект супер класса.
Сделав поле класса открытым, мы не можем наложить ограничения на значения, которые поле может принимать, например, если сделать поле возраст(age) открытым, то мы не сможем проконтролировать, что в это поле кто-то запишет отрицательное значение, а также мы не можем среагировать на такое поведение клиента, например, сообщив, что возраст не может быть меньше 0.
При этом public можно использовать с final-полями и неизменямыми объектами. При этом final не гарантирует нам, что вы не измените сам объект(если он модифицируемый). Т.е final гарантирует лишь то, что вы не измените ссылку на объект, но сам объект вы все также вольны менять.
public также часто используется для выставления констант наружу, делая их public static final
.
Никогда не надо делать public static final на массив, так как массив изменяемая структура данных, то все получат возможность менять значения в таком массиве. А это огромная проблема.
Если вам все-таки хочется так сделать, то сделайте массив неизменяемым с помощью метода Collections
.
- Чем ниже уровень доступа - тем лучше
- Не делайте public полей, за исключением public static final констант. При этом такие константы не должны ссылаться на изменяемые объекты.
- Всегда старайтесь использовать все плюсы инкапсуляции - проверяйте значения, которые вы присваиваете полям и соответствующим образом реагируйте на ошибки.