This is a discussion on Does a pattern exist within the Software Patterns forums, part of the Testing category; I try to make a design in Java and am looking for a pattern to solve my problem. I can ...
|
|||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
Does a pattern exist
I try to make a design in Java and am looking for a pattern to solve my
problem. I can best describe this with an example application: a pinball machine. A pinball machine consists of different kind of objects (a bumper, a flipper, a tab, a light, ...) I could derive all these from a common HitableByBall. I also have two kinds of Balls (RoundBall and EllipsoidBall), and as more than one ball can be on the board at the same time, so they could hit each other too, so I should derive Ball also from HitableByBall. To implement the pinball machine, I would have to describe the interactions between a ball and a bumper, a ball and a flipper, .... In the superclasses, I could write if 'this ball hits any HitableByBall', call the relevant interaction method. I can use inheritance to make a distinction between the two kinds of balls, but within some method this.Interact(HitableByBall h), i would have to fall back to a switch statement for each kind of hittable object. Is there a better way ? I think there must be some pattern that defines a separate 'interaction object' for each combination of HitableByBall types, but then I don't know how to effectively bind and select the correct type of interaction object when two HitableByBall come into contact with each other. Did anyone recognize this type of problem ? |
|
|||
|
Re: Does a pattern exist
On Tue, 07 Oct 2003 16:29:17 +0000, Jan Vereecke wrote:
> I try to make a design in Java and am looking for a pattern to solve my > problem. I can best describe this with an example application: a pinball > machine. [snip] > I think there must be some pattern that defines a separate 'interaction > object' for each combination of HitableByBall types, but then I don't know > how to effectively bind and select the correct type of interaction object > when two HitableByBall come into contact with each other. Did anyone > recognize this type of problem ? Sound very likely to be MultipleDispatch. Maybe a DoubleDispatch is sufficiently, if so then the easiest implementation are VisitorPattern. -- Simon Strandgaard |
|
|||
|
Re: Does a pattern exist
Hi Jan,
interesting question. >A pinball machine consists of different kind of objects (a bumper, a >flipper, a tab, a light, ...) I could derive all these from a common >HitableByBall. It should be recognized that HitableByBall would probably end up as a base class for ALL objects within the play region of the flipper machine because walls, the ground plate and even the covering glass pane are hittable objects in the end. >To implement the pinball machine, I would have to describe the interactions >between a ball and a bumper, a ball and a flipper, .... You are raising one of the most crucial questions in game design there: Who is responsible for regulating physical interactions? In your pinball paradigma you could take at least three standpoints: 1. The ball hits the bumper, so the ball must alter speed and direction itself 2. The bumper pushes the ball, so the bumper has to change the ball's direction and velocity 3. Ball and bumper collide, so some external instance has to decide how this affects both objects The first two suggestions pose serious problems in certain situations, especially when two balls are in the game. With two balls colliding it is not clear which of the two balls is the "active" element that shall change the others' parameters (suggestion 2) or which change will occur first (suggestion 1). Hence, I always advocate the solution of the "omnipotent third" that evaluates collisions, adheres to laws of nature (e. g. gravity) and thereupon administers the changes. Now the question arises how the omnipotent third gains knowledge of the collision. This is a crucial problem because none of the elements within the pinball machine have any idea about the position of any other object that might be in there as well. To accomplish a design where each object (or at least each ball) knows where every other object is located you would have to propagate position messages from every single object to every other, thereby enabling each object to detect a collision with another one. But then again, with two balls colliding, both would recognize a collision and take measures to react to it. Complete mayhem! I would thus recommend the following solution: 1. Movement Initiation Phase: A VISITOR iterates through all objects in the game and tells them to Move(). 2. Movement Phase: Every object knows its coordinates, velocity and direction of motion. It updates its position and does a Notify() on all OBSERVERs attached to it. 3. Movement Propagation Phase: The responsible Observer issues a MESSAGE (or COMMAND) to the omnipotent third. The command must contain the game element the observer got notified by and - for convenience - the position of that element. 4. Collision Detection Phase: The omnipotent third (a SINGLETON by all means) evaluates position messages and checks for collisions. If a collision between two objects is detected, it calls a CreateVisitor(object1, object2) from a FACTORY. 5. Primary Update Phase: The VISITOR which was just created visits both of the objects, considers laws of nature and updates velocity and direction to both objects. 6. Secondary Update Phase: The omnipotent third now might additionally call an OBSERVER himself which would then trigger the scoring mechanism, take an element out of the game or else. 7. Step 1 again You might wonder why phase 2 exists because every element could as well be self responsible for propagating a position message to the omnipotent third. But phase 2 is crucial for events which do occur independently of the omnipotent third. Suppose you would like to add some twinkling to a rolling ball. Just attach a second "twinkle-observer" to the ball and let this observer trigger changes in twinkling. >I can use inheritance to make a >distinction between the two kinds of balls, but within some method >this.Interact(HitableByBall h), i would have to fall back to a switch >statement for each kind of hittable object. That fairly complex switching hierarchy is in the above design decentralized across the FACTORY class (phase 4), where there is one CreateVisitor()-method for each possible collision. These methods return specialized VISITORs which exactly know what to do to the two colliding objects. HTH, Malte --- The above e-mail address is not valid. To contact me, please use my real e-mail address: malte AT t DASH online DOT de Just replace the capitalized words with the corresponding punctuation marks. |
|
|||
|
Re: Does a pattern exist
Thanks for your answer. It will take some time to think it through.
It is definitely a good discussion on how to tackle this particular problem. I think it's also a good basis for the more general problem where any two objects of a same baseclass interact in a way that is dependent of the actual subclass of the two baseclasses. (e.g. chemical elements, color-mixing, geometrical problems, ...). I am just wondering: my main 'problem' was that I did not see a way to get out of the "giant switch statement", which any OO book tells you to avoid. I believe that your omnipotent third will still contain such a giant switch ? > 4. Collision Detection Phase: The omnipotent third (a SINGLETON by all > means) evaluates position messages and checks for collisions. If a > collision between two objects is detected, it calls a > CreateVisitor(object1, object2) from a FACTORY. To avoid it, I was thinking about a scheme where each object could contain a list of interaction objects: one for each other type of object it could interact with. In the initialization phase, these VISITORS would be attached to the object. When two objects collide, the lists are compared, and the interaction object that is common to both is called. This would avoid the switch (at the cost of very expensive comparisons) and create an omnipotent third that is independent of any future kinds of objects. Whether or not this is feasible will be highly dependent on how complex and varied the interactions are, and especially on the costs of always comparing lists of interaction objects. (this might still be feasible if the lists are short or if RTTI and call-by-method-signature is used). Thanks |
|
|||
|
Re: Does a pattern exist
On Wed, 08 Oct 2003 13:19:04 +0000, Jan Vereecke wrote:
> Simon Strandgaard <qj5nd7l02@sneakemail.com> wrote in > news an.2003.10.07.16.49.00.546017@sneakemail.com:> >> MultipleDispatch, DoubleDispatch > could you give a reference to something discussing these patterns ? Sorry I don't know any Java resources on this topic (I use C++Ruby). The ModernC++Design book has a good chapter about this topic. But it is probably not the easiest place to start getting familiar with a new pattern. http://www.moderncppdesign.com/ http://sourceforge.net/projects/loki-lib/ A quick google-search on 'multiple dispatch' yields many result, but they seems to be: C++, dylan, and in .pdf!! very low signal2noise ratio. Anyone who know some good links ? -- Simon Strandgaard |
|
|||
|
Re: Does a pattern exist
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 In article <Xns940E91A5F9FE3jvab1@193.210.197.139>, on 08 Oct 2003 12:19:04 GMT, Jan Vereecke <jan.N0SPAMvereecke@advalvasN0SPAM.be> wrote: | Simon Strandgaard <qj5nd7l02@sneakemail.com> wrote in | news an.2003.10.07.16.49.00.546017@sneakemail.com:| | > MultipleDispatch, DoubleDispatch | could you give a reference to something discussing these patterns ? Learn to use google. <http://www.google.co.uk/search?hl=en&lr=&ie=UTF-8&oe=utf-8&q=%2Bdouble+dispatch+%2Bpattern+%2Bjava&spell=1> <http://www.google.co.uk/search?hl=en...gle+Search&met a=> <davidp /> - -- David Postill -----BEGIN PGP SIGNATURE----- Version: PGP 8.0.2 - not licensed for commercial use: www.pgp.com Comment: Get key from pgpkeys.mit.edu:11370 iQA/AwUBP4SuXXxp7q1nhFwUEQIkGQCg3VTZMXRAFwahCMVYSkMPi6fuZc0AmwXU PtUTzKmfw4nj6/OgfzmLJA+Q =KDaR -----END PGP SIGNATURE----- |
|
|||
|
Re: Does a pattern exist
>I am just wondering: my main 'problem' was that I did not see a way to
>get out of the "giant switch statement", which any OO book tells you to >avoid. I believe that your omnipotent third will still contain such a >giant switch ? Nope. No switch statement in my code. The compiler does things for you. Imagine the following situation: You have three types of objects that can interact pairwise. These three object types are ClassA ClassB ClassC So you end up with the three possible interactions A-B, A-C and B-C. Now instead of implementing a switch statement that might get inmanageable in very short time, the following FACTORY comes in handy: class InteractionFactory { ABInteractionClass CreateInteraction(ClassA a, ClassB b); ACInteractionClass CreateInteraction(ClassA a, ClassC c); BCInteractionClass CreateInteraction(ClassB b, ClassC c); }; Sorry for the C++ code but I'm sure you get the idea. The return objects of type XYInteractionClass are classes that know what to do to the two objects that have collided. You might call them interaction managers or so. Now look at how things are going to work during runtime when two objects interact: 1. A and B collide 2. Somebody recognizes the collision 3. This somebody now calls "InteractionFactory.CreateInteraction(A,B)" The return object (an interaction manager) is exactly the one you want since the compiler selects it for you based on the types of the two objects. 5. The interaction takes place and on it goes See, no switch statement! >I was thinking about a scheme where each object could >contain a list of interaction objects: Well, this would surely solve your problem in many cases but two issues can arise with that approach. First, suppose objects A and B come together for an interaction to occur. Which of the two is now responsible for starting the interaction? And who controls the interaction process. Here the MULTIPLEDISPATCH pattern really has its merits, like Simon recommended. Second, what if the interaction was moderated by external conditions? Suppose, for example, a zero-gravity bonus in the pinball machine or a happy-hour rebate in a billing system. You would then have to update every single element in your system with a new list of interaction objects every time the external condition changes. And to complicate things even further, remember the PacMan game with those tiny pills that could make PacMan invulnerable for encounters with the evil haunters. In a multiplayer situation you would have situations where the interactions of one PacMan were totally different from those of the other players' PacMans. I would implement this not with a conditional statement in the interaction object but instead with a new set of interaction objects for that single PacMan. My recommendation thus remains to take the interaction objects out of the elements and install them at another level. Regards, Malte --- The above e-mail address is not valid. To contact me, please use my real e-mail address: malte AT t DASH online DOT de Just replace the capitalized words with the corresponding punctuation marks. |
|
|||
|
Re: Does a pattern exist
> Sorry I don't know any Java resources on this topic (I use C++Ruby).
What has Ruby other modern most used languages dont have. I mean in relation to the opportunity Ruby "can give the industry"? I ask because few secs of browsing at its site shown me another yet free scripting language derriving syntax from other langs offering nothing new to me after those few secs gaze which didnt inspire me to look more for details. Any good points to go back and take more serious look at? greetings, Daniel Biesiada |
|
|||
|
Re: Does a pattern exist
"Daniel Biesiada" <spam@no.thank.you> skrev i en meddelelse
news:bmm6n9$r0t$1@atlantis.news.tpi.pl... > > Sorry I don't know any Java resources on this topic (I use C++Ruby). > > What has Ruby other modern most used languages dont have. > I mean in relation to the opportunity Ruby "can give the industry"? > I ask because few secs of browsing at its site shown me another yet free > scripting language derriving syntax from other langs offering nothing new > to me after those few secs gaze which didnt inspire me to look more > for details. Any good points to go back and take more serious look at? Citing Ruby's author Matz; "The purpose of Ruby is to maximize programming pleasure." I think also Ruby's purpose is to minimizing the programmers stress level. These 2 things is what Ruby has, what no other languages has... prove me wrong :-) Before I knew Ruby, I wrote pseudocode before implementing things in C++. That code were actually 98% correct Ruby code. Unbelievable..but true. Besides that Ruby is pure obejct oriented, meaning that everything is an object which you can inspect or extend (Neither C++, Java, Python is true oo). There is an interesting slideshow presentation here: http://www.ruby-lang.org/en/jaoo2001/index.html Great introduction + reference: http://www.rubycentral.com/book/ There also exists a number of physical books: http://www.rubygarden.org/ruby?RubyBookList In my sparetime I work on a programmers editor written in Ruby: http://aeditor.rubyforge.org/ -- Simon Strandgaard |