Как соотносится дизайн JavaBeans с сокрытием информации?
Два семестра назад у меня был профессор, который сказал:
Некоторым из вас было сказано всегда включать методы установки и получения для всех частных переменных экземпляра. Я говорю, что это разрушает сокрытие информации и часто приводит к системам, в которых нельзя применять инварианты.
Теперь это звучит правильно для меня. Но разве включение таких методов установки / получения не является основной частью создания JavaBeans? Если так, то почему? Если нет, что я неправильно понимаю в JavaBeans?
4 ответа
Методы получения и установки не требуются в классе Java Bean. Все, что требуется, - это то, что класс должен быть публичным, у него должен быть открытый конструктор без аргументов, и он должен реализовывать Serializable. Однако для того, чтобы переменные автоматически обнаруживались при использовании вашего компонента, вы должны предоставить методы получения и установки в соответствии со стандартным соглашением об именах (getVarname, setVarname...).
В любом случае вы хотите сделать внешне видимыми только те переменные, которые видят бизнес за пределами вашего класса.
Вы можете прочитать, почему методы получения и установки являются злыми:
Вы можете возразить, сказав: "А как же JavaBeans?" Что насчет них? Вы, безусловно, можете создавать JavaBeans без методов получения и установки.
BeanCustomizer
,BeanInfo
, а такжеBeanDescriptor
все классы существуют именно для этой цели. Разработчики спецификаций JavaBean бросили в картину идиому getter/setter, потому что они думали, что это будет простой способ быстро создать bean-компонент - то, что вы можете сделать, пока учитесь, как делать это правильно. К сожалению, никто этого не сделал.Средства доступа были созданы исключительно как способ пометить определенные свойства, чтобы программа-создатель пользовательского интерфейса или аналог могли идентифицировать их. Вы не должны вызывать эти методы самостоятельно. Они существуют для автоматического использования инструмента. Этот инструмент использует API самоанализа в
Class
Класс, чтобы найти методы и экстраполировать существование определенных свойств из имен методов. На практике эта основанная на самоанализе идиома не сработала. Это сделало код слишком сложным и процедурным. Программисты, которые не понимают абстракцию данных, на самом деле вызывают методы доступа, и, как следствие, код менее обслуживаем.
Ваш профессор прав. Вы не хотите слепо создавать методы получения и установки для всех переменных экземпляра. Вы хотите создать их там, где они необходимы.
Если у тебя есть BankAccount
класс с balance
переменная экземпляра, создание геттеров и сеттеров для нее имеет смысл, если вы хотите иметь возможность проверять и устанавливать баланс.
Даже здесь скрывается информация - в форме инкапсуляции реализации. Добытчик "double getBalance()
"может просто вернуть значение базовой переменной экземпляра, если это double
или это может быть возвращение значения, полученного из BigDecimal
если это выбор реализации для переменной, или это может быть вызов удаленного веб-сервиса и возврат результата. Таким образом, метод получения / установки все еще позволяет варьировать реализацию и, таким образом, не нарушает инкапсуляцию (и, соответственно, не делает JavaBeans).
JavaBeans делает для вас определение интерфейса (getXXX(), setXXX()
) для получения и установки "свойств" - атрибутов класса, которые пользователи обычно хотят проверять или изменять. Если в вашем классе есть информация, которая не считается "свойством", нет необходимости раскрывать ее. Например, скажем, BankAccount
В классе есть переменная экземпляра, используемая для проверки вывода средств. Если клиенту не требуется доступ или изменение этого, нет смысла создавать для него метод получения или установки.
Обычно это довольно просто: вы выставляете сеттеры / геттеры для переменных, которые нужно сделать видимыми извне, и вы не выставляете сеттеры / геттеры для переменных, о которых никто не знает.