Как обсуждалось ранее , правильная инкапсуляция приводит к полному отсутствию «голых данных». Однако остается вопрос: как объекты могут взаимодействовать, если они не могут обмениваться данными? В конце концов мы должны предоставить некоторые данные, чтобы другие объекты могли их использовать, верно? Да, это правда. Тем не менее, я думаю, у меня есть решение, которое сохраняет инкапсуляцию на месте, позволяя объектам взаимодействовать.
Скажи, что это наш объект:
1
2
3
4
5
6
|
class Temperature { private int t; public String toString() { return String.format( "%d C" , this .t); } } |
Это представляет температуру. Единственное поведение, которое он демонстрирует, — это печать температуры в градусах Цельсия. Мы не хотим раскрывать t
, потому что это приведет к проблеме «голых данных» . Мы хотим держать это в секрете, и это хорошее желание.
Теперь мы хотим иметь возможность печатать температуру в градусах Фаренгейта. Наиболее очевидный подход заключается в том, чтобы ввести другой метод toFahrenheitString()
или добавить логический флаг к объекту, который изменит поведение метода toString()
, верно? Любое из этих решений лучше, чем добавление метода getT()
, но ни одно из них не является идеальным.
Что если мы создадим этот декоратор:
1
2
3
4
5
6
7
8
|
class TempFahrenheit implements Temperature { private TempCelsius origin; public String toString() { return String.format( "%d F" , this .origin.t * 1.8 + 32 ); } } |
Это должно работать просто замечательно:
1
2
3
|
Temperature t = new TempFahrenheit( new TempCelsius( 35 ) ); |
Единственная проблема заключается в том, что он не будет компилироваться в Java, поскольку класс TempFahrenheit
не имеет доступа к частному t
в классе TempCelsius
. И если мы сделаем это общедоступным, каждый сможет прочитать его напрямую, и у нас возникнет проблема «голых данных» — серьезное нарушение инкапсуляции.
Однако, если мы разрешим этот доступ только одному классу, все будет хорошо. Примерно так (не будет работать в Java; это просто концепция):
1
2
3
4
5
6
7
|
class TempCelsius { trust TempFahrenheit; // here! private int t; public String toString() { return String.format( "%d C" , this .t); } } |
Поскольку это ключевое слово trust
помещено в класс, который разрешает доступ, у нас не будет проблемы «голых данных» — мы всегда будем точно знать, какие объекты обладают знаниями о t
. Когда мы что-то меняем в t
, мы точно знаем, где обновить код.
Что вы думаете?
Вы можете также найти эти связанные сообщения интересными: инкапсуляция покрывает голые данные ; Сколько инкапсулируют ваши объекты? ; Поведение объекта не должно быть настраиваемым ; Как неизменный объект может иметь состояние и поведение? ; Градиенты неизменности ;
JavaScript отключен в вашем браузере, поэтому вы не можете видеть комментарии под этим сообщением.
Ссылка: | Могут ли объекты быть друзьями? от нашего партнера JCG Егора Бугаенко в блоге « О программировании» . |