您的位置:首页 > 编程语言 > Delphi

《GOF设计模式》—观察者(OBSERVER)—Delphi源码示例:拉模型(pull model)

2011-03-03 10:08 666 查看
示例:拉模型(pull model)
说明:
目标除最小通知外什么也不送出,而在此之后由观察者显式地向目标询问细节。
代码:

unit uPullModel;

interface

uses
    SysUtils, Classes, Dialogs;

type
    TSubjectState = record
        A, B: Integer;
    end;

    TObserver = class;

    TSubject = class
    private
        FObservers: TList;
    public
        constructor Create;
        destructor Destroy; override;
        //---
        procedure Attach(AObserver: TObserver);
        procedure Detach(AObserver: TObserver);
        procedure Notify;
    end;

    TConcreteSubject = class(TSubject)
    private
        FState: TSubjectState;
        function GetA: Integer;
        function GetB: Integer;
        procedure SetA(const Value: Integer);
        procedure SetB(const Value: Integer);
    public
        property A: Integer read GetA write SetA;
        property B: Integer read GetB write SetB;
    end;

    TObserver = class
    public
        procedure Update; virtual; abstract;
    end;

    TConcreteObserver = class(TObserver)
    protected
        FSubject: TSubject;
    public
        constructor Create(ASubject: TSubject);
        destructor Destroy; override;
        //---
        procedure Update; override;
    end;

procedure Test;

implementation

procedure Test;
var
    ASubject: TConcreteSubject;
    AObserver: TObserver;
begin
    ASubject := TConcreteSubject.Create;
    AObserver := TConcreteObserver.Create(ASubject);
    try
        ASubject.A := 1;
        ASubject.B := 2;
        ASubject.Notify;
    finally
        AObserver.Free;
        ASubject.Free;
    end;
end;

constructor TSubject.Create;
begin
    FObservers := TList.Create;
end;

destructor TSubject.Destroy;
begin
    FObservers.Free;
    //---
    inherited;
end;

procedure TSubject.Attach(AObserver: TObserver);
begin
    FObservers.Add(AObserver);
end;

procedure TSubject.Detach(AObserver: TObserver);
begin
    FObservers.Remove(AObserver);
end;

procedure TSubject.Notify;
var
    i: integer;
begin
    with FObservers do
    begin
        for i := 0 to Count - 1 do
            TObserver(Items[i]).Update;
    end;
end;

constructor TConcreteObserver.Create(ASubject: TSubject);
begin
    FSubject := ASubject;
    if FSubject <> nil then FSubject.Attach(self);
end;

destructor TConcreteObserver.Destroy;
begin
    if FSubject <> nil then FSubject.Detach(self);
    //---
    inherited;
end;

procedure TConcreteObserver.Update;
begin
    if FSubject is TConcreteSubject then
    begin
        with TConcreteSubject(FSubject) do
            ShowMessage(IntToStr(A + B));
    end;
end;

function TConcreteSubject.GetA: Integer;
begin
    Result := FState.A;
end;

function TConcreteSubject.GetB: Integer;
begin
    Result := FState.B;
end;

procedure TConcreteSubject.SetA(const Value: Integer);
begin
    FState.A := Value;
end;

procedure TConcreteSubject.SetB(const Value: Integer);
begin
    FState.B := Value;
end;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐