Использование интерфейсов
Автор: DROnik
Статья находится в разработке
Простой интерфейс
Агрегирование
Имплементация
делегирование
агрегирование
Наследование интерфейсов
Простой интерфейс
Нужен для отделения декларируемых возможностей класса от непосредственной реализации.
type ISomeInterface = interface function ReturnSomething(aP: string): integer; procedure DoSomething; procedure DoSomethingElse( var r: single);stdcall; end; TRealization = class( TInterfacedObject, ISomeInterface) private function GetSomething( aP: string): integer; procedure DoSomething;//Реализация не обязательно должна быть в области public public function ISomeInterface.ReturnSomething = GetSomething;//переопределяем реализацию procedure DoSomethingElse( var r: single);stdcall; destructor Destroy;override; end; procedure DoSomethingElse( obj: ISomeInterface); var r: single; begin obj.DoSomethingElse( r); end; procedure TForm1.Button1Click( Sender: TObject); var Some: ISomeInterface; begin Some:= TRealization.Create; Some.DoSomething; Some.ReturnSomething( 'ff'); DoSomethingElse( Some); //Не нужно делать Some.Free! Сам дохнит:) end;
Агрегирование
Один объект обладает несколькими свойствами.
Основная особенность - для таких объектов нужно вручную делать _AddRef и _Relize. В хелпе об этом почему-то умалчивается, но факт остается фактом. Я в своё время долго стучал головой об стекло монитора:)
type IFeature1 = interface procedure DoOne; end; IFeature2 = interface procedure DoTwo; end; IFeature3 = interface procedure DoThree; end; TMultiObject = class(TInterfacedObject, IFeature1, IFeature2, IFeature3) procedure DoOne; //реализация фичи1 procedure DoTwo; //реализация фичи2 procedure DoThree; //реализация фичи3 constructor Create; destructor Destroy;override; end; //В эти функции можно передовать любые классы поддерживающие //заданные интерфейсы procedure CallFeature1( Obj: IFeature1); begin Obj.DoOne; end; procedure CallFeature2( Obj: IFeature2); begin Obj.DoTwo; end; procedure CallFeature3( Obj: IFeature3); begin Obj.DoThree; end; constructor TMultiObject.Create; begin Self._AddRef; //!!!!!! end; //Тестируем procedure TForm1.Button2Click( Sender: TObject); var MultObj: TMultiObject; begin MultObj:= TMultiObject.Create; MultObj.DoOne; //явно вызываем методы MultObj.DoTwo; MultObj.DoThree; CallFeature1( MultObj); //Передаем объект в том виде, CallFeature2( MultObj); //в котором его хочет получить CallFeature3( MultObj); //функция MultObj._Release; //!!!!!! end;
Имплементация
делегирование
Выносим из реализации класса реализации отдельных фрагментов
type //Декларируем свойства для объекта. //Их реализация нас не волнует. IDeclaredOptions = interface procedure Metod1; procedure Metod2; procedure Metod3; end; TSuperManager = class private FRealization: IDeclaredOptions; //... public property Realization: IDeclaredOptions read FRealization write FRealization; end; //реализации могут быть абсолютно любыми классами, //могут поддерживать дополнительные интерфейсы и //быть унаследованными от разных предков TRealization1 = class(TInterfacedObject, IDeclaredOptions) procedure Metod1; procedure Metod2; procedure Metod3; end; TRealization2 = class( TInterfacedObject, IDeclaredOptions) procedure Metod1; procedure Metod2; procedure Metod3; end; procedure TForm1.Button2Click( Sender: TObject); var SM: TSuperManager; begin SM:= TSuperManager.Create; if random( 100)>50 then SM.Realization:= TRealization1.Create else SM.Realization:= TRealization2.Create; SM.Realization.Metod1; SM.Free; end;
агрегирование
Выносим из реализации класса реализацию отдельного интерфейса