help with understanding the visitor pattern

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

help with understanding the visitor pattern

Pharo Smalltalk Users mailing list
Hello,

Im busy with this project: https://github.com/RoelofWobben/Die

Now I also want to try to add a DieHandler and a Die together.
And I heared you can use the visitor pattern to solve this.

As far asĀ  I understand the pattern I have to make a new class which
contains only the + method.

But I fail to understand to see how I can make a difference between the
+ of a Die and the + of a DieHandler.

So can someone help me understand this pattern and maybe learn me step
by step how to implement this in my code.

Regards,

Roelof


Reply | Threaded
Open this post in threaded view
|

Re: help with understanding the visitor pattern

Richard O'Keefe
First, this is presumably the "Die" exercise from the Pharo track of
exercism.io.
Second, this is a case where
 - there is nothing to a Die other than the number of faces,
   so from a practical point of view there should not be a Die class;
 - there is nothing to a DieHandle other than a sequence of dice,
   so from a practical point of view there should not be a DieHandle
   class (not least because the word "Handle" here makes no sense
   in English and since it may contain many dice it would be better
   as DiceHandle, if only Handle made sense here).
Once you realise that a Die is just an Integer wearing a burqa and a
DIeHandle is just an OrderedCollection or Bag wearing a burqa,
it may be easier to figure out how to combine these things.
Of course it is most unwise to use #+ for combining dice and/or
DieHandles.  Both because + is a confusing choice and because
we already *have* a selector that means "concatenate these two
sequences", namely #,

Looking at my own answer to this, and others, I see that you want
two operations:
  aDieHandle addDie: aDie
  aDieHandle + anotherDieHandle
You are not required to define + with either operation a Die.

One way to do this is to add a new method
  DieHandle >> addAllTo: another [
    dice do: [:each | another addDie: each].
    ^another
  ]
then
  DieHandle >> + another [
    ^another addAllTo: (self addAllTo: DieHandle new))
]

Now if you want to extend this to treat a single Die as if it were a
DieHandle containing itself, just do

  Die >> addAllTo: another [
    another addDie: self.
    ^another
  ]
  Die >> + another [
    ^another addAllTo: (self addAllTo: DieHandle new))
  ]

Now that Die and DieHandle have some selectors in common (and an actual method),
it might make sense to introduce a common superclass.
DiceSet (no data)
  roll    ^self roll: Random default
  roll: rng
  diceNumber
  addAllTo:
  + another ^another addAllTo: (self addAllTo: DieHandle new)
Die < DiceSet (faces)
  roll: rng ^faces atRandom: rng
  diceNumber ^1
  addAllTo: aHandle aHandle addDie: self. ^aHandle
DieHandle < DiceSet (dice)
  roll: rng ^self detectSum: [:die | did roll: rng]
  diceNumber ^dice size
  addAllTo: aHandle dice do: [:die | aHandle addDie: die]. ^aHandle

What we have here is pretty close to the Composite pattern, not the
Visitor pattern.
If a DieHandle could accept DieHandles as elements as well as Die instances, it
would be a bona fide example of Composite, and the code would need a few minor
changes.

The Visitor pattern is a way of dealing with "the Expression Problem".
You don't *have* that problem.
It doesn't seem like a good idea to apply it here.

On Wed, 16 Oct 2019 at 21:33, Roelof Wobben via Pharo-users
<[hidden email]> wrote:

>
> Hello,
>
> Im busy with this project: https://github.com/RoelofWobben/Die
>
> Now I also want to try to add a DieHandler and a Die together.
> And I heared you can use the visitor pattern to solve this.
>
> As far as  I understand the pattern I have to make a new class which
> contains only the + method.
>
> But I fail to understand to see how I can make a difference between the
> + of a Die and the + of a DieHandler.
>
> So can someone help me understand this pattern and maybe learn me step
> by step how to implement this in my code.
>
> Regards,
>
> Roelof
>
>