中国程序员联盟 正在重新改版中ing 不便之处还请见谅 改版后将内容涉及java delphi .net php
 
  首页 | 数据库开发 | 网络通讯 | 多线程 | 多媒体开发 | 图像处理 | 程序人生 | 系统函数 | 控件开发 | Web服务
 
  当前位置:笨鱼delphi技术网>数据库开发>设计模式>文章内容

delphi Observer Pattern

来源:站内 关于:bill 发布时间:2007-06-23   [收藏] [推荐]

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

Observer Graphic

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).


[浏览: 次]   
上一篇:delphi Strategy Pattern (策略)   下一篇:delphi Adapter Pattern
[收藏] [推荐] [返回顶部] [打印本页] [关闭窗口]  
    评论加载中…
google adsense热点文章
·delphi COM+对象缓冲池
·delphi Delphi_Delphi面向对象编程的20
·delphi Template Pattern (模板)
·delphi Singleton Pattern (设计模式)
·delphi Adapter Pattern
·delphi Strategy Pattern (策略)
     delphi技术网 | firefox 下载 | Avant Browser下载 | dedecms 技术网 | drupal 爱好者 | php 技术网
  Copyright@www.delphichm.com,2006-2009.All Rights Reserved.
 
程序员联盟 | delphi Java .net|QQ:707102932