Подтвердить что ты не робот

Является ли класс, который управляет несколькими классами "объектом Бога"?

Чтение запись в Википедии о объектах Бога, в ней говорится, что класс является объектом-богом, когда он слишком много знает или делает слишком много.

Я вижу логику этого, но если это правда, то как вы связываете каждый класс? Разве вы не всегда используете мастер-класс для подключения управления окнами, подключений DB и т.д.

4b9b3361

Ответ 1

Основная функция/метод может знать о существовании окон, баз данных и других объектов. Он может выполнять сложные задачи, такие как введение модели в контроллер.

Но это не значит, что он управляет всеми мелочами. Вероятно, он ничего не знает о том, как реализована база данных или окна.

Если бы это произошло, его можно было бы обвинить в объекте Бога.

Ответ 2

Объект god - это объект, который прямо или косвенно содержит ссылки, на большинство, если не на все объекты в приложении. Как видно из этого вопроса, почти невозможно избежать наличия объекта-бога в приложении. Некоторые объекты должны содержать ссылки на различные подсистемы: пользовательский интерфейс, базу данных, связь, бизнес-логику и т.д. Обратите внимание, что объект-бог не обязательно должен определяться приложением. Многие фреймворки имеют встроенные объекты богов с именами типа "контекст приложения", "среда приложения", "сеанс", "активатор" и т.д.

Проблема заключается не в том, существует ли объект-бог, а в том, как он используется. Я проиллюстрирую с крайним примером...

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

class NumberFormatter {
    ...
    String format(double value) {
        int decimalPlaces = getConfiguredPrecision();
        return formatDouble(value, decimalPlaces);
    }

    int getConfiguredPrecision() {
        return /* what ??? */;
    }
}

Вопрос в том, как getConfiguredPrecision выяснить, что вернуть? Одним из способов было бы дать NumberFormatter ссылку на глобальный контекст приложения, который он хранит в поле участника, называемом _appContext. Тогда мы могли бы написать:

return _appContext.getPreferenceManager().getNumericPreferences().getDecimalPlaces();

Сделав это, мы только что сделали NumberFormatter в объект-бог! Зачем? Потому что теперь мы можем (косвенно) ссылаться практически на любой объект в приложении через его поле _appContext. Это плохо? Да, это так.

Я собираюсь написать unit test для NumberFormatter. Пусть настроены параметры... ему нужен контекст приложения?! WTF, который имеет 57 методов, которые мне нужно высмеять. О, ему нужен только менеджер pref... WTF, я должен издеваться над 14 методами! Числовые префы!?! Вверните его, класс достаточно прост, мне не нужно его проверять...

Скажем, что в контексте приложения был другой метод, getDatabaseManager(). На прошлой неделе мы использовали SQL, поэтому метод возвращал объект базы данных SQL. Но на этой неделе мы решили перейти на базу данных NoSQL, и теперь метод возвращает новый тип. Изменено ли изменение NumberFormatter? Хмммм, я не помню... да, возможно, я вижу, что в конструкторе есть контекст приложения... позвольте мне открыть источник и посмотреть... нет, нам повезло: это только обращается к getPreferenceManager()... теперь можно проверить другие 93 класса, которые принимают контекст приложения как параметр...

Этот же сценарий возникает, если изменения сделаны в менеджере настроек или в объекте числовых настроек. Мораль истории состоит в том, что объект должен содержать только ссылки на то, что ему нужно для выполнения своей работы, и только те вещи. В случае NumberFormatter все, что ему нужно знать, - это одно целое число - число десятичных знаков. Он может быть создан непосредственно объектом-богом приложения, который знает магическое число (или pref-менеджер или еще лучше, числовые префы), не превращая форматирующий элемент в объект-бог. Кроме того, любым компонентам, которые должны форматировать числа, может быть присвоен форматтер вместо объекта god. Побеждает вокруг.

Итак, резюмируя, проблема заключается не в существовании объекта-бога, а скорее в придании богоподобному статусу другим объектам волей-неволей.

Кстати, принцип разработки, который решает эту проблему, стал известен как Закон Деметры. Или "при оплате в ресторане дайте серверу ваши деньги не вашему кошельку".

Ответ 3

По моему опыту это чаще всего происходит, когда вы имеете дело с кодом, который является продуктом управления проектами "Развивайте, как вы идете" (или там не хватает). Когда проект не продуман и не запланирован, а обязанности объекта свободны и не делегируются должным образом. В сценариях тезисов вы обнаруживаете "объект-бог", являющийся основным для кода, который не имеет никакой очевидной организации или делегирования.

Это не взаимосвязь или взаимосвязь разных классов, которая является проблемой с объектами-богами, это тот факт, что божественный объект много раз может выполнить большинство, если не все обязанности, связанные с его производными детьми, и являются довольно непредсказуемыми ( кем бы то ни было, кроме разработчика) в отношении того, каковы их определенные обязанности.

Ответ 4

Просто знание о "множественных" классах не делает Бога Богом; зная о нескольких классах, чтобы решить проблему, которая должна быть разделена на несколько под-проблем, делает, делает Бога.

Я думаю, что основное внимание должно быть сосредоточено на том, следует ли разделить проблему на несколько под-проблем, не на количество классов, о которых знает данный объект (как вы указали, иногда зная о нескольких классы необходимы).

Боги чрезмерно раздуты.