Должны ли объекты знать о своих пользователях в определенных случаях?

Я закладываю основы для потенциальной игры, но у меня возникают проблемы с проектированием классов, которые должны быть инкапсулированы, но при этом эффективны.

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

Однако иногда кажется удобным, чтобы некоторые объекты знали друг о друге.

Допустим, у нас есть класс Dog.

public class Dog {

  public void eat() { ... }
  public void wagTail() { ... }

}

У собак есть владельцы, поэтому существует класс владельцев собак.

public class DogOwner {
  private Dog dog;

  public Dog getDog() { return dog; }
  public void petDog() { ... }
  public void takeDogForWalk() { ... }
}

А что, если у нас есть Dog, но нет его владельца? Кажется, имеет смысл сделать метод getOwner() для Dog.

public class Dog {
  private DogOwner owner;

  public void eat() { ... }
  public void wagTail() { ... }
  public DogOwner getOwner() { return owner; }

}

Однако теперь это дает Dog информацию о DogOwner, что, похоже, нарушает сокрытие информации. Это также создает избыточность, потому что Dog имеет DogOwner, а DogOwner имеет Dog.

Другой способ найти владельца — просто просмотреть всех владельцев и найти соответствующую собаку. Хотя это не создаст зависимости Dog и DogOwner, это кажется намного более дорогим, чем должно быть, потому что нам нужно перебрать всех владельцев.

Итак, нормально ли для Dog использовать метод getOwner()? Если это не так, какие другие альтернативы существуют для эффективного доступа к владельцу, если известен только Dog?


person Blubber    schedule 02.07.2015    source источник
comment
это взаимное отношение. собака ведет себя по отношению к своему хозяину не так, как по отношению к остальному миру. С другой стороны, если вы находитесь в контексте, где у вас есть ссылка на собаку, разве вы не имеете в то же время ссылку на владельца? (или вы действительно можете получить доступ к собаке напрямую, минуя ее владельца?)   -  person njzk2    schedule 02.07.2015


Ответы (3)


"Надо полагаться мало" - ровно столько, сколько нужно, не больше, не меньше.

Конечно, собака может иметь связь со своим хозяином. Вы спрашивали об альтернативах: во-первых, всегда хранить информацию о собаке и владельце вместе, даже если много кода не заботится о владельце. Во-вторых, если у вас есть собака и вы не знаете владельца, вы, очевидно, не можете спросить владельца. У вас может быть хэш-таблица, сопоставляющая собак владельцам, но тогда вы можете просто хранить собаку у владельца. Или у вас есть база данных всех владельцев собак, и вы сканируете ее в поисках владельца этой собаки — не совсем масштабируемо.

person gnasher729    schedule 02.07.2015

Хотя я не прагматик в разработке программного обеспечения, я не понимаю, как это обязательно нарушит слишком много принципов проектирования. Чтобы Dog "знал" что-либо о DogOwner, ему все равно нужно получить доступ к методам DogOwner. Итак, вы не говорите Dog.getDogOwnersName или что-то в этом роде, вы бы сказали Dog.getOwner().getName(). Таким образом, Dog волнует только то, кто его владелец. Но любая информация, кроме этой, по-прежнему эффективно скрыта.

person Jonathan Adam    schedule 02.07.2015

Я бы сказал, что это нормально. Одной из альтернатив, которые приходят на ум, было бы использование словаря с Dog в качестве ключа и DogOwner в качестве значения (поскольку гипотетически DogOwner может меняться со временем). Это также имело бы дополнительное преимущество, заключающееся в сохранении одного центрального репозитория отношений Dog/DogOwner.

person iliketocode    schedule 02.07.2015