SitePoint Sponsor |
|
User Tag List
Results 51 to 63 of 63
-
Jan 12, 2005, 17:00 #51
- Join Date
- Sep 2003
- Location
- Melbourne, Victoria, Australia
- Posts
- 115
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Yet again another fantastic thread. A great deal to think about here.
A simple example you might be able to help me with ... In a common web application, the code will generally be focused on reading data from a store and presenting it in the browser. eg ...
PHP Code:// Example 1
$eb =& new EventBroker();
$event =& $eb->findEventByName( 'myevent' ); // $event is my concern!
$template->setAttribute( 'venue', $event->getVenue() );
$template->setAttribute( 'date', $event->getDate() );
// Example 2
$event =& new Event(); // this also concerns me
$event->setName( 'phpgig' );
$event->setDate( '20050215' );
$eb =& new EventBroker();
$eb->save( $event );
I have an uncomfortable feeling about the numerous noun and simple storage classes I have (Event, Article, NewsItem). They do nothing much apart from getting\setting attributes. Is the logical end to convert these back to simple data arrays? Is this use of a noun acceptable or is there a more appropriate name or direction I can be coming from?
Cheers,
Af
-
Jan 12, 2005, 17:08 #52
- Join Date
- May 2003
- Location
- Calgary, Alberta, Canada
- Posts
- 275
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Manor
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).
- 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;
}
}
}
}
- 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.Last edited by Brenden Vickery; Jan 13, 2005 at 00:40.
-
Jan 12, 2005, 18:24 #53
Afro, in your situation I would ask the following:
Does the event, article or newsitem class expose any methods at all, other than get/set routines? Second, is there some reason you can't skip the classes and use arrays to start with. If your packaging does not add anything more than what a stock datatype can offer, there's no reason to use it. There's one minor caveat...argument type hinting.
function (Event $item);
-
Jan 12, 2005, 18:34 #54
- Join Date
- Sep 2003
- Location
- Melbourne, Victoria, Australia
- Posts
- 115
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Good point.
I was thinking of going back to using arrays to store the data. I think it was a case of 'overdesign' that created those classes anyway. Any drawbacks that people can see to using an array to store that data?
Brenden, that post made heaps of sense. Thanks for ellaborating so much on that idea. Looking forward to your blog article series too.
Thanks again,
Af.
-
Jan 12, 2005, 18:57 #55
I would probably re-evaluate why you made it a class to begin with. Possibly there was an underlying factor. Maybe you actually intended to add reponsibilities to it at some point, or maybe those that are currently part of of another object would be better off within Event? If so, using the class is ok, though I'd rather see you write an abstract IEvent, base CEvent, and then custom event types for each type of event, CCustomEvent, COtherEvent...this way you can write functions like the one below and pass in any class based on IEvent. This may also eliminate the need for a 'type' property within 'Event'.
function ( IEvent $item );
-
Jan 12, 2005, 19:10 #56
- Join Date
- Apr 2003
- Location
- London
- Posts
- 2,423
- Mentioned
- 2 Post(s)
- Tagged
- 0 Thread(s)
Hi...
Originally Posted by Afro Boy
That said there will be a lot of duplication of pretty boring code. You could definitely code generate the classes, or perhaps use some generic class and reflection (with __call() perhaps). Do you need named accessors? Perhaps get($key) and set($key, $value) would result in a simpler one off class. Called Row perhaps?
My favourite is code generation becuase you could generate the DB schema at the same time. That way you wouldn't have to edit both every time you change the schema. I think there are lot's of choices though.
yours, MarcusMarcus Baker
Testing: SimpleTest, Cgreen, Fakemail
Other: Phemto dependency injector
Books: PHP in Action, 97 things
-
Jan 12, 2005, 20:00 #57
My thoughts exactly Marcus. By using __set and __get you can limit which properties are writable by a consumer.
Code:public function __construct($namedValueArray) { $this->_accepted = array('id', 'name'); $this->_readonly = array('id'); // may want to unset any entries that aren't acceptable here... $this->_properties = $namedValueArray; } public function __get($name) { if (in_array($name, $this->_accepted) && array_key_exists($name, $this->_properties)) { return $this->_properties[$name]; } else { // exception or other handling... } } public function __set($name, $value) { if (in_array($name, $this->_accepted) && array_key_exists($name, $this->_properties) && !in_array($name, $this->_readonly)) { $this->_properties[$name] = $value; } else { // exception or other handling... } }
Excuse me for going off on a tangent by posting this code. Back to the discussion...
-
Jan 15, 2005, 14:23 #58
- Join Date
- May 2003
- Location
- Calgary, Alberta, Canada
- Posts
- 275
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Afro Boy
Replace Array with Object : http://www.refactoring.com/catalog/r...ithObject.html
Replace Record with Data Class :http://www.refactoring.com/catalog/r...DataClass.html
Fowler on the mechanics and motivations behind this refactoring:
Originally Posted by Martin Fowler - Refactoring
PHP Code:$event = array();
$event['name'] = 'phpgig';
$event['date'] = '20050215';
// is refactored to:
$event = new Event();
$event->setName( 'phpgig' );
$event->setDate( '20050215' );
Last edited by Brenden Vickery; Jan 15, 2005 at 15:57.
-
Jan 15, 2005, 15:25 #59
- Join Date
- Mar 2004
- Location
- netherlands
- Posts
- 104
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Brenden Vickery
Originally Posted by Brenden Vickery
Originally Posted by Brenden Vickery
Originally Posted by Brenden Vickery
)
I like the rest of your code, but Im not a fan of using an in-between class (bet) to gain access to the bettor. But thats just my personal taste, and probably this is the best way. Nice job
-
Jan 15, 2005, 19:27 #60
- Join Date
- Nov 2001
- Location
- Bath, UK
- Posts
- 2,498
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Brenden Vickery
PHP Code:$event = new Event();
$event['name'] = 'phpgig';
$event['date'] = '20050215';
DouglasHello World
-
Jul 9, 2005, 06:32 #61
- Join Date
- Mar 2004
- Location
- netherlands
- Posts
- 104
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
After I had posted a comment in the "First steps in OOP" thread some time ago, I was hoping to get some comments on the way I tackled the problem (http://www.sitepoint.com/forums/show...6&postcount=17) because it actually just does exactly the same as I've been trying to evaluate and discuss in here, but now on an actual problem. And despite the good critics and discussion in here, critics and comments stayed away on that approach, whereas I was hoping to see some. Does this mean that the approach did well on that subject, or did many of you just fell asleep after my first line, and just didn't care to comment
?
-
Jul 10, 2005, 03:22 #62
- Join Date
- May 2005
- Location
- Holland!
- Posts
- 852
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by lazy_yogi
foreach($this->observers as $observer){
$observer->update($this)
}
this goes for those who would implement the iterator on to their collection class as well....
Cheers,
-GaloBusiness as usual is off the menu folks, ...
-
Jul 10, 2005, 03:34 #63
- Join Date
- May 2005
- Location
- Holland!
- Posts
- 852
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
or:
PHP Code:$event = new EventCollection(); //Creates a new Collection storage
$event->create('phpgig'); //Creates a new event object
$event->setDate('20060215');
$event->add(); //Stores date automaticly, 0 if date = set, add's new event object
$event->invoke(); //triggers it
invoke is a method that is provided by the SPL through the reflection package.
-GaloBusiness as usual is off the menu folks, ...
Bookmarks