Introduction
While I was developing a new web application in our company, I found that every entity in the system had some shared fields that held data about when and who saved that entity into the system. Basically, those fields were CreationDate, CreatedBy, LastModificationDate, LastModificationBy and EntityId for sure. There are multiple approaches to solve this situation:
- In every user control, include these fields and reflect data to them directly. However, this would force you to write more duplicated code and would make update and maintenance more complicated and error-frequent processes. Imagine that you had 10 controls; this means you you'd need to do 10 updates if any update were needed in the entity details.
- Create a user control called
details and place those fields in it, accessing those fields directly from each entity screen. Although this would ease maintenance and updates, this approach has a disadvantage in that those controls would now be tightly coupled. Applications with tightly coupled classes tend to be brittle and difficult to maintain, because changes in one class could affect all the tightly coupled classes. The problem: how can user controls -- objects -- notify other controls �- objects -- of state changes without being dependent on their classes?
- Use the observer pattern and create loosely coupled controls to communicate between each other without depending on their classes.
In this article, I will show how to build a simple user control that implements the observer pattern to handle updates and pass notifications around, which is done in order to update a set of objects when some important event has occurred.
Background
The observer pattern is categorized under Behavioral Patterns. Behavioral Patterns are those patterns which are concerned with algorithms and the assignment of responsibilities between objects. Behavioral patterns describe not just patterns of objects or classes, but also the patterns of communication between them.
So, What is the Observer Pattern?
The observer design pattern should, �Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.�
What is the Subject? What is the Observer?
Subject: the object which will frequently change its state and upon which other objects depend.
Observer: the object which depends on a subject and updates according to its subject's state.
Here�s how it works: an observer signs up to receive notifications of changes to the subject.
A second observer can register itself, too. In fact, a subject may have any number of dependent observers. Observers are not aware of the presence of each other.
When a certain event occurs, all observers are notified.
An observer can unregister itself from a subject so that it will never receive notifications from the subject.
With this generic way of communicating between the subject and observers, collaborations can be built dynamically instead of statically. The code is now much more separate, and thus easier to maintain and reuse. There is no direct dependency between subject class and observer class.
Using the Code
In our example, Address_UC is a ConcreteSubject and RecordDetails_UC is one of its ConcreteObservers. So, when the domain object associated with the Address_UC class has changed, the RecordDetails_UC class will be notified and will handle this event in a proper way. I will show how to explicitly implement the observer pattern another time by using delegates and events.
Implementing Subject Class
You can implement the Subject class as a super class or abstract class. However, due to the limitations in some languages like C# and VB.NET, that class can inherit only once. This will cause a problem because most domain objects are inherits from domain objects. So, our subject class will be implemented using an interface. Remember that class can implement many interfaces.
public interface ISubject
{
List<IObserver> ObserversList {get;}
void AttachObserver(IObserver observer);
void DeAttachObserver(IObserver observer);
void NotifyObservers();
}
Implementing the Observer Class
public interface IObserver
{
void Updateobject(ISubject subject);
}
The observer class is very simple and contains a method that allows subjects to notify it. All we need to know is how to implement ISubject methods in our ConcreteSubject Address_UC. It's as simple as this:
#region ISubject Members
public List<ObserverTutorial.App_Code.IObserver> ObserversList
{
get { return this.m_ObserversList; }
}
public void AttachObserver(ObserverTutorial.App_Code.IObserver observer)
{
this.ObserversList.Add(observer);
}
public void DeAttachObserver(ObserverTutorial.App_Code.IObserver observer)
{
this.ObserversList.Remove(observer);
}
public void NotifyObservers()
{
foreach (App_Code.IObserver observer in this.ObserversList )
{
observer.Updateobject(this);
}
}
#endregion
Note that the NotifyObservers method will be called form another method in Address_UC when a certain event occurs, something like after a user saves domain object data:
protected void btnOk_Click(object sender, EventArgs e)
{
bool result = SaveEntityData();
if (result)
{
this.NotifyObservers();
}
}
In the ConcreteObserver RecordDetails_UC, the implementation of the IObserver lonely method Updateobject allows Address_UC to notify RecordDetails_UC that it has changed. It is passing itself as a parameter so that RecordDetails_UC can update its state, too, in a proper way. Firstly, however, RecordDetails_UC needs to register itself with Address_UC:
ISubject Subject = this.Parent as ISubject;
if (Subject != null)
{
Subject.AttachObserver(this);
}
Points of Interest
The Microsoft .NET Framework defines the notion of delegates and events to accomplish the observer role. Therefore you would rarely implement the observer pattern explicitly in .NET, but should use delegates and events instead. I attached an implementation of this sample using delegates and events, too.
History
- 5 February, 2008 -- Original version posted
| You must Sign In to use this message board. |
|
|
 |
|
|
 |
|
 |
dvptUml wrote: So shameful to use that flag as Jerusalem is jewish town since more 5000 years.
Jerusalem was for Muslems and will stay like that. We will continue in our struggle against Jewish occupation until we have victory or martyrdom. I advice people like to take care of their own business and stay away from things which they will never know it's real circumstances.
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
First, Jerusalem was established by jewish, and accept all religions : musulman religion appeared more 5000 years after jewish.
Second, i'm offended by your proselytizing and more your threat, so i report your message and requires your expulsion, as you're making threats.
Third, i'm looking if lawsuit is possible.
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
Politics and religion have no place on this site. If you have a problem then either take it offline or leave this site altogether.
cheers, Chris Maunder CodeProject.com : C++ MVP
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
|
 |
|
 |
With a unified type system, there is little value in coupling the IObserver with the ISubject. In the past, I have implemented IObserver similar to:
public interface IObserver { void Updateobject(object subject); }
You can view the initial subscription as part of the creation. The notification is really part of the behavior. It does not rely on any of the ISubject interface methods (as written). Frankly, I find this design too abstract and a higher-level abstraction that has some semantics on the type of object observing is more useful.
Roger A. Crawfis Associate Professor Computer Science & Engineering The Ohio State University
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
1. Why is the list of observers exposed from the subject interface? Don't the add and remove methods suffice? 2. Why is the "NotifyObservers" method exposed publicly? Shouldn't this be a side effect of something else done to the subject?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
"
MaxGuernsey wrote: 1. Why is the list of observers exposed from the subject interface? Don't the add and remove methods suffice?
" That was to force Subject class to create a list which will hold observer objects. You can remove it from interface but you must create observer list in each subject class.
MaxGuernsey wrote: 2. Why is the "NotifyObservers" method exposed publicly? Shouldn't this be a side effect of something else done to the subject?
Sure, this will be a side effect in real life scenario. You can't set "NotifyObservers" to private due the limitation of interface (interface can have protected,private,internal ,,, access modifiers) This implementation is only an example to explain what the observer pattern is. As I said you should use events and delegates instead.
Thanks very much for your concern.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I think we, generally, agree. There are just a few details to work out.
Huthaifa Afanah wrote: That was to force Subject class to create a list which will hold observer objects. You can remove it from interface but you must create observer list in each subject class.
Do you? That seems like an implementation detail. Maybe they want to use a linked list. Maybe some subjects only want to support one observer and throw an exception if more than one observer attempts to register interest.
Huthaifa Afanah wrote: Sure, this will be a side effect in real life scenario. You can't set "NotifyObservers" to private due the limitation of interface (interface can have protected,private,internal ,,, access modifiers) This implementation is only an example to explain what the observer pattern is. As I said you should use events and delegates instead.
Your example seems like it would work just fine if NotifyObservers was not present in the ISubject interface and was, instead, just a private method in your page code. It really is just a side effect of btnOk_Click().
This is a fundamentally good example and it's going to influence how a lot of people think. Unfortunately, many people are implementation-oriented and are going to take this example very literally. Do you want them to get it in their heads that observable objects should always expose a method that lets consumers of their public interface directly trigger a notification?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
In the 'traditional' Observer pattern there is a NotifyObservers() method on the Subject interface so the author is just following tradition here. You can adapt the Observer pattern to do lots of different things, I use variations of it all the time.
Sure you can do this with delegates and events, however, variety is the spice of life as they say.
Adam
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Of course you could do this with .Net events - that's just an implementation of the Observer pattern. I don't understand why they keep coming up.
The primary value of patterns - though there are others - is encapsulation... "Find what varies and encapsulate it."
Appeals to tradition (or to authority, depending on how your quotes are interpretted) aside, exposing behavior that should be private is pretty much the exact opposite of the point of design patterns.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
MaxGuernsey wrote: Maybe they want to use a linked list. Maybe some subjects only want to support one observer and throw an exception if more than one observer attempts to register interest.
According to the definition of observer pattern "Define a one-to-many dependency ..." it seems that their is a many of observers in the subject class. Developer can implement observer pattern in a way which suites his scenario. My example is in a general manner.
MaxGuernsey wrote: Do you want them to get it in their heads that observable objects should always expose a method that lets consumers of their public interface directly trigger a notification?
No, definitely. So I will mention this comment in the article body. Thanks again.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I highly recommend that you add a hint class and pass it as a parameter to your NotifyObservers calls. Otherwise you'll very quickly run into a situation where the observer is wondering just what it is about the subject that has changed, but doesn't have the information to find out.
- Owen -
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Turns out I actually CAN use this (and actually need it for something I'm currently working on). I'd read more complex articles on the subject and discarded it, thinking it was more work than I really needed to do.
Thanks.
It has become appallingly obvious that our technology has exceeded our humanity. - Albert Einstein
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Custom events/delegates would provide the same functionality. System.ComponentModel.INotifyPropertyChanged is also a nice alternative for consolidating a lot of events into a single interface.
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
|
 |
|
 |
I've rather ended up implementing the observer pattern, but reinventing the wheel is never as easy as discovering it 
So yes, delegates fit the bill, but it's nice to see some formality and validation to the approach I've taken.
It has become appallingly obvious that our technology has exceeded our humanity. - Albert Einstein
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thanks, for your comment. As I said in the "Points of Interest" delegates and events represents the observer pattern in .Net framework and other programming languages and we should use it instead of implementing it by ourselves. But I provide this example to explain what is observer pattern and how it could be implemented. It's a nice thing to know a good reason for why delegates and events are created for and what this means in "a pattern way" let me say.
Thanks for all.
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
|