Re: Design decision for a game
On Thu, 22 May 2008 13:28:37 -0700, pek <kimwlias@gmail.com> wrote:
[...]
OK.. I think I understand some things here. I won't be fancy, so
threshold is a little overkill (although I did like the idea). What I
see problematic here is this:
class House {
...
public void addCard(Card card) {
// do some things, or probably nothing because the rules would
take care of it
...
// inform listeners
for (HouseListener lstnr : listeners) {
lstnr.cardAdded(this, card);
}
}
...
}
That part seems fine, as far as it goes.
class SixCardsRule implements HouseListener {
...
public void cardAdded(House house, Card card) {
if ( house.getCards().size() == 5 ) {
// then adding this card satisfies this Rule. So,
house.setCards(new ArrayList<Card>());
// Now notify everyone. The 50 is for the score to be added
for (RuleListener lstnrs : listeners) {
lstnrs.ruleSatisfied("Six cards in total",50);
}
}
}
...
}
This part I'm not so sure of.
Without seeing your whole architecture, it's hard to say for sure. But =
it =
seems to me that someone other than the Rule should be maintaining the =
score. I'm not sure if this is the House, or if you have some other cla=
ss =
that's the entire Game. But it seems to me that the Rule should not =
necessarily be raising score-change events itself, but rather should be =
=
calling some method somewhere that adds 50 points to the score. Objects=
=
that need to be notified of score changes would be attached as a listene=
r =
to _that_ object.
Now, if you _also_ want to provide for notification of when a specific =
rule is satisfied, your Rules could allow those listeners to be added. =
=
And they would be notified much as you show above. Except that the scor=
e =
would not necessarily be part of the method parameters, at least not in =
my =
view.
Alternatively, if you _do_ want the Rule notifications to include the =
score, then either _all_ rule-satisfying conditions should affect the =
score, or you need to expand your RuleListener interface so that there a=
re =
different methods, some of which include a point total to be added to th=
e =
score, and others that don't. Or perhaps you provide just one method in=
=
the interface that is the "score changed" notification", and that's sent=
=
separately from other notifications, like "rule satisfied".
Any of these could work. Which is "best" is hard to say. For my tastes=
, =
I'd prefer either the first suggestion or the last. If you intend for =
there only to ever be a single scoring object, then the first might be =
more appropriate. Then each Rule would have to know which object was th=
at =
single scoring object and would directly call a method on that object to=
=
update the score.
On the other hand, if you want your design to be more flexible, such tha=
t =
you can have multiple scorers present, then it probably makes more sense=
=
for the Rules to use the RuleListener interface to report score changes.=
=
Each scoring object can then subscribe as appropriate to the rules =
relevant for that scoring object.
As an example of this, consider something like (following your previous =
=
listener interface pattern...you may want to consider instead following =
=
the usual Java model, where an "Event" class is defined that includes al=
l =
of the relevant data, including the source and the specifics of the even=
t):
public interface RuleListener
{
void ruleSatisfied(Rule sender, string ruleName);
void scoreChange(Rule sender, int points);
}
Then scoring objects can subscribe to the Rules as needed, and the UI an=
d =
other interested objects can also subscribe. If it turns out that there=
's =
little or no overlap between these two types of subscribers, you might =
even break the interface into two, with one interface dedicated to thing=
s =
that are just "activity notification" sorts of things, and the other =
dedicated to things that actually change the game state. Often one even=
t =
from each might be raised, but only objects of the appropriate =
functionality would subscribe to the specific listener group. That way =
=
you don't waste a lot of time having, for example, having UI objects =
receiving and ignoring notifications for game state changes, and having =
=
game state objects receiving and ignoring notifications for UI events.
I think ultimately I'd go with _some_ variation on this last approach =
(that is, the one where the Rule supports listeners for events separated=
=
into appropriate categories, whether in the same interface or in two or =
=
more), but any of the above would probably work (including what you =
posted, if you really want to do it that way).
By the way, I'm not sure that the House should expose the collection =
implementation. That is, rather than a "setCards" method that takes the=
=
actual collection, it probably makes more sense to have a "clearCards" =
method that resets the internal implementaton. If you really need a way=
=
to add or set multiple cards at once from a non-empty collection, you =
could still have a more general-purpose method that takes a List<Card> =
instead of some specific collection type.
Pete