2010-09-22 4 views
2

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

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

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

Какие методы? я бы ответил: Fisherman.Launch (удочка), FIshingRod.TryToFish (пруд) возвращает булево

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

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

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

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

+2

«Самый элегантный дизайн» в значительной степени зависит от того, что хотят сделать типичные пользователи вашей классной библиотеки. Собирают ли они рыболовные видеоигры? крупномасштабные симуляции Монте-Карло со многими экспериментами по моделированию для изучения истощения инкубатория? Дизайн может быть идеально подходит для одного случая использования и все же быть слишком сложным, плохо приспособленным или даже неспособным к другому варианту использования. Есть проекты, которые были бы плохими для практически любого варианта использования, но его трудно сказать, что дизайн элегантен, не учитывая предполагаемое использование. –

+0

Хорошо, очень хорошо. Позвольте мне уточнить свой вопрос, чтобы я мог сузить возможные ответы. – LaBracca

ответ

7

У меня был бы рыбак, рыбалка, рыбалка, пруд, рыба и «небо» (или «окружающая среда»).

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

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

Методы, которые следуют бы нечто вроде следующего:

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

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

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

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

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

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

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

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

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

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

Большое спасибо, это именно тот ответ, который я искал. Обсуждение FishingLogic очень интересно. Басиально все вещи, которые в реальном мире не делают (пруд не спрашивает небо) могут (это не обязательно, конечно, зависит от того, насколько сложным является сценарий) быть делегированы «чистой фабрикой». Я сохраню этот ответ и просмотрю его снова через несколько месяцев, когда (надеюсь) я использовал OOAD в реальном мире. Благодарю. – LaBracca

+0

Очень хороший ответ! Только один раздражитель: почему пруд добирается, чтобы решить, ставить ли рыбу на линию? Разве рыба сама не могла смотреть на небо и решила пойти на укус или нет? Тогда вы могли бы также иметь «голод», «укусить счастье», «агрессивность» и т. Д. Рыбы, определить, решит ли какая-либо рыба или больше решиться на крючок. –

+0

@Marjan and Keith: так хорошо сказать, что до тех пор, пока модель не будет иметь рыб, один класс должен нести ответственность за то, что на самом деле является решением рыбы (идти или нет на крючке), в этом случае класс FishingLogic имеет смысл? Конечно, если кто-то начинает моделировать рыб, пруд становится более похожим на то, что он есть в реальной жизни: это не смесь воды и рыб, а просто водный консинер для рыб. Итак, если я хорошо понимаю, чем больше классы в домене соответствуют сложности «реального мира», тем больше объекты будут вести себя «точно», как в реальном мире. – LaBracca

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 :) OP сказал, что «это суперсимметричная версия реального мира». Так что, конечно, это слишком сложно. Тем не менее вопросы остаются. –

+3

Это проблема OOA & D. Ответ, который они хотят, будет по-настоящему переработанным. – KeithS

2

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

Fisherman, Rod, Line, Fish, Sky 

Fisherman.cast(), .drinkBeer(), .chooseRod(), .addLineToRod() 
Rod.cast() 
Line.cast() 
Fish.bite() 
Fish.checkDay() 
Sky.isDay() 
Смежные вопросы