Какой дизайн наиболее элегантен для этой простой проблемы с OOAD?

2

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

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

Какие классы определить? Я бы ответил: Рыбак, Рыбалка, Понд, День (для моделирования ночью и днем).

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

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

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

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

UPDATE: Первый комментарий к вопросу и ответы на вопрос, чтобы заставить меня быть более конкретным. Как я уже писал выше, "это суперсимметричная версия реального мира", в любом случае позвольте сказать, что я хочу увеличить сложность позже, а не увеличивать ее, допустим, увеличить ее достаточно, чтобы было хорошо, чтобы все классы, перечисленные мной выше (например, потому что я отслеживаю, сколько рыб есть в пруду, как устал рыбак,...). В любом случае наиболее интересными для меня вопросами являются "как моделировать вероятность" и "внешние факторы". Рассматривайте это как вопрос новичков для людей, которые не имеют большого количества навыков в OOAD.

  • 2
    «Самый элегантный дизайн» в значительной степени зависит от того, что хотят делать обычные пользователи вашей библиотеки классов доменов. Они создают рыболовные видеоигры? крупномасштабные симуляции Монте-Карло с множеством симуляционных испытаний для изучения истощения инкубатория? Конструкция может идеально подходить для одного варианта использования, но при этом быть слишком сложной, неподходящей или даже не подходящей для другого варианта использования. Существуют дизайны, которые могут быть плохими практически для любого случая использования, но трудно сказать, что дизайн элегантен без учета предполагаемого использования.
  • 0
    Хорошо, очень хороший момент. Позвольте мне обновить мой вопрос, чтобы я мог сузить возможные ответы.
Теги:
oop

3 ответа

7
Лучший ответ

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

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

Иерархия объектов, которая встряхивается, заключается в том, что FishingLine может дополнительно содержать Рыбу и принадлежит Рыболовству, принадлежащему Рыбаку. Пруд содержит рыбу, получает FishingLines, но не "владеет" ими, а также знает, но не владеет Sky.

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

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

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

FishingRod.Launch(Pond) - Освобождает Fishing Fishing RolfLine в пруду.

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

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

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

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

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

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

  • Рыбак - это "актер", ближайший аналог нашего пользователя. Пользователь такой системы в основном стоит над плечом актера и говорит ему, что делать.
  • FishingRod - это "помощник" или "полезность". Это реальный аналог "инструмента" и содержит смесь государственной и бизнес-логики, которая помогает ему выполнять очень специфическую задачу.
  • FishingLine в этой модели похожа на "запрос" или "команда". Его единственная цель - дать от одного объекта другому, и когда это произойдет, оно сигнализирует, что получатель должен принять конкретное действие.
  • Рыба - это "ответ"; ответ на запрос. Может быть один, может быть, и нет.
  • Пруд - это "хранилище"; он содержит вещи и обрабатывает запросы внешних объектов для этих вещей в соответствии с набором логик.
  • Sky - это "ведро штата". Он имеет данные и обеспечивает доступ к этим данным через свой интерфейс.
  • FishingLogic - это "чистое изготовление"; он не имеет аналога с "существительным" (объектом) в реальном мире, который мы моделируем, и существует, чтобы содержать экологические правила или вещи, которые происходят без того, чтобы объекты модели знали (как рыба решает пойти на крючок?)
  • 0
    Большое спасибо, это именно тот ответ, который я искал. Обсуждение FishingLogic очень интересно. В сущности, все вещи, которые в реальном мире не делают (пруд не спрашивает небо), можно (это не обязательно, конечно, зависит от того, насколько сложен сценарий) делегировать «чистому выдумке». Я сохраню этот ответ и рассмотрю его снова через несколько месяцев, когда (надеюсь) я использовал OOAD в реальном мире. Благодарю.
  • 0
    Очень хороший ответ! Только один раздражитель: почему пруд решает, ставить ли рыбу на леску? Неужели сама рыба не смотрит на небо и решает пойти на укус или нет? В конечном итоге вы также можете иметь «голод», «укус счастья», «агрессивность» и т. Д. Рыбы, чтобы определить, решит ли какая-нибудь одна или несколько рыб совершить рывок на крючке.
Показать ещё 3 комментария
2

Класс рыбы также может "смотреть на небо", чтобы решить, насколько он голоден. Класс пруда кажется довольно инертным.

Fisherman, Rod, Line, Fish, Sky

Fisherman.cast(), .drinkBeer(), .chooseRod(), .addLineToRod()
Rod.cast()
Line.cast()
Fish.bite()
Fish.checkDay()
Sky.isDay()
2

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

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 этого класса. Все остальное, учитывая спецификации, является чрезмерным.

  • 0
    Lol :) ОП сказал, что "это упрощенная версия случая из реального мира". Так что, конечно, он перегружен. Вопросы все еще стоят, хотя.
  • 3
    Это проблема OOA & D. Ответ, который они хотят получить, будет слишком сильным по определению.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню