Как я могу написать контроллер, не превращая его в объект Бога? - PullRequest
8 голосов
/ 25 октября 2010

В моем приложении Controller, который запускается основным методом.Контроллер инициализирует хуки, соединения с базой данных, пользовательский интерфейс, другое соединение и другие вещи.Он содержит большую часть состояния программы (нет, это не Singleton).В другом примере есть контроллер для бота, который обрабатывает интерпретацию и отправку команд.Оба довольно большие файлы.

Я читал об объектах Бога, но я не знаю, как их разделить.Если я разделю переводчика и диспетчера в боте, это приведет к ужасной цепочке вызовов (что-то вроде getBot().getParser().getOutput().sendMessage(recipient, message)).Аналогично, в первом Контроллере, если я разделю вещи, у вас будут только объекты Data, которые содержат поля, и некоторые вспомогательные методы-псевдонимы.Разделение их только ухудшит ситуацию.И прежде чем вы предположите, что это не поддерживаемо, на самом деле это не так.Я даже не писал контроллер Bot, но я все еще знаю, что происходит.

Проблема, однако, в том, что класс Bot имеет длину 2000 строк (вероятно, короче, если я удалил комментарии Javadoc), а длина Bot примерно равна 1000.Много линий = объект Бога.Но нормально ли это для одного или двух основных классов проекта?

Ответы [ 4 ]

11 голосов
/ 25 октября 2010

«Много линий» вовсе не означает, что класс - это божественный объект, это ужасный ужасный ориентир для выяснения, следует ли вам что-то реорганизовать.Некоторые вещи очень сложны и требуют сложного и изначально большого объекта.Идея объекта Бога состоит в том, что делает класс .

Например, если бы я создал объект, который мог бы

DoMyTaxes()
GiveMeHugs()
LogThisError()
StartGameLoop()

Объект был бы квалифицирован как объект Бога, даже если это может быть только 100 строк кода.Основная идея заключается в том, что все вышеперечисленное совершенно не связано (в конце бизнес-логики спектра), так почему же в мире они все являются частью одного и того же объекта.Если бы я решил, что объятия будут длиться дольше, я мог бы в конечном итоге поднять налоги.Введите IRS.

Однако, если вы работаете над симулятором физики, допустим, и класс Classical() будет иметь такие методы / объекты, как:

Space()
Time()
Velocity()
Speed()
Mass()
Acceleration()
Gravity()
Force()
Impulse()
Torque()
Momentum()
AngularMomentum()
Inertia()
MomentOfInertia()
ReferenceFrame()
Energy()
KineticEnergy()
PotentialEnergy()
MechanicalWork()
VirtualWork()
DAlembertsPrinciple()

(любезно предоставленоВикипедия)

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

Объект Quantum() будет еще более сложным, разумеется.

Повторим, идея о программе поведение , а не поток данных :

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

Если вы считаете, что есть проблема, вы можете попробовать реализовать различные формы опосредованное или более уродливые шаблоны, такие как внедрение зависимостей .

3 голосов
/ 25 октября 2010

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

Вопрос, который я задам, - если бы я дал это другому разработчику, могли бы они легко понять и поддерживать его?

Если ответ положительный, то, скорее всего, вам ничего не нужно делать. Если нет, то рефакторинг в порядке.

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

2 голосов
/ 26 октября 2010

Я бы предложил, чтобы физический / двигательный движок определенно был отделен от переводчика языка;хотя интерпретатору языка потребуется доступ к некоторым общедоступным методам и свойствам физического движка, нет никаких причин, по которым два аспекта робота должны быть в одном классе.Сам языковой переводчик можно разделить на несколько классов, как и движок.Может существовать объект master-control, но он должен иметь относительно небольшой объем кода.Это, основной движущий механизм и основной языковой движок, должны все делегировать большую часть своей работы объектам, которые их составляют.

0 голосов
/ 15 февраля 2013

Я думаю, что ключевым принципом здесь является «сплоченность».

DoMyTaxes()
GiveMeHugs()
LogThisError()
StartGameLoop()

.. не является сплоченным.

Что-то вроде:

GiveMeHug()
GiveMeKisses()
GiveMeHugs(int noOfTimes)
GiveMeHugs(int noOfTimes, Person person)
GiveMeHugsAndKisses()

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

...