Я НЕ гуру OO-дизайна ... Вот один способ, который я лично считаю лучше.
Внедрите реализацию интерфейса GenreGuesser в Book ... это лучше всего сделать через BookFactory. Фабрика настраивается ОДИН РАЗ, а затем используется для создания «похожих» книг. Я подумываю об использовании здесь внедрения зависимостей (например, среды Springs DI или Google Guice), которая значительно сокращает накладные расходы по «подключению» фабрик к вещам, которые от них зависят; -)
Затем мы можем получить И КЕШИТЬ вычисленный атрибут на лету. Обратите внимание, что кэширование результата подразумевает, что IDENTITY объектов Book (например, author & title) является окончательным или, по крайней мере, фиксированным однократным набором.
public String getGenre()
{
if (this.genre==null)
this.genre = genreGuesser.getGuess();
return this.genre;
}
Так что в основном вы делаете свое собственное "позднее связывание" для каждого вычисляемого поля. Кроме того, ничто не мешает вам (или пользователю) устанавливать каждое поле вручную, если «догадка» по умолчанию не является базовой.
Это обеспечивает простой "богатый" интерфейс в классе Book; ценой того, чтобы сделать Книгу осведомленной о понятии "догадки" ... и я не фанат "интеллектуальных" объектов переноса, как таковых, что напоминает другой подход.
Если мы собираемся принять на себя все накладные расходы, связанные с наличием класса BookFactory, и мы МОЖЕМ ограничиться ТОЛЬКО КОГДА-ЛИБО созданием книг через фабрику, то почему бы просто не позволить BookFactory (который по определению знает все о Book и это атрибуты) заполнить все вычисляемые поля с (угаданными) значениями по умолчанию. Затем класс Book снова становится простым, тупым, передающим объектом, который делает именно то, что ему нужно, и НИЧЕГО ЕЩЕ.
Мне будет интересно прочитать предложения других.
Приветствия. Кит.