Java-дизайн: повторяющиеся методы подобъектов

Когда я работал над своим проектом и должен был использовать много вложенных объектов, я очень не был уверен в своем дизайне структуры в Java, когда хотел установить переменную экземпляра глубоко вложенного объекта из верхнего объекта. Такое ощущение, что я скучаю по базовому пониманию, возможно, структурированного дизайна в Java. Любое понимание этого ценится.

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

Country
  Capital
     Palace
        King

Если я сейчас хочу установить приватную строковую переменную 'nameOfKing' в King из основного объекта (Country), мне придется определить каждый метод во всех высших классах King. Что-то вроде этого:

public class Country {
   private Capital capital;

   public void setNameOfKing(String n) {
      capital.setNameOfKing(n);
   }
}

public class Capital{
   private Palace palace;

   public void setNameOfKing(String n) {
      palace.setNameOfKing(n);
   }
}

public class Palace{
   private King king;

   public void setNameOfKing(String n) {
      king.setNameOfKing(n);
   }
}

public class King{
   private String nameOfKing;

   public void setNameOfKing(String n) {
      this.nameOfKing = n;
   }
}

так что я могу позвонить country.setNameOfKing(n);. Это нормально, если у вас всего несколько переменных, но что, если в классах King, Palace, Capital определено много других переменных и методов, и все они должны вызываться из Country. Что, если Palace также содержит другие объекты класса, такие как (сейчас просто придумываю) ThroneRoom, Treasury, Queen и т. д. Это означало бы, что почти все методы в подклассах должны существовать в классе Country, который может потенциально означает, что вам нужно создать огромное количество методов просто для передачи информации подобъектам, что приводит к очень большому классу Country.

Теперь, я полагаю, вы могли бы технически сказать, что король также может быть определен в самой стране, избавляясь от дополнительных методов в Palace и Capital, но это все равно означало бы, что методы должны существовать в классе Country, и что, если эта структура имеет смысл как в логике, сгруппированной вместе, что было бы лучшим подходом для этого? Я не уверен, что есть лучший способ, но я не могу избавиться от ощущения, что я что-то здесь упускаю.


person lokipoki    schedule 23.02.2017    source источник
comment
так что getPalace().setFoo() не вариант?   -  person Patrick Parker    schedule 23.02.2017
comment
То есть вы имеете в виду изменение метода в классе Country вот так? capital.getPalace().setNameOfKing(n); Это изменит тот факт, что потенциально у вас может быть большое количество методов в классе Country.   -  person lokipoki    schedule 23.02.2017


Ответы (1)


Это вопрос ответственности.

Спросите себя: "Кто должен знать, кто такой король?". Когда ты во дворце, ты отвечаешь за короля? Очевидно нет. Король не управляется вашим дворцом, но он привязан к вашей стране по закону.

Запрос palace.setNameOfKing() аналогичен тому, что вы просите дом дать имя новорожденному. Ваш дом не несет этой ответственности, и ему нельзя позволять это делать.

Правильный способ сделать это — получить экземпляр King и напрямую установить его имя.


Теперь есть проблема с этим подходом: вам, возможно, придется использовать много геттеров, чтобы найти экземпляр King. Но вы можете решить эту проблему с помощью функционального подхода к вашим классам.

palace.getOwner() может вернуть интерфейс Owner с King implements Owner.

Те же правила можно применить и к другим вашим классам.

person Guillaume F.    schedule 23.02.2017
comment
Да, это вопрос ответственности, и я бы сделал еще один шаг вперед и даже не позволил бы теоретически установить имя короля повсюду, предоставив метод общедоступного сеттера. - person Markus Benko; 23.02.2017