Скажем, у вас есть приложение, разделенное на 3 уровня: графический интерфейс, бизнес-логику и доступ к данным. На уровне вашей бизнес-логики вы описали свои бизнес-объекты: геттеры, сеттеры, аксессоры и т.д.... вы получаете эту идею. Интерфейс уровня бизнес-логики гарантирует безопасное использование бизнес-логики, поэтому все методы и аксессоры, которые вы вызываете, будут проверять ввод.
Это замечательно, когда вы сначала пишете код пользовательского интерфейса, потому что у вас есть четко определенный интерфейс, которому вы можете доверять.
Но вот сложная часть, когда вы начинаете писать уровень доступа к данным, интерфейс к бизнес-логике не соответствует вашим потребностям. У вас должно быть больше доступа и геттеров для установки полей, которые/будут скрыты. Теперь вы вынуждены разрушать интерфейс вашей бизнес-логики; теперь возможно установить поля из уровня пользовательского интерфейса, который на уровне пользовательского интерфейса не имеет деловых настроек.
Из-за изменений, необходимых для уровня доступа к данным, интерфейс к бизнес-логике подорвался до такой степени, что можно даже установить бизнес-логику с недопустимыми данными. Таким образом, интерфейс больше не гарантирует безопасного использования.
Надеюсь, я достаточно четко объяснил проблему. Как вы предотвращаете эрозию интерфейса, сохраняете скрытие информации и инкапсуляцию, и все же сохраняете различные потребности интерфейса между разными слоями?