From: Christopher on
originally posted in comp.lang.c++ and referred here:

The observer pattern itself is easy enough. I've implemented it using
a Event that contains data for any Event type I forsee my application
using. My problem is I don't want one and only one general purpose
type of Event. I want to write my design in such a way that more Event
Types can be created and used down the road as needed. How can you
design the Events in such a way that more can be handled later by the
same Observer and Subject classes when they don't know what your
Events look like right now?

I thought about using an enum or string Identifier in the Base Event
class to tell which of the derived Events to cast to, but that is no
good, because every time someone makes a new derived class they have
to modify a seperate library. yucky.
From: Daniel Pitts on
Christopher wrote:
> originally posted in comp.lang.c++ and referred here:
>
> The observer pattern itself is easy enough. I've implemented it using
> a Event that contains data for any Event type I forsee my application
> using. My problem is I don't want one and only one general purpose
> type of Event. I want to write my design in such a way that more Event
> Types can be created and used down the road as needed. How can you
> design the Events in such a way that more can be handled later by the
> same Observer and Subject classes when they don't know what your
> Events look like right now?
>
> I thought about using an enum or string Identifier in the Base Event
> class to tell which of the derived Events to cast to, but that is no
> good, because every time someone makes a new derived class they have
> to modify a seperate library. yucky.
How about this, follow the Java example and make every type event have a
corresponding type of Listener. Your event sources would have
addFooListener(FooListener) and your FooListener has a
fooHandler(FooEvent) Repeat the process for BarEvent events.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Christopher on
On Nov 20, 7:54 pm, Daniel Pitts
<newsgroup.spamfil...(a)virtualinfinity.net> wrote:
> Christopher wrote:
> > originally posted in comp.lang.c++ and referred here:
>
> > The observer pattern itself is easy enough. I've implemented it using
> > a Event that contains data for any Event type I forsee my application
> > using. My problem is I don't want one and only one general purpose
> > type of Event. I want to write my design in such a way that more Event
> > Types can be created and used down the road as needed. How can you
> > design the Events in such a way that more can be handled later by the
> > same Observer and Subject classes when they don't know what your
> > Events look like right now?
>
> > I thought about using an enum or string Identifier in the Base Event
> > class to tell which of the derived Events to cast to, but that is no
> > good, because every time someone makes a new derived class they have
> > to modify a seperate library. yucky.
>
> How about this, follow the Java example and make every type event have a
> corresponding type of Listener. Your event sources would have
> addFooListener(FooListener) and your FooListener has a
> fooHandler(FooEvent) Repeat the process for BarEvent events.
>
> --
> Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

I guess that I am trying to avoid having class declarations like
class A : public ListenerB : public ListenerC : public ListenerD :
public ListenerE......: public Listener Z

I also had hopes of sorting the events by time and placing them all
inside one container, but I think I can achieve that with a base event
type.

It may still be the best way so far. Thanks.
From: Patrick May on
Christopher <cpisz(a)austin.rr.com> writes:
> The observer pattern itself is easy enough. I've implemented it
> using a Event that contains data for any Event type I forsee my
> application using. My problem is I don't want one and only one
> general purpose type of Event. I want to write my design in such a
> way that more Event Types can be created and used down the road as
> needed. How can you design the Events in such a way that more can be
> handled later by the same Observer and Subject classes when they
> don't know what your Events look like right now?

I'm not sure I understand the problem you're trying to address.
If all of your events inherit from the (abstract) base Event class,
then you can pass any instance of one of those classes to an Observer
that accepts Event objects.

If you want to execute logic that is specific to a particular
subtype of Event without modifying your Observer implementation, you
have a few options. One is to encapsulate the behavior in the Event
subtype and simply call a method like execute() on the Event object
when it is received. Another, more flexible option is to use the
Chain of Responsibility pattern to register Event handlers
dynamically.

> I thought about using an enum or string Identifier in the Base Event
> class to tell which of the derived Events to cast to, but that is no
> good, because every time someone makes a new derived class they have
> to modify a seperate library. yucky.

Tres yucky. I've used Chain of Responsibility to decouple
implementation from interface in several large systems. It's easier
in languages that allow dynamic loading of new classes, but can be
done in C and C++ with dlopen and friends. Applying the pattern in a
service oriented system is even easier.

Regards,

Patrick

------------------------------------------------------------------------
S P Engineering, Inc. | Large scale, mission-critical, distributed OO
| systems design and implementation.
pjm(a)spe.com | (C++, Java, Common Lisp, Jini, middleware, SOA)
From: Daniel Pitts on
Christopher wrote:
> On Nov 20, 7:54 pm, Daniel Pitts
> <newsgroup.spamfil...(a)virtualinfinity.net> wrote:
>> Christopher wrote:
>>> originally posted in comp.lang.c++ and referred here:
>>> The observer pattern itself is easy enough. I've implemented it using
>>> a Event that contains data for any Event type I forsee my application
>>> using. My problem is I don't want one and only one general purpose
>>> type of Event. I want to write my design in such a way that more Event
>>> Types can be created and used down the road as needed. How can you
>>> design the Events in such a way that more can be handled later by the
>>> same Observer and Subject classes when they don't know what your
>>> Events look like right now?
>>> I thought about using an enum or string Identifier in the Base Event
>>> class to tell which of the derived Events to cast to, but that is no
>>> good, because every time someone makes a new derived class they have
>>> to modify a seperate library. yucky.
>> How about this, follow the Java example and make every type event have a
>> corresponding type of Listener. Your event sources would have
>> addFooListener(FooListener) and your FooListener has a
>> fooHandler(FooEvent) Repeat the process for BarEvent events.
>>
>> --
>> Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
>
> I guess that I am trying to avoid having class declarations like
> class A : public ListenerB : public ListenerC : public ListenerD :
> public ListenerE......: public Listener Z
>
> I also had hopes of sorting the events by time and placing them all
> inside one container, but I think I can achieve that with a base event
> type.
>
> It may still be the best way so far. Thanks.
I can see why you would want to avoid that. Makes me realize the beauty
of anonymous inner classes in Java :-)

The problem is that any runtime information you might add to the event
(such as an EventType token) is likely to cause a few "switch"
statements (or switch like constructs), and that is often (not always)
an indication of poor-OO design. The decision of which behavior to
invoke should usually be polymorphic or delegated, not
flowing-conditionals. Unless your in lisp :-)

It might be better to group similar events and have one or few Listener
classes that have default noop virtual functions for the event handlers.
This is similar to the visitor pattern, and could even be implemented
as such on the event dispatcher:

void FooEvent::dispatchEventTo(Listener &listener) {
listener.foo(*this);
}

void BarEvent::dispatchEventto(Listener &listener) {
listener.bar(*this);
}

Warning, this may be a Java centric approach.
--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>