The observer design pattern can be used when you want objects to know when something happens to an object being observed.
This is done with a Subject and an Observer.
For example, let's say we have a Dragon that will be the subject and then have people as observers. When the dragon switches to a flying mode the observers will look up instead of forward.
To accomplish that we need an ISubject that will have the method to add, remove and notify observers.
- public interface IDragonSubject
- {
- void Subscribe(IDragonObserver observer);
- void Unsubscribe(IDragonObserver observer);
- void Notify();
- }
And the specification for the observers as in the following:
- public class Dragon : IDragonSubject
- {
- private IList<IDragonObserver> observers;
-
- private bool flying;
- public bool Flying
- {
- get { return flying; }
- set
- {
- if (flying != value)
- {
- flying = value;
- Notify();
- }
- }
- }
-
- public Dragon()
- {
- observers = new List<IDragonObserver>();
- }
-
-
- public void Subscribe(IDragonObserver observer)
- {
- observers.Add(observer);
- }
-
-
- public void Unsubscribe(IDragonObserver observer)
- {
- observers.Remove(observer);
- }
-
-
-
- public void Notify()
- {
- foreach (var observer in observers)
- {
- observer.Update(this);
- }
- }
- }
And our observer:
- public class Person : IDragonObserver
- {
- public enum LookingDirectionTypes
- {
- Foward,
- Up,
- Down,
- Left,
- Right,
- }
-
- public LookingDirectionTypes LookingDirection { get; set; }
-
- public void Update(Dragon dragon)
- {
- if (dragon.Flying)
- LookingDirection = Person.LookingDirectionTypes.Up;
- else
- LookingDirection = LookingDirectionTypes.Foward;
- }
- }
Finally, we can put all the pieces together and see the result. In this test there are a couple of people observing the dragon, the third one is elsewhere. So when the dragon starts flying person1 and person2 will look up.
- [TestClass]
- public class ObserverTest
- {
- [TestMethod]
- public void DragonFlyPeopleLookUp()
- {
- Dragon dragon = new Dragon();
-
-
- Person p1 = new Person();
- Person p2 = new Person();
- Person p3 = new Person();
-
-
- dragon.Subscribe(p1);
- dragon.Subscribe(p2);
-
-
- dragon.Flying = true;
-
- Assert.AreEqual(Person.LookingDirectionTypes.Up, p1.LookingDirection);
- Assert.AreEqual(Person.LookingDirectionTypes.Up, p2.LookingDirection);
-
- Assert.AreEqual(Person.LookingDirectionTypes.Foward, p3.LookingDirection);
- }
- }
A real-life example is on Assassins Creed. Ordinary people are the observers and the assassin is the subject. When the subject tosses money all observers are notified that the action happened and if they are in range they will take an
action.