Наследование Delphi-интерфейса и шаблон наблюдателя - PullRequest
0 голосов
/ 29 марта 2011

Я хотел бы создать общий предметный интерфейс и повторно использовать его с «специфическими» классами 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 Ответ

2 голосов
/ 29 марта 2011

Необходимо привести интерфейс к динамическому приведению с использованием оператора as.

Ваш код, ISerialObserver(IInterface(Obs)), является определенной точкой отказа.Вместо этого вы должны написать Obs as ISerialObserver.Но почему бы не сделать свой список TList<ISerialObserver> и, таким образом, избегать приведения?

Тем не менее, вы уверены, что все в вашем списке реализует ISerialObserver?Это не очевидно из этих выдержек.Вы можете проверить поддержку интерфейса с помощью оператора is или более функциональной функции Supports().

Кроме того, вам не нужно наследовать от IInterface, что является неявным.Таким образом, вы можете заменить ISubject = interface(IInterface) на ISubject = interface и т. Д.

...