473,738 Members | 2,009 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Observer Design Pattern

Hello All!

I am trying to implement my own Design Patterns Library.
I have read the following documentation about Observer Pattern:
1) Design Patterns by GoF
Classic description of Observer. Also describes implementation
via ChangeManager (Mediator + Singleton)
2) Pattern hatching by John Vlissides
Describes Observer's implementation via Visitor Design Pattern.
3) Design Patterns Explained by Alan Shalloway and James Trott
Describes Observer's implementation via Adaptor Design Pattern.
4) CUJ's article : "Prying eyes : A Policy-Based Observer I,II" by
Andrei Alexandrescu
Very interesting articles, which describes attempt to implement
a policy-based Observer and several serious problems:
a) Mutual recursion (potential infinite loops, etc...)
b) Active observers problem (iteration problem)
c) Notification order problem
d) GetState()'s return value problem

I am trying to combine best aspects of each approach.

Consider the following pseudo-code example:

class Subject
{
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;

virtual @@@ GetState() = 0; // !!! What type should be
returned???
};

class Observer
{
public:
virtual void Update(Subject* ) = 0;
};

class MySubject : public Subject
{
public:
void Attach(Observer *)
{
/// Add pair
}
void Detach(Observer *)
{
/// Delete pair
}
void Notify()
{
/// Call observer->Update(this) for each observer in mapping
}

@@@ GetState()
{
/// Return MySubject-specific data. BUT HOW???
}
private:
// Subject-Observer mapping
// MySubject-specific data
};

class YourSubject : public Subject
{
public:
// Along similar lines
private:
// Subject-Observer mapping
// YourSubject-specific data
};

class MyObserver : public Observer /// This class represents MySubject
and YourSubject
{
public:
void Update(Subject* s)
{
/// Only Subject's interface is available here (not MySubject
or YourSubject)
/// I know one bad solution - type switch via dynamic_cast.
if TypeOf(s) == MySubject
{
/// Update MySubject-specific part of representation
}
else if TypeOf(s) == YourSubject
{
/// Update YourSubject-specific part of representation
}
}
private:
/// MyObserver-specific data (e.g. GUI widgets for subjects
representation)
};
The problem lies in poor Subject's interface.
Subject doesn't know anything about MySubject's private data.

I don't understand why GoF includes GetState method in Subject's
interface.
Type of GetState()'s return value depends up concrete subclass of
Subject, i.e.
class ConcreteSubject : Subject
{
public:
ReturnValue<Con creteSubject> GetState();
...
};

Main question:
How to avoid type switching in ConcreteObserve r::Update(Subje ct* s)?

Thanks!

P.S.
Sorry for my english :)

May 31 '06 #1
22 4731

Krivenok Dmitry wrote:
Hello All!

I am trying to implement my own Design Patterns Library.
I have read the following documentation about Observer Pattern:
1) Design Patterns by GoF
Classic description of Observer. Also describes implementation
via ChangeManager (Mediator + Singleton)
2) Pattern hatching by John Vlissides
Describes Observer's implementation via Visitor Design Pattern.
3) Design Patterns Explained by Alan Shalloway and James Trott
Describes Observer's implementation via Adaptor Design Pattern.
4) CUJ's article : "Prying eyes : A Policy-Based Observer I,II" by
Andrei Alexandrescu
Very interesting articles, which describes attempt to implement
a policy-based Observer and several serious problems:
a) Mutual recursion (potential infinite loops, etc...)
b) Active observers problem (iteration problem)
c) Notification order problem
d) GetState()'s return value problem

I am trying to combine best aspects of each approach.

Consider the following pseudo-code example:

class Subject
{
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;

virtual @@@ GetState() = 0; // !!! What type should be
returned???
};

class Observer
{
public:
virtual void Update(Subject* ) = 0;
};

class MySubject : public Subject
{
public:
void Attach(Observer *)
{
/// Add pair
}
void Detach(Observer *)
{
/// Delete pair
}
void Notify()
{
/// Call observer->Update(this) for each observer in mapping
}

@@@ GetState()
{
/// Return MySubject-specific data. BUT HOW???
}
private:
// Subject-Observer mapping
// MySubject-specific data
};

class YourSubject : public Subject
{
public:
// Along similar lines
private:
// Subject-Observer mapping
// YourSubject-specific data
};

class MyObserver : public Observer /// This class represents MySubject
and YourSubject
{
public:
void Update(Subject* s)
{
/// Only Subject's interface is available here (not MySubject
or YourSubject)
/// I know one bad solution - type switch via dynamic_cast.
if TypeOf(s) == MySubject
{
/// Update MySubject-specific part of representation
}
else if TypeOf(s) == YourSubject
{
/// Update YourSubject-specific part of representation
}
}
private:
/// MyObserver-specific data (e.g. GUI widgets for subjects
representation)
};
The problem lies in poor Subject's interface.
Subject doesn't know anything about MySubject's private data.

I don't understand why GoF includes GetState method in Subject's
interface.
Type of GetState()'s return value depends up concrete subclass of
Subject, i.e.
class ConcreteSubject : Subject
{
public:
ReturnValue<Con creteSubject> GetState();
...
};

Main question:
How to avoid type switching in ConcreteObserve r::Update(Subje ct* s)?

Thanks!

P.S.
Sorry for my english :)


Maybe you should try to avoid reading to many design books. You can
start by forgeting everything you read in the GoF book (unless you
interested in making your life as programmer harder and your code more
complicated)

May 31 '06 #2
bo*******@yahoo .com wrote:
Krivenok Dmitry wrote:
Hello All!

I am trying to implement my own Design Patterns Library.
I have read the following documentation about Observer Pattern:
1) Design Patterns by GoF
Classic description of Observer. Also describes implementation
via ChangeManager (Mediator + Singleton)
2) Pattern hatching by John Vlissides
Describes Observer's implementation via Visitor Design Pattern.
3) Design Patterns Explained by Alan Shalloway and James Trott
Describes Observer's implementation via Adaptor Design Pattern.
4) CUJ's article : "Prying eyes : A Policy-Based Observer I,II" by
Andrei Alexandrescu
Very interesting articles, which describes attempt to implement
a policy-based Observer and several serious problems:
a) Mutual recursion (potential infinite loops, etc...)
b) Active observers problem (iteration problem)
c) Notification order problem
d) GetState()'s return value problem

I am trying to combine best aspects of each approach.

Consider the following pseudo-code example:
[snipped code]
Main question:
How to avoid type switching in ConcreteObserve r::Update(Subje ct* s)?


Maybe you should try to avoid reading to many design books. You can
start by forgeting everything you read in the GoF book (unless you
interested in making your life as programmer harder and your code
more complicated)


Maybe you could back that up with some specific instances?

Jeff Flinn
May 31 '06 #3
Krivenok Dmitry wrote:
Hello All!

I am trying to implement my own Design Patterns Library.
You can't do that in general. Design Patterns are at a level higher
than simple code reuse. That said...

The classic "pull model" can be implemented like this:

class Observer
{
public:
virtual ~Observer() { }
virtual void update() = 0;
};

class Subject
{
std::set< Observer* > observers;
public:
void attach( Observer* o ) {
observers.inser t( o );
}

void detach( Observer* o ) {
observers.erase ( o );
}

void notify() {
for_each( observers.begin (), observers.end() ,
mem_fun( &Observer::upda te ) );
}
};
class MySubject : public Subject
{
int state;
public:
int getState() const { return state; }
void setState( int value ) { state = value; notify(); }
};

class MyObserver : public Observer
{
MyObserver( const MyObserver& );
MyObserver& operator=( const MyObserver& );

MySubject* subject;

public:
MyObserver( MySubject* subject_ ): subject( subject_ ) {
subject->attach( this );
}

~MyObserver() {
subject->detach( this );
}

void update() {
// do something with subject->getState();
}
};

However, I have found the "push model" to be much more useful:

template < typename Observer >
class Subject {
std::set< Observer* > observers;

public:
void attach( Observer* o ) {
observers.inser t( o );
}

void detach( Observer* o ) {
observers.erase ( o );
}

template < typename ConcreteSubject >
void notify( const ConcreteSubject * cs, void (Observer::*fn) ( const
ConcreteSubject * ) ) {
std::set< Observer* >::iterator it = observers.begin ();
while ( it != observers.end() ) {
Observer* ob( *it++ );
(ob->*fn)( cs );
}
}
};
I don't understand why GoF includes GetState method in Subject's
interface.
They did that because they were looking at SmallTalk examples which
didn't translate well to C++
Main question:
How to avoid type switching in ConcreteObserve r::Update(Subje ct* s)?


As I showed above.

May 31 '06 #4
Krivenok Dmitry wrote:
Hello All!

I am trying to implement my own Design Patterns Library.
I have read the following documentation about Observer Pattern:
1) Design Patterns by GoF
Classic description of Observer. Also describes implementation
via ChangeManager (Mediator + Singleton)
2) Pattern hatching by John Vlissides
Describes Observer's implementation via Visitor Design Pattern.
3) Design Patterns Explained by Alan Shalloway and James Trott
Describes Observer's implementation via Adaptor Design Pattern.
4) CUJ's article : "Prying eyes : A Policy-Based Observer I,II" by
Andrei Alexandrescu
Very interesting articles, which describes attempt to implement
a policy-based Observer and several serious problems:
a) Mutual recursion (potential infinite loops, etc...)
b) Active observers problem (iteration problem)
c) Notification order problem
d) GetState()'s return value problem

I am trying to combine best aspects of each approach.


You might want to try out "Head First Design Patterns". Pretty decent book.

Joe
May 31 '06 #5
Daniel T. wrote:
Krivenok Dmitry wrote:
Hello All!

I am trying to implement my own Design Patterns Library.

You can't do that in general. Design Patterns are at a level higher
than simple code reuse. That said...


I'm not sure what you mean by this. Can you elaborate?

Joe
May 31 '06 #6
> > You can't do that in general. Design Patterns are at a level higher
than simple code reuse. That said...


I'm not sure what you mean by this. Can you elaborate?


I think what he means is that the patterns in the GoF book are not code
patterns per se, in that they were not meant to be reused as a unit of
code, but rather DESIGN patterns, which you could use to solve common
design problems. In other words, you may have to write and modify the
pattern code from scratch to solve the coding problem, but the design
problem is addressed by the design pattern you select.

This is somewhat subtle, especially in C++ where generic programming
has such a foothold. Often times we want to make an ideal instance of a
pattern in highly reusable C++ code. I think this is a great idea, even
if only for practices sake.

May 31 '06 #7

Jeff Flinn wrote:
bo*******@yahoo .com wrote:
Krivenok Dmitry wrote:
Hello All!

I am trying to implement my own Design Patterns Library.
I have read the following documentation about Observer Pattern:
1) Design Patterns by GoF
Classic description of Observer. Also describes implementation
via ChangeManager (Mediator + Singleton)
2) Pattern hatching by John Vlissides
Describes Observer's implementation via Visitor Design Pattern.
3) Design Patterns Explained by Alan Shalloway and James Trott
Describes Observer's implementation via Adaptor Design Pattern.
4) CUJ's article : "Prying eyes : A Policy-Based Observer I,II" by
Andrei Alexandrescu
Very interesting articles, which describes attempt to implement
a policy-based Observer and several serious problems:
a) Mutual recursion (potential infinite loops, etc...)
b) Active observers problem (iteration problem)
c) Notification order problem
d) GetState()'s return value problem

I am trying to combine best aspects of each approach.

Consider the following pseudo-code example:
[snipped code]
Main question:
How to avoid type switching in ConcreteObserve r::Update(Subje ct* s)?


Maybe you should try to avoid reading to many design books. You can
start by forgeting everything you read in the GoF book (unless you
interested in making your life as programmer harder and your code
more complicated)


Maybe you could back that up with some specific instances?

Jeff Flinn

To be more specific will take too mach of my time bust generaly I think
that in many of those advice books (not just in programming books) they
think that the have those silver bults that they discovor and now its
their job to convince you that once you will use them you can "kill"
all of your problems with them. Take for exaple the books about "how to
become rigch in X days" - do you really belive that by following their
advices you will become richer - if you do then by all means you can
coninue along this road. Presonlly I don't think (coming back to
programmning) that someone who don't know my system, the truble I have
implementing it and that I don't know too mach about him/her eigher can
give me solutions. If I need advice I will at least let my advicer see
my personl problem then I belive that he/she can truly help me. Anther
thing is - reading those books give you the impration that those people
never really wrote production code and their solutions are to academic

May 31 '06 #8
"Jeremy Jurksztowicz" <ju**********@g mail.com> writes:
You can't do that in general. Design Patterns are at a level higher
than simple code reuse. That said...
I'm not sure what you mean by this. Can you elaborate?


I think what he means is that the patterns in the GoF book are not code
patterns per se, in that they were not meant to be reused as a unit of
code, but rather DESIGN patterns, which you could use to solve common
design problems. In other words, you may have to write and modify the
pattern code from scratch to solve the coding problem, but the design
problem is addressed by the design pattern you select.


Precisely. I recomment that the OP head directly to "Modern C++
Design" by Alexandrescu. Most of that book is generic implementations
of design patterns.
This is somewhat subtle, especially in C++ where generic programming
has such a foothold. Often times we want to make an ideal instance
of a pattern in highly reusable C++ code. I think this is a great
idea, even if only for practices sake.


And extremely difficult, as anyone who has read Alexandrescu (or
looked at the various Boost libraries that do similar things) can
attest.

----------------------------------------------------------------------
Dave Steffen, Ph.D. Fools ignore complexity.
Software Engineer IV Pragmatists suffer it.
Numerica Corporation Some can avoid it.
ph (970) 419-8343 x27 Geniuses remove it.
fax (970) 223-6797 -- Alan Perlis
dgsteffen at numerica dot us
May 31 '06 #9
bo*******@yahoo .com wrote:
Jeff Flinn wrote:
bo*******@yahoo .com wrote:
Krivenok Dmitry wrote:
Hello All!

I am trying to implement my own Design Patterns Library.
I have read the following documentation about Observer Pattern:
1) Design Patterns by GoF
Classic description of Observer. Also describes implementation
via ChangeManager (Mediator + Singleton)
2) Pattern hatching by John Vlissides
Describes Observer's implementation via Visitor Design Pattern.
3) Design Patterns Explained by Alan Shalloway and James Trott
Describes Observer's implementation via Adaptor Design Pattern.
4) CUJ's article : "Prying eyes : A Policy-Based Observer I,II" by
Andrei Alexandrescu
Very interesting articles, which describes attempt to implement
a policy-based Observer and several serious problems:
a) Mutual recursion (potential infinite loops, etc...)
b) Active observers problem (iteration problem)
c) Notification order problem
d) GetState()'s return value problem

I am trying to combine best aspects of each approach.

Consider the following pseudo-code example:


[snipped code]
Main question:
How to avoid type switching in ConcreteObserve r::Update(Subje ct*
s)?

Maybe you should try to avoid reading to many design books. You can
start by forgeting everything you read in the GoF book (unless you
interested in making your life as programmer harder and your code
more complicated)


Maybe you could back that up with some specific instances?

Jeff Flinn

To be more specific will take too mach of my time bust generaly I


[snipped baseless opinion]

How about focusing on just Design Patterns by GoF?

Jeff Flinn
May 31 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
7041
by: Andy Read | last post by:
Hello all, I have the requirement to produce source code that produces an object hierarchy. Example: Root | Folder 1
3
2627
by: Michael Schneider | last post by:
Hello All, I am comming back to python after being away for several years. I would like to use weak refs in an observer pattern implementation. The problme that I have seems to be that weakrefs can't manage functions. ------------------- from docs: http://www.python.org/doc/current/lib/module-weakref.html
4
1933
by: decrypted | last post by:
Since I couldn't find a OO design/architext forum, I thought I would post here... I have a win app with forms management. forms are grouped by category (pertains to company, pertains to project. etc). This is represented, for example, by a company window containing additional windows such as company information, document history, yada yada. I am using the Observer/Observable pattern to refresh all the forms in a group when another form...
0
1620
by: FluffyCat | last post by:
Last week I continued my series of design patterns examples using PHP 5. Here now is my 14th example, the Observer pattern. http://www.fluffycat.com/PHP-Design-Patterns-Observer/ In the Observer Pattern, a Subject object notifies an Observer object if it's the Subject object's state changes. Pretty simple and fairly useful.
0
1096
by: schoenfeld1 | last post by:
I have the actor/observer pattern implemented in my application. I have added a remoted object as an observer to an actor object. In other words, a proxy object (returned by the Activator.GetObject()) is a listener to some actor object which unpredictably calls some method from proxy object's interface. The remoted object is a long-living object. The question is whether this is reliable or not? Since the logical validity of the...
4
4679
by: Gianni Mariani | last post by:
Two issues here: a) What is the accepted definition of "observer pattern". While I can't point to anything specific, I do remember having issues with inconsistency in the definition. b) Generic observer design in C++. I have been pushing the Austria "Twin" interface for a while and more recently the multi threaded version of it "TwinMT" (see the 6129 alpha on sourceforge)
1
1874
by: Christopher | last post by:
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...
4
2115
by: Mohamed Mansour | last post by:
Hello, What is the purpose of implementing the Observer Pattern if we can trigger an event easily? For example (from books), You have a "Forecaster" which notifies "Observable" when a prediction is ready, then there is a "WeatherViewer" which calls methods from the "Observer Interface".
5
1480
by: Alan Isaac | last post by:
I have two questions about the "observer pattern" in Python. This is question #1. (I'll put the other is a separate post.) Here is a standard example of the observer pattern in Python:
0
8968
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9473
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9334
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9259
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8208
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6750
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4824
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2744
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2193
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.