Распределение ответственности: игра с игроками, каждый из которых имеет банковский счет - PullRequest
1 голос
/ 31 октября 2011

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

Но этот маленький сценарий продолжает беспокоить меня.

Допустим, я разрабатываю простую настольную игру. У меня есть класс Game, который содержит информацию о доске и игроках. Игроки создаются из класса Player. У всех игроков есть банковский счет, созданный из класса BankAccount.

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

Мой банковский счет имеет методы для снятия, пополнения и возврата баланса. Но моя игра не знает о банковском счете игрока. Только про плеер. Должен ли я дать своему классу Player метод getAccount, чтобы я мог вызвать playerObject.getAccount().withdraw()? Или как мне взять на себя ответственность за это поведение? Должен ли мой класс Player реализовать метод withdraw(), который просто вызывает account.withdraw() для своего связанного объекта учетной записи?

Ответы [ 4 ]

3 голосов
/ 31 октября 2011

A Bank должен иметь контроль над BankAccounts, а не player объектами.

Другими словами, Банк должен представлять собой набор BankAccounts плюс некоторые дополнительные методы для управления этими счетами.

Это так, что вы можете делать такие вещи, как:

bank.WithDrawMoney(player, amount);

или

bank.TransferMoney(playerFrom, playerTo, amount);

В этом случае банк будет «искать» счет, который имеет этот игроки извлеките из него соответствующие средства.

Представьте, что это был реальный банковский счет.Человек не несет этот счет с ними, только ссылка на него.Банк несет ответственность за перевод средств (депозиты, снятие средств ..).

Итак, на верхнем уровне у вас будет Game, который содержит такие объекты, как Players, Bank и Board.Он может иметь лучшие методы, такие как RollDice().Правление может иметь такой метод, как Move(player, distance);

1 голос
/ 31 октября 2011

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

В конце концов все сводится к балансу. Если ваш класс аккаунта имеет 20 методов / свойств (давайте проигнорируем аргументы о том, является ли 20 большим числом), то с точки зрения кодирования наличие функции player.getAccount () будет дублировать намного меньше кода, чем 20 функций в проигрывателе. это просто переадресация звонков на счет.

С другой стороны, вы должны помнить, что теперь getAccount () связывает реализацию вашего игрового класса с тем фактом, что у каждого игрока должна быть учетная запись. У вас не может быть игроков, у которых нет банковских счетов.

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

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

1 голос
/ 31 октября 2011

playerObject.getAccount().withdraw() нарушает "Закон" Деметры .

Разоблачение методов для игрока и т. Д., Которые имеют смысл для игрока.Исследуйте Инверсию Control для работы с зависимостями.

0 голосов
/ 28 февраля 2012

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

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

Я понимаю, что вы заявили, что у вас есть класс банковского счета, но если процесс действительно оплачивается Джо Блоггсом наличными (из его тайника в унитазе), Фредом, без какого-либо отношения к банкутогда ему не понадобится банковский счет.Если Фред в какой-то момент решит занести его в банк, а не продолжать набивать его под матрас (или игровую доску), то в этот момент ему понадобится банк и счет.

Предполагается, что игрок может получить / имеетОбращаясь к другим игрокам, первый процесс будет видеть (в Player) что-то вроде:

void payPlayer( player, amount )
{
  spendCash( amount ); // reduces stash by "amount"
  player.recieveCash( amount );

}

Размер тайника денег может быть просто атрибутом класса игрока.

Второе занятие - это совсем другое.Теперь Фред должен сначала сказать своему банку , что он хочет внести 100 долларов, а затем свой банк , либо через дыру в стене, либо в кассе, (будем надеяться) пополнить свой счет.Так что Фреду действительно нужен банк и, возможно, счет.Но почему ему нужна учетная запись ? Какой цели он служит в игре?Это определенно необходимый компонент программы, или это просто потому, что банки - это то, куда деньги идут в реальной жизни?

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

Таким образом, ответ на вопрос о том, как осуществить перевод денег в игре, зависитцеликом и полностью на игровой механике.Если вам действительно нужен класс, подобный банковскому счету, то вполне вероятно, что у вас должен быть банк.Но вы должны спросить себя, зачем вам действительно нужны объекты банковского счета, летающие в первую очередь?И если банковский счет игрока напрямую связан с ними, действительно ли это уже банковский счет или просто Джо опускает руку в унитаз?

...