Delphi接口继承和Observer Pattern

时间:2011-03-29 16:34:23

标签: delphi exception observer-pattern

我想创建一个通用的Subject Interface,因此将它重用于“specifics”Observer类。所以我为主题尝试了这个代码:

unit uISubject;

interface

type

    ISubject = interface(IInterface)
        procedure RegisterObserver(Observer: IInterface);
        procedure RemoveObserver(Observer: IInterface);
        procedure NotifyObservers;
    end;

implementation

end.

我有以下观察员课程:

串行通信观察器

unit uISerialObserver;

interface

type

    ISerialObserver = interface(IInterface)
    ['{EF833BD7-31C1-49B3-8041-F1574AC043F0}']
        procedure DataAvailable(ReceivedData: AnsiString);
    end;

implementation

end.

更新进度条的观察者

unit uIProgressObserver;

interface

type

    IProgressObserver = interface(IInterface)
    ['{05AC7C76-CD41-42AB-B793-1512E68D91D5}']
        procedure UpdateProgressParameters(Min, Max: Cardinal);
        procedure IncrementParameter;
    end;

implementation

end.

我已经实现了这样的Notify方法:

procedure TSerialPortCommunicator.NotifyObservers;
var
    Obs: IInterface;
begin
    for Obs in FObservers do
    begin
        ISerialObserver(Obs).UpdateObserver(FReceivedData);
    end;
end;

,其中

FObservers: TList<IInterface>;

NotifyObservers运行时,Delphi会返回访问冲突错误。

我想知道我做错了什么?

1 个答案:

答案 0 :(得分:2)

您需要使用as运算符强制转换界面。

您的代码ISerialObserver(IInterface(Obs))是一个特定的失败点。你应该写Obs as ISerialObserver。但为什么不制作你的列表TList<ISerialObserver>,从而避免演员?

那就是说,你确定列表中的所有内容都实现了ISerialObserver吗?这些摘录并不明显。您可以使用is运算符或更实用的Supports()函数来检查界面支持。

此外,您不需要从IInterface继承,这是隐式的。因此,您可以将ISubject = interface(IInterface)替换为ISubject = interface,依此类推。