Я вот тут подумал, что здорово было бы, если бы в Дельфи были определены интерфейсы для базовых классов. Например, был бы интерфейс IList, реализуемый классом TList. IStringList, реализуемый TStringsList и т.п. А особенно классно, было бы если бы были определены интерфейсы реализующие взаимодействие с компонентами.
Например интерфейс:
ICaptionedControl = interface property Caption:string; end;
Если бы все контролы, имеющие свойство Caption(например TLabel; TButton; TCheckBox; TRadioButton; TGroupBox; TBitBtn; TSpeedButton), реализовывали его, было бы намного проще их изменять. Хотя, подобное на практике нужно только, когда начинаешь реализовывать собственный механизм перевода программы.
Пример с Db-control-ами
Более полезным было бы применение интерфейсов в Db-контролах. Например, имея интерфейсы:
IDataSourceProperty = interface property Datasource: Idatasource; end;
IDataFieldProperty = interface property DataFieldName:string; function GetDataField: IField; end; IReadOnly = interface property ReadOnly: Boolean; end;
Можно было бы упростить работу с Db-контролами в разы, просто проверяя, реализует ли контрол соответствующий интерфейс. Это было бы полезно для обработки прав доступа в программе. Например, если у пользователя нет прав на работу с определённым полем в базе, то и в приложении, все контролы использующие данное поле можно спрятать, или сделать их доступными только для чтения.
А то сейчас, чтобы реализовать что-то подобное, приходится либо использовать TypInfo, либо проверять классы вручную:
procedure ValidateControlsField(Sender: TObject); var tmpField: Tfield; begin If aControl is TDbEdit then tmpField := TDbEdit(aControl).DataField else If aControl is TDbMemo then tmpField := TDbMemo(aControl).DataField else If aControl is TDbComboBox then tmpField := TDbComboBox(aControl).DataField; end;
А всё потому, что TDbEdit наследуется от TCustomMaskEdit, TDbComboBox от TCustomComboBox, а TDbMemo от TCustomMemo.
В случае с интерфейсами, код выглядел бы примерно так:
procedure ValidateControlsField(Sender: TObject); var tmpDataFieldPropertyI: IDataFieldProperty; begin if Supports(Sender, IDataFieldProperty, tmpDataFieldPropertyI) then begin // работаем с Tfield, точнее IField end; end;
Где ещё это было бы полезно?
Если в приложении вместо приведения типов, использовать интерфейсы, это увеличит возможность повторного использования кода.
При создании расширений(плагинов).
Можно было бы вводить поддержку плагинов, использующих функционал классов, без возни с COM или BPL(которые требуют, чтобы и exe и bpl были скомпилированы одной версией компилятора).
Автоматическое уничтожение объектов. Вводить меньше кода.
Вместо того, чтобы писать так:
procedure SomeProcedure; var tmpSL: TStringList; begin tmpSL:= TStringList.Create; try // работаем с tmpSL finally tmpSL.Free; end; end;
Можно было бы писать так:
procedure SomeProcedure; var tmpSL: IStringList; begin tmpSL:= TStringList.Create; // работаем с tmpSL end; // tmpSL будет автоматически освобождена.
Самое главное
Станет намного легче менять реализацию. Если работа будет идти через интерфейсы, то станет намного проще заменить один класс другим. Особенно в случае замены одного набора компонентов, другим.
Например:
Сейчас у меня в проектах используются стандартные Db-контролы(TDbEdit, TDbComboBox). Чтобы заменить из на другие аналогичные Db-контролы(например Ehlib-овские), придётся заменить компоненты на форме, а также пройтись по коду в поисках явной проверки типов(if Sender is TDbEdit then …). Если бы были интерфейсы, и в коде использовались они, то, многое бы работало без изменений.
Давайте обсудим
Что вы думаете об этой идее?
p.s. У Delphi появился форум на UserVoice. И я добавил туда эту идею. Пожалуйста проголосуйте за неё(можно голосовать без регистрации):
Add interface support for basic VCL classes
p.p.s. Мне очень не нравится интерфейс QC. =( Но я кое-как разобрался, и с помощью встроенной в Delphi QC Tool с мегаужасным интерфейсом добавил отчёт: QC#73087
p.p.p.s. Если не сложно, то проголосуйте ещё за поддержку Firebird в Delphi.(навряд ли это, что-то изменит, но не попытаться я не могу=))
p.p.p.s. Обсуждение этой темы на Винграде
Идея хорошая (самому в голову такое приходило), но навряд ли будет реализована. Слишком несопоставимы затраченные на неё усилия и полезная отдача.
ОтветитьУдалитьКстати, было бы неплохо создать эту тему как Suggestion на QC ;)
ОтветитьУдалитьДобавил: QC#73087
ОтветитьУдалитьАлексей в своем блоге написал решение данного вопроса
ОтветитьУдалитьhttp://kazav.blogspot.com/2009/04/delphi.html