понедельник, 15 мая 2017 г.

Могут ли объекты быть друзьями?


Как обсуждалось ранее, правильная инкапсуляция приводит к полному отсутствию «голых данных». Однако остается открытым вопрос: как объекты могут взаимодействовать между собой, если они не могут обмениваться данными? Думаю, у меня есть решение, которое сохраняет и инкапсуляцию на месте, и позволяя объектам взаимодействовать.



Class Temperature {
  private
int t;
 
public String toString () {
    
Return String.format ("% d C", this.t);
 
}} 


Объект представляет собой температуру. Единственное поведение, которое он проявляет, это печать температуры в градусах Цельсия. Мы не хотим раскрывать t, потому что это приведет к проблеме «голых данных». Мы хотим сохранить тайну, и это хорошее желание. 

Теперь мы хотим иметь возможность печатать температуру в градусах Фаренгейта. Наиболее очевидным подходом было бы введение другого метода toFahrenheitString () или добавление булевского флага к этому объекту, который изменит поведение метода toString (), правильно? Любое из этих решений лучше, чем добавление метода getT (), но ни один из них не идеален. 

Что делать, если мы создадим такой декоратор: 

class TempFahrenheit implements Temperature {
  private
TempCelsius origin;
 
public String toString () {
    
Return String.format (
      
"% D F", this.origin.t * 1.8 + 32
    
);
  
}} 


Он должен работать просто отлично:
Temperature t = new TempFahrenheit(
  new TempCelsius(35)
);
Единственная проблема заключается в том, что он не будет компилироваться в Java, потому что классу TempFahrenheit не разрешен доступ к приватному t в классе TempCelsius. И если мы сделаем t public, каждый сможет прочитать его напрямую, и у нас будет эта проблема «голых данных» - серьезное нарушение инкапсуляции.Однако, если мы разрешим доступ только к одному классу, все будет хорошо. Что-то вроде этого (не будет работать на Java, это просто концепция): 

Class TempCelsius {
  trust
TempFahrenheit; // Вот!
  private
int t;
  p
ublic String toString () {
    
Return String.format ("% d C", this.t);
  
}} 


Поскольку это ключевое слово trust помещено в класс, который разрешает доступ, у нас не будет проблемы с «голыми данными» - мы всегда будем точно знать, какие объекты обладают знаниями о t. Когда мы что-то меняем в t, мы точно знаем, где обновить код. 

Постскриптум Обсудив эту идею ниже в комментариях, я начал думать, что нам не нужно это ключевое слово доверия вообще. Вместо этого мы должны просто предоставить всем декораторам доступ ко всем частным атрибутам объекта.

Комментариев нет:

Отправить комментарий