Delphi 3. Библиотека программиста

       

Почему интерфейсы?


Перед тем как следовать дальше, я хотел бы объяснить, почему я пользуюсь интерфейсами Delphi3, вместо того чтобы просто определить классы вида и фрейма и создавать объекты на их основе. Не вызвано ли применение интерфейсов обычным желанием воспользоваться новой эффектной возможностью Delphi 3?

Вовсе нет. Начнем с того, что виды и фреймы связаны циклической зависимостью. Фрейм должен сообщать виду о необходимости чтения или записи в модель; вид должен сообщать фрейму об изменении свойства Valid. Разумеется, подобную циклическую зависимость можно было бы реализовать с помощью опережающего объявления классов вместо опережающего объявления интерфейсов, но мне кажется, что интерфейсы делают эти взаимосвязи более понятными и избавляют их от груза посторонних свойствиметодов. Кроме того, хотя я и не использую такую возможность вEMBEDDEDFORMS.PAS, применение интерфейсов означает, что вид можно реализовать несколькими различными способами — он не обязан быть потомком TEmbeddedForm. Однако самая важная причина заключается в том, что вид сам может быть фреймом.

Например, объект Employee (работник) может содержать ссылки на объекты типа People для самого работника и его руководителя, каждый из которых в свою очередь содержит сведения об имени и адресе. Вид объекта Employee может содержать внутренние виды для соответствующих полей. В Delphi не поддерживается множественное наследование, поэтому объект не может одновременно быть TView и TFrame, однако он легко может реализовать интерфейсы IView и IFrame.

Перед тем как в Delphi появилась поддержка интерфейсов, для реализации чего-то наподобие протокола INotify обычно применялись процедурные типы:

type TOnValidChanged = procedure(ChangingObject: TObject) of object; procedure TViewAddNotifiee(Callback: TOnValidChanged);

Такая схема работала, но TOnValidChanged — это практически то же самое, что и TNotifyProc, и в каждой Delphi-программе такие процедурные типы встречаются в избытке. Вы можете передать процедуре AddNotifiee любой объект TNotifyProc, и компилятор никак не сможет предотвратить ошибочную передачу неверного параметра. При использовании интерфейсов процедура косвенного вызова (callback) фрейма должна иметь правильное имя и правильную сигнатуру, и притом она должна принадлежать объекту, реализующему протокол IFrame — это намного снижает вероятность случайных ошибок.



Содержание раздела