
Originally Posted by
Manor
I'm sorry to bump this thread up, but I tried the following:
I wanted to see how a very simple application (part of) would turn out using noun-classes with representative roles, and one using doers with actual doer roles. Well, these designs are how I would do it, so there's probably something terrible wrong in the following examples, but ok
The idea was to create a simple betting mechanism (let users bet on a particular match), with the following purposes/requirements:
- Beeing able to bet on a match
- Check for winners when a match is played
- Update finance if a bet is a winner
So I started coding away with the noun approuch, leading to this:
Following Link For entire quote:
http://www.sitepoint.com/forums/show...8&postcount=26
Did you notice how your class names followed how you described the requirements? After laying out your requirements you made a Bet, Match and Finance class. See how your Bet class is responsible for checking if itself is a winner and updating its finance? In normal conversation a Bet does not check if it won. See my point?
To carry on with the same theme, you've added Bets to Matches which doesn't happen in real life, and you can get an owner from Finance. Your code should make sense from a model of the real life domain.
Next you've tried to do things from a "Doers" perspective creating classes called BetPlacer, WinChecker and FinanceHolder. I think this worked out much better because it fit closer to the domain. There are still some problems like, why does a FinanceHolder have an Owner?
Bringing this to the real world domain of placing bets lets use this site:http://www.ildado.com/horse_racing_rules.html as an example of our "domain expert". Ive pulled a few quotes that show how the expert discusses aspects of placing bets etc.
# Bettor (US) - Someone who places or has a bet. A 'Punter' in the UK.
# Bet - A transaction in which monies are deposited or guaranteed.
# Bookie - (U.K.) Short for bookmaker. The person or shop who accepts bets.
# Bookmaker - Person who is licensed to accept bets on the result of an event based on their provision of odds to the customer. (Sportsbook US).
Using these definitions and our new knowledge of the domain, we can re-word our requirements to this:
- A Bettor places Bets.
- A Bookmaker accepts Bets.
- A Bet is a money transaction.
- A Bookmaker pays winning Bettors
- A Bookmaker make Events avaiable to Bet on.
This might yield something like this:
PHP Code:
$bettor = new Bettor();
$bettor->money = 100;
$bookmaker = new BookMaker();
$bookmaker->makeEventAvailable(new Event('Hockey'));
$bookmaker->acceptBet($bettor->placeBet(40, 'Hockey', 5));
$bookmaker->acceptBet($bettor->placeBet(20, 'Hockey', 7));
$bookmaker->updateScore('Hockey', 5);
$bookmaker->payWinners();
class Bettor {
var $money;
function placeBet($amount, $event, $score) {
$this->money -= $amount;
return new Bet($this, $amount, $event, $score);
}
}
class Bet {
var $money;
var $eventName;
var $bettor;
var $score;
function Bet(&$bettor, $money, $eventName, $score) {
$this->bettor =& $bettor;
$this->money = $money;
$this->eventName = $eventName;
$this->score = $score;
}
}
class Event {
var $name;
var $score;
function Event($name) {
$this->name = $name;
}
}
class BookMaker {
var $bets = array();
var $events = array();
function acceptBet($bet) {
$this->bets[] = $bet;
}
function makeEventAvailable($event) {
$this->events[$event->name] = $event;
}
function updateScore($eventName, $score) {
$this->events[$eventName]->score = $score;
}
function payWinners() {
foreach($this->bets as $bet) {
if ($this->events[$bet->eventName]->score == $bet->score) {
$bet->bettor->money += $bet->money * 2;
}
}
}
}
I made a few assumptions here like in these requirements:
- A Bookmaker pays winning Bettors
- A Bookmaker make Events available to Bet on.
I would expect as we learn more about the domain we may find things that change the wording of these requirements. For instance does the bookmaker need to keep track of the amount of money it has? Does the Bookmaker pay winning bettors and if so where is the "domain experts" use of those terms? Does the Bookmaker make Events available? ...
Choosing the name of your classes is very important like marcus says. The language that those classes speak through their methods and dependencies is just as important and should be chosen based on how you speak about them.
Hope this makes sense.
EDIT: Fixed 100 spelling/grammar mistakes.. I rely on spell check as you can tell.
Bookmarks