Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
- Decouples information model from Interface model (MVC, Document-View)
- Good to synchronize changes in one object with other dependent objects when you don't know how many there may be.
- Good when one object needs to notify another object without knowing in advance which object it will be
The Observer pattern is a generalized version of a more specific pattern known as the Model-View-Controller (MVC), which is used to build interfaces in Smalltalk-80 and other OO class libraries. MVC aims at decoupling views (GUI classes) and models (problem domain objects) by establishing a subscribe/notify protocol between them. Whenever the model's data changes, it notifies any views that depend on it. In response, each view that has subscribed to receive notifications gets the opportunity to update itself.
With this approach you can attach multiple views to a model, to create distinct representations of each state the object can have. It allows you to create new views without affecting the model. The Controller classes in MVC define the way the user interface reacts to user input, such as keyboard events and mouse movements. However, some implementations of MVC, such as Java Swing (JFC framework), merge the View and Controller parts in the singular GUI classes.
Structure of Observer Pattern

Implementation of Observer Pattern
In this sample (uObserver.pas) TMySubject implements the TObservable interface, which represents the object that is being observed (the subject). The observed object will normally be a problem domain or data object. In this case, our data object contains x and y values, which are accessible via getX()/setX, getY()/setY methods.
TMyBars implements the TObserver interface, and is registered with TMySubject in order to be notified whenever the state of the subject changes (x and y values). It encapsulates two progress bars that will reflect the state changes. TMyBars pulls the X and Y values, whenever it receives a notification from TMySubject.
// Observer interface consists of a single update() method used to
// notify the observer to update itself to reflect the state change
// on the subject (observable object)
TObserver = class
procedure Update(ChangedSubject: TObservable); virtual; abstract;
end;
// Subject interface
TObservable = class
// Add and remove are used to subscribe/un-subscribe
procedure Add(Observer: TObserver); virtual; abstract;
procedure Remove(Observer: TObserver); virtual; abstract;
// notify subscribed/registered observers of state change
procedure Notify; virtual; abstract;
end;
An instance of TList (FObservers) is used to manage the references of all the observers that have subscribed to receive state change notifications.
// concrete observable classes
// Observable/Subject data object
TMySubject = class(TObservable)
private
FObservers: TList;
Fx: integer;
Fy: integer;
public
constructor Create;
destructor Destroy; override;
//TObservable
procedure Add(Observer: TObserver); override;
procedure Remove(Observer: TObserver); override;
procedure Notify; override
//MyData interface
function getX: integer;
function getY: integer;
procedure setX(value: integer);
procedure setY(value: integer);
end;
// Concrete Observer Object
TMyBars = class(TObserver)
private
FBarX: TProgressBar;
FBarY: TProgressBar;
public
constructor CreateBars(aParent: TWinControl);
destructor Destroy; override;
procedure Update(ChangedSubject: TObservable); override;
end;
implementation
// TMySubject Observable object
constructor TMySubject.Create;
begin
inherited Create;
FObservers := TList.Create;
end;
destructor TMySubject.Destroy;
begin
FObservers.Free;
inherited Destroy;
end;
procedure TMySubject.Add(Observer: TObserver);
begin
FObservers.Add(Observer);
end;
procedure TMySubject.Remove(Observer: TObserver);
begin
FObservers.Remove(Observer);
end;
procedure TMySubject.Notify;
var
i: integer;
begin
for i := 0 to pred(FObservers.Count) do
TObserver(FObservers.Items[i]).Update(Self);
end;
// Observer
constructor TMybars.CreateBars(aParent: TWinControl);
begin
inherited Create;
FBarX := TMyProgressBar.Create(nil);
FBarY := TMyProgressBar.Create(nil);
FBarX.Parent := aParent;
FBarY.Parent := aParent;
end;
destructor TMybars.Destroy;
begin
FBarX.Free;
FBarY.Free;
inherited Destroy;
end;
// When the observer is notified with the Update() method,
// it updates itself by pulling the values of X and Y.
procedure TMyBars.Update(ChangedSubject: TObservable);
begin
FBarX.Position := (ChangedSubject as TMySubject).getX;
FBarY.Position := (ChangedSubject as TMySubject).getY;
end;
Note that the Changed subject is passed in the update method. This allows the observer to register with multiple subjects and provide an integrated view of different data objects, since it knows which subject changed it can respond differently for each one (not shown in this example).