Какой дизайн наиболее элегантен для этой простой проблемы с OOAD? - PullRequest
2 голосов
/ 23 сентября 2010

Я пытаюсь начать работу с OOAD, эта проблема пришла мне в голову, и я не уверен, что могу найти хорошее решение: (это упрощенная версия случая из реального мира).

Рыбак ловит рыбу в пруду с помощью удочки.При каждом запуске лески существует вероятность вылова рыбы, равная 1/10 при солнечном свете и 1/20 ночью.

Какие классы определить? Я бы ответил: Fisherman, FishingRod, Pond, Day (для моделирования дня и ночи).

Какие методы? Я бы ответил: Fisherman.Launch (FishingRod), FIshingRod.TryToFish (Pond) возвращает логическое значение

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

Как моделировать внешний фактор (дневной свет)?

Любой комментарий приветствуется.Также примеры кода.

ОБНОВЛЕНИЕ: Первый комментарий к вопросу и ответ tdammers заставляют меня быть более конкретным.Как я уже писал выше, «это упрощенная версия случая из реального мира», в любом случае, скажем, я хочу увеличить сложность позже, а не супер увеличить, скажем, увеличить ее настолько, чтобы было хорошо, чтобы все классы, которые я перечислилвыше (например, потому что я отслеживаю, сколько рыб в пруду, насколько устал рыбак, ...).В любом случае, самые интересные для меня вопросы: «Как моделировать вероятность» и «Внешние факторы».Относитесь к этому как к вопросу новичка для людей, у которых не так много навыков в OOAD.

Ответы [ 3 ]

7 голосов
/ 23 сентября 2010

У меня были бы Рыбак, Рыболовная удочка, Рыболовная леска, Пруд, Рыба и "Небо" (или "Окружающая среда").

На объектно-ориентированной земле объекты обычно оказываются умнее, чем вы думаете. Рыбак "имеет" (содержит) FishingRod. Он бросает FishingLine (компонент FishingRod) в Пруд. Пруд «смотрит» на небо, чтобы определить, день это или ночь, а затем бросает кубик, чтобы определить, стоит ли ему ставить рыбу на линию.

Иерархия объектов, которая встряхивает, заключается в том, что FishingLine может по выбору содержать Fish и принадлежит FishingRod, который принадлежит Fisherman. Пруд содержит Рыбу, получает FishingLines, но не «владеет» ими, а также знает о Небе, но не владеет им.

Следующие методы будут выглядеть примерно так:

Fisherman.FishingRod - свойство инициализации (или пара методов получения / установки), используемое, чтобы дать Рыболову FishingRod для FishAt () Pond с. Это необязательно; Рыбак может создать свой собственный FishingRod, или он сам может выбрать его из коллекции FishingRods вместо того, чтобы ему подарили FishingRod.

Fisherman.FishAt (Pond) - скажите Рыбаку, чтобы он использовал FishingRod, чтобы запустить () FishingLine в пруд, затем извлеките () его, чтобы получить рыбу.

FishingRod.Launch (Пруд) - высвобождает рыболовную леску FishingRod в пруд.

FishingRod.Retrieve () - Извлекает FishingLine из пруда, возвращая рыбу, которая также может быть ничем.

Pond.StockWith (Fish []) - Дает Прудовой Рыбе Рыбака, чтобы поймать с FishingRod. Помните, что в ОО-земле все должно быть либо дано, что оно хочет, либо знать, как это сделать; Пруд может так же легко создать Рыбу, если вы хотите следовать этой модели, но пользовательская история здесь не говорит, как это происходит (обычно это означает, что это выходит за рамки этой истории).

Pond.SetFishingLine (FishingLine) - используется FishingRod для помещения своей FishingLine в пруд. Это «движущая функция», которая включает в себя бизнес-логику. Когда это вызывается, Пруд должен спросить Небо, наступил ли день, и, возможно, поставить Рыбку на Леску, основываясь на шансах, указанных во времени дня.

Sky.IsDay () - метод, который возвращает true, если день, и false, если ночь.

Если вы думаете, что Пруд не должен напрямую знать точные правила, согласно которым Рыба попадает на Рыболовную Линию, он может отдать Рыболовную Линию и ее Рыбу [] так называемой «чистой фабрикации». Эта фальсификация, «FishingLogic», будет тем, кто исследует Небо и применяет правила. В процессе разработки это часто полезно, потому что это означает, что FishingLogic может меняться без изменения Pond, если FishingLogic не требуется больше от Pond (например, температура воды).

Различные объекты представляют различные базовые «шаблоны» в реальном программировании:

  • Рыбак - «актер», ближайший аналог нашего пользователя. Пользователь такой системы в основном стоит за плечом актера и говорит ему, что делать.
  • FishingRod - это «помощник» или «утилита». Это реальный аналог «инструмента» и содержит смесь логики состояния и бизнеса, которая помогает ему выполнять очень специфическую задачу.
  • FishingLine в этой модели похож на «запрос» или «команду». Его единственная цель состоит в том, чтобы передаваться от одного объекта к другому, и, когда это происходит, он сигнализирует о том, что получатель должен предпринять конкретное действие.
  • Рыба - это «ответ»; ответ на запрос. Может быть один, а может и нет.
  • Пруд является "хранилищем"; он содержит вещи и обрабатывает запросы внешних объектов на эти вещи в соответствии с набором логики.
  • Небо - это "государственное ведро". Он имеет данные и обеспечивает доступ к этим данным через свой интерфейс.
  • FishingLogic - это «чистое изготовление»;он не имеет аналога «существительного» (объекта) в реальном мире, который мы моделируем, и существует для того, чтобы содержать экологические правила или вещи, которые происходят без того, чтобы модельные объекты не знали, как (как рыба решает попасть на крючок?)
2 голосов
/ 23 сентября 2010

Класс Рыбы также может «смотреть на небо», чтобы решить, насколько он голоден.Класс Pond кажется довольно инертным.

Fisherman, Rod, Line, Fish, Sky

Fisherman.cast(), .drinkBeer(), .chooseRod(), .addLineToRod()
Rod.cast()
Line.cast()
Fish.bite()
Fish.checkDay()
Sky.isDay()
2 голосов
/ 23 сентября 2010

Нет классов. Нет методов. Одна функция с тремя аргументами.

bool launch_rod(bool daytime, float chance_daytime, float chance_night) {
    float chance = daytime ? chance_daytime : chance_night;
    float cast = random_float();
    return cast < chance;
}

Это все, что нужно сделать. Может быть, просто может быть, обернуть все это в классе и создать свойства chance_daytime и chance_night этого класса Все остальное, учитывая спецификации, чрезмерно инженерно.

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