Задача объектно-ориентированного проектирования - PullRequest
7 голосов
/ 01 октября 2010

Если я программирую игру, в которой есть рабочий, который рубит дрова (из деревьев), где бы я поместил метод "cutWood" в рабочий класс или в класс дерева?

РЕДАКТИРОВАТЬ: Первый пример, который я прочитал на OOD, был о круге (класс под названием круг), в котором есть метод, называемый «вычислить площадь».Теперь, конечно же, круг не рассчитывает свою собственную площадь.Единственный способ думать об этом - это то, что вычисление площади является операцией, которая имеет отношение к кругу (операция, выполняемая на кругу)

Таким образом, метод cutWood относится как к рабочему, так и к дереву.

Ответы [ 12 ]

8 голосов
/ 01 октября 2010

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

Рабочий должен вызвать метод вырубки на любом дереве, которое он хочет, а не на дереве, сообщающем работникучто он должен сократить это.Если вы хотите абстрагировать это, как намекнул Ханс, вы можете создать интерфейс ICuttable для метода Cut и сделать так, чтобы ваше дерево его реализовало.

Рассмотрим что-то, с чем вы знакомы, String.Когда вы хотите вырезать строку (split), вы не определяете метод splitString в каждом объекте, который собирается это сделать.Независимо от того, какой объект решит разделить строку, происходит одно и то же - и обычно для этого нужно знать внутренности целевого объекта (строки).Многие другие объекты просто вызывают метод split строки.Строковый объект обладает высокой связностью - потому что его методы способствуют выполнению общей задачи - манипулированию строками.

Я не понимаю, как резка дерева вносит большой вклад в сам рабочий объект.

4 голосов
/ 01 октября 2010

Вы в основном ответили на вопрос: «рабочий, который рубит дрова». Вы должны поместить это в рабочий класс.

4 голосов
/ 01 октября 2010

Спросите себя: рабочие рубят древесину или деревья рубят древесину?

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

Создать

cut(Material m)

метод для работника для дополнительной объектно-ориентированности.

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

Для меня это звучит как кандидат на шаблон Стратегии. Вам может понадобиться абстрактный класс WorkerAction с методом executeAction. Затем подклассы класса WorkerAction будут реализовывать такие детали, как вырезание дерева, поиск золота и другие рабочие действия. Таким образом, подкласс знает о деталях дерева и может вызывать необходимые методы на дереве, чтобы воздействовать на дерево во время его резки.

Тогда рабочему классу нужна только ссылка на экземпляр конкретного WorkerAction, для которого он вызывает executeAction (). Работник не знает подробности о Дереве, Золоте и т. Д. Таким образом, работник может выполнять действие, но вы не ограничиваете работника только одним действием. Фактически вам больше не нужно изменять рабочий класс, если вы хотите, чтобы ваш работник выполнял больше действий в будущем.

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

нужно ли вам модифицировать дерево по мере его обрезки?

Вам нужно изменить работника, так как он режет дерево?

Я бы подумал, что в итоге вы получите WoodCutting сервис, который обрабатывает событие, возможно, модификации обоих, или, в свою очередь, вызывает worker.cutWood() И tree.woodCut()

ахах, что за вопрос;)

1 голос
/ 01 октября 2010

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

Таким образом вам необходимо решить, за какой объект / класс отвечает за что.Это приведет вас к правильным ответам на вопрос о том, какие методы размещения.

Таким образом, задайте себе такие вопросы, как: рабочий решает сам рубить дрова?Если он это сделает, то, вероятно, его не нужно заказывать, поэтому ему не понадобится метод cut (tree) .Но если пользователь может приказать ему сделать это, ему потребуется метод cut (tree) .Другой пример: должно ли дерево знать, что он срублен?Что ж, если срезанное дерево просто приводит к его удалению из леса, ему может не понадобиться такой tree.cut () метод.Но если вы назначаете на дерево ответственность (пере) рисовать себя во время вырезания, вам может понадобиться метод tree.cut () .Дерево можно даже смоделировать как имеющее ширину, и он может рассчитать, сколько срезов необходимо, прежде чем он рухнет.

1 голос
/ 01 октября 2010

Вы можете иметь метод cutWood в рабочем классе и метод cutted в древовидном классе. Очевидно, что worker.cutWood вызывает tree.cutted, что может вернуть количество заготовленной древесины. Tree.cutted сделает все, что нужно, чтобы дерево умерло.

Если вы рассматриваете вызовы методов как «сообщения, отправленные от одного объекта к другому», то имеет больше смысла говорить «игрок отправляет сообщение« вырезать дрова »работнику, который, в свою очередь, отправляет сообщение« вырезать » дерево ".

0 голосов
/ 01 октября 2010

Это интересная тема. Иногда я думал о том же сценарии. Я думаю, что хороший способ пойти, это поместить метод в класс с наивысшей сплоченностью. Поэтому класс Tree будет первым выбором. С другой стороны, если вы попытаетесь соответствовать модели реального мира, я бы сказал, что класс Worker должен иметь возможность выполнять какие-то действия, в том числе вырезать дерево. Я часто нахожусь в таких ситуациях и задаюсь вопросом, где найти подходящее место для применения этого метода. Другим подходом будет класс, который знает о работнике и дереве и, следовательно, обрабатывает механизм вырубки деревьев. Таким образом, оба класса (дерево, рабочий) ничего не знали бы об этом.

0 голосов
/ 01 октября 2010

На этот вопрос действительно можно ответить, только если вы объясните, что делает cutWood.

Если cutWood влияет только на состояние Tree, то оно относится к Tree, например,

public void cutWood() {
    this.height = 0;
}

В случае calculateArea вам нужен только радиускруг (предположим, что пи постоянен), чтобы сделать этот расчет - больше ничего.Вот почему он относится к Circle.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...