Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование IInterface 
:(
    Опции темы
DarkProg
  Дата 10.1.2013, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: 2
Всего: 19



Добрый день. Продолжаю развиваться и как всегда возникают вопросы smile

Давно знаю про IInterface, знаю что их можно "пачками" использовать для дополнения классам, но несколько не понимаю их применения.

Оно из применений интерфейса, это возможность запихать какой-то объект который наследуется от этого интерфеса в DLL и потом можно будет вернуть этот интерфейс и управлять через интерфейс объектом.

А также можно передавать интерфейсы между приложениями для управления объектами.

Я правильно это понимаю? И тогда мне не нужен ни какой ShareMem и прочая шелуха, ведь через интерфейс можно по идее передать и объекты целиком, да?


Но вот ещё интересует, есть ли смысл в применении интерфейсов внутри одного приложения?
Я знаю что некоторые программисты используют интерфейсы чтобы не уничтожать явно объекты, мне в принципе это не интересно, так как я памятью всегда управляю вручную и "ну чисто религия не позволяет делать по другому".
Читал, что интерфейс удобен когда у двух классов разный предок, то можно ещё добавить по интерфейсу и тогда появятся общие методы, в остальном же по сути обычное наследование будет удобнее и правильнее что ли?

В общем подытожьте правильно ли я понимаю суть этой технологии?


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
Illusion Dolphin
Дата 10.1.2013, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 36
Всего: 63



Цитата

Оно из применений интерфейса, это возможность запихать какой-то объект который наследуется от этого интерфейса в DLL и потом можно будет вернуть этот интерфейс и управлять через интерфейс объектом.

Применение интерфейса это абстрагирование от реализации. Используется когда не важно, что реагирует нужную функциональность, важно лишь что интерфейс предоставляет нужные методы.

Цитата

А также можно передавать интерфейсы между приложениями для управления объектами.
Я правильно это понимаю? И тогда мне не нужен ни какой ShareMem и прочая шелуха, ведь через интерфейс можно по идее передать и объекты целиком, да?

ShareMem и интерфейсы никак не связаны.
Если у вас 2 приложения то тут возможны 2 варианта:
1) Они написаны на делфи (ну мы тут его рассматриваем). В этом случае можно применять полную объектную модель, подключив ShareMem. Но можно и ограничиться интерфейсами.
2) Они написаны на чём угодно. Тогда для взаимодействия можно использовать интерфейсы, это более гибкая модель по сравнению с вызовом функций. 

Цитата

Но вот ещё интересует, есть ли смысл в применении интерфейсов внутри одного приложения?

ДА

Цитата

В общем подытожьте правильно ли я понимаю суть этой технологии? 

Не думаю smile

Я использую интерфейсы "пачками", большую часть на c# и в подавляющем большинстве внутри одного приложения. Их можно использовать:
1) Если неизвестно, что за класс у нас имеется, но он может что-то уметь. Особенно если они наследуются не от одного предка или на этого предка нельзя повлиять. Пример - у меня в приложении есть много разных форм и в какой-то момент времени надо узнать текущее изображение в окне ниже по z-indexу, т.е. под текущим окном. Это может быть любая форма, которая имеет или нет изображения. В результате делается интерфейс:

Код

  ICurrentImageSource = interface(IInterface)
    function GetCurrentImageFileName: string;
  end;


И я у формы прошу этот интерфейс, если он есть то я могу запросить текущий файл, если нет - не беда. И мне абсолютно не важно, что это за форма и как она реализована, главное - она реализует интерфейс.
2) Есть несколько различных реализаций одной функциональности. Т.е. внешне они одинаковые, а внутри - нисколько. Например - для работы с камерами которые определяются как устройства в винде есть 2 возможности - WIA и WPD, второе доступно только с Vista SP1. И надо как-то работать с этими функциональностями без миллиона проверок, чтобы код был один. Для этого создаётся 2 разных объекта, каждый из которых реализует заданный интерфейс и в зависимости от версии Windows создаётся разный объект, но коду, который работает с объектом - всё равно, как всё устроено внутри и как это работает. 

3) Ещё есть пример у меня - уменьшение зависимостей. Допустим имеется много форм, которые могут вызывать друг друга. При этом образуются циклические зависимости. Для решения я для каждой формы создаю интерфейс, который определяет внешнее описание. В каждом модуле формы форма регистрируется в общем хранилище, а когда нужно получить какую-то форму, в коде вызывается функция:
Код

function CreateForm<T: IInterface>(): T;

И проблема решена! Более того, если будет создана новая реализация формы, всё, что потребуется сделать - сменить регистрацию формы, весь код остальной останется нетронутым.

4) В других целях я использую интерфейсы в c#, в делфи тоже можно так (частично, в полной мере не дорос ещё делфи): есть например модули, которые друг друга используют. И надо их протестировать (юнит-тестирование). Причём модули-то друг друга используют, а их надо протестировать независимо.
И тут на помощь приходят интерфейсы - к каждому модулю добавляется интерфейс и работа ведётся исключительно по нему. И если надо отдельно протестировать модуль, то ему подсовывается фальшивая реализация зависимости в виде другой реализации интерфейса. 

Примеров на самом деле множество, наверное, стоит почитать в интернете примеры, может там ещё матчасть есть.

Это сообщение отредактировал(а) Illusion Dolphin - 11.1.2013, 07:58


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
superVad
Дата 10.1.2013, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 735
Регистрация: 6.4.2006
Где: Черкассы, Украина

Репутация: 4
Всего: 15



Цитата(DarkProg @  10.1.2013,  10:26 Найти цитируемый пост)
Но вот ещё интересует, есть ли смысл в применении интерфейсов внутри одного приложения?Я знаю что некоторые программисты используют интерфейсы чтобы не уничтожать явно объекты, мне в принципе это не интересно, так как я памятью всегда управляю вручную и "ну чисто религия не позволяет делать по другому".

Ну если не надо автоматическое управление памятью. То в большинстве случаев интерфейсы можно заменить классами с virtual; abstract; методами.
Можно такие штуки делать - ссылка.
Ну и класс может реализовывать несколько интерфейсов (если это зачем то понадобится).
PM MAIL   Вверх
DarkProg
Дата 11.1.2013, 07:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: 2
Всего: 19



Цитата(Illusion Dolphin @  10.1.2013,  21:38 Найти цитируемый пост)
Примеров на самом деле множество, наверное стоит почитать в интернете примеры, может там ещё матчасть есть. 

Я пытался погуглить, но не совсем понял куда и в каком направлении надо, да есть примеры, но частенько весьма однотипные, либо вообще одно и тоже встречается.

Illusion Dolphin, за развёрнутый ответ спасибо, буду дальше вникать smile


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
stanilar
Дата 11.1.2013, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 9.2.2010

Репутация: нет
Всего: нет



Цитата

используют интерфейсы чтобы не уничтожать явно объекты, мне в принципе это не интересно


Смысл использования в программе интерфейсов это, безусловно, возможность реализации множественного наследования. У этого приема есть свои плюсы, но есть и свои минусы:

1) при разрастании проекта интерфейсы усложняют отладку (и понимание) нестандартной логики. Для примера можете посмотреть на реализацию VCL (а также практически любые сторонние компоненты для дельфи), для опытного разработчика архитектура и особенности работы VCL(и большей части сторонних компонент) понятны на уровне интуиции. Что нельзя сказать про большую часть видимого мной прикладного кода, где был сделан упор на интерфейсы.

2) При сопровождении проекта интерфейсы ограничивают возможности по исправлению багов. Для примера опять можно взять VCL - вы наследуете нужный элемент библиотеки, дорабатывая по необходимости. При этом логика работы самой VCL не меняется. Такой прием вполне подходит и для коррекции багов, когда изменение базового кода несет  усложнение общей архитектуры программы.

3) Усложняют развитие и сопровождение проекта в целом.

3.a) Те задачи, которые в большинстве случаев решаются перегрузкой процедур базового класса в наследнике, для интерфейсов потребуют написания отдельного класса целиком. В тех случаях, когда класс с требуемой реализацией можно унаследовать от базового, логика получения требуемого интерфейса может оказаться настолько нетривиальной и хитросплетенной, что польза от интерфейсов, как механизма абстракции, будет крайне незначительной. В последнем случае, переписывание всей логики работы с проблемным интерфейсом на использование классов может оказаться единственно верным решением.

3.b) Необходимо следить за соответствием различных реализаций одного интерфейса на соответствие правилам использования этого интерфейса. Небольшие различия в логике разных реализаций интерфейса могут привести к неуловимым ошибкам в логике программы, по причинам, описанным в 1).

4)Тяжело проходит передача проекта следующему программисту. Интерфейсы по своей природе должны скрыть зависимость от реализации, поэтому для нового человека код проекта представляет из себя мешанину разрозненной логики.

5) По хорошему (как следствие п4), интерфейсы должны быть хорошо документированы (за исключением тривиальных случаев, как в п1 от Illusion Dolphin ), что удается далеко не всем программистам, и очень часто забывается. При этом можно отметить следующий парадокс: программа, сама по себе, является описанием той задачи, что она решает, и (по идее) не требует документирования самой себя. Наличие элемента языка в программе, который явно требует документирование самого себя,  соответствует требованию вести документацию на документацию.


З.Ы. Давно обхожусь без интерфейсов везде, где это возможно. И, на самом деле, приходит понимание что это далеко не самый мощный прием программирования. Значимость интерфейсов как механизма абстракции (в пределах программы) против виртуальных классов очень часто оказывается незначительной.  Поэтому отношусь к этой технике в большей степени как к механизму взаимодействия модулей, чем как к приему программирования.
PM MAIL   Вверх
DarkProg
Дата 11.1.2013, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: 2
Всего: 19



Цитата(stanilar @  11.1.2013,  17:04 Найти цитируемый пост)
1) при разрастании проекта интерфейсы усложняют отладку (и понимание) нестандартной логики. Для примера можете посмотреть на реализацию VCL (а также практически любые сторонние компоненты для дельфи), для опытного разработчика архитектура и особенности работы VCL(и большей части сторонних компонент) понятны на уровне интуиции. Что нельзя сказать про большую часть видимого мной прикладного кода, где был сделан упор на интерфейсы.

Я видел реализации VCL причём с очень мощной системой интерфейсов, код красивый, и я понимаю почему они так сделали, хотя разобраться там действительно сложно.

Приём сам по себе мощный, и по сему я решил спросить имеет ли смысл заморачиваться, правильно ли я понимаю саму технологию, правильно ли я понял выгоду и проблемы которые мне светят. 
Сейчас мне приходится тянуть два очень крупных проекта и честно говоря порой ну просто бесит делать в них изменения(или искать баг) из-за того что изначально писали где-то "на побыстрее", где-то "о я нашёл клёвую штуку она в одну строку всё сделает", в итоге получили страшненького толстячка и уже просто приходится переделывать на нормальное так как это необходимость, сейчас где-то 2-3 модуля только я переписываю с остервенением, потому что я устал бадаться.

Почему мне нужны интерфейсы ещё, я просто приложение хочу распилить на dll, т.к. половину форм которые есть в проекте достаточное долгое время уже никто не трогает и их бы по хорошему скомпилировать и не трогать, пусть себе лежат отдельно. Да и полезность от интерфейсов мне будет, главное правильно реализовать, а вот косяк именно с тем что сложно отлаживать это будет, и пока что я себе смутно представляю это, но ничё где наша не пропадала. А пихать такие изменения бездумно мне совсем не хочется...


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
bems
Дата 12.1.2013, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Цитата(Illusion Dolphin @  10.1.2013,  20:38 Найти цитируемый пост)
Если у вас 2 приложения то тут возможны 2 варианта:
1) Они написаны на делфи (ну мы тут его рассматриваем). В этом случае можно применять полную объектную модель, подключив ShareMem. Но можно и ограничиться интерфейсами.
столько раз говорилось что нельзя, что уже лень повторять



--------------------
Обижено школьников: 8
PM MAIL   Вверх
stanilar
Дата 14.1.2013, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 9.2.2010

Репутация: нет
Всего: нет



Цитата
 распилить на dll 


Пилита на bpl, тогда можно будет заменить интерфейсы на объекты.

PM MAIL   Вверх
DarkProg
Дата 14.1.2013, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: 2
Всего: 19



Цитата(stanilar @  14.1.2013,  09:30 Найти цитируемый пост)
Пилита на bpl, тогда можно будет заменить интерфейсы на объекты.

Знаю о таком способе, только при нынешнем подходе, который есть у нас хрен два я смог отпилить хотя бы одну форму, матерился полвечера... так что всё равно придётся переделывать... а с dll оно как-то получается солиднее что ли...


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
stanilar
Дата 14.1.2013, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 9.2.2010

Репутация: нет
Всего: нет



Цитата
 солиднее 

У запутанной архитектуры программы есть серьезное достоинство: программиста поддерживающего сей ###код практически нельзя уволить. А еще ему нужно регулярно поднимать зп, чтоб сам не ушел.

PM MAIL   Вверх
DarkProg
Дата 14.1.2013, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: 2
Всего: 19



Цитата(stanilar @  14.1.2013,  12:00 Найти цитируемый пост)
У запутанной архитектуры программы есть серьезное достоинство: программиста поддерживающего сей ###код практически нельзя уволить. А еще ему нужно регулярно поднимать зп, чтоб сам не ушел.

Нету ничего у нас запутанного, кто не тянет серьёзное программирование, тех к ядру приложения не пускают. Самое главное, это нормально отрисовать архитектуру, потом нормально её реализовать и задокументировать. Последнее наверное ключевое, что надо сделать.


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
stanilar
Дата 14.1.2013, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 9.2.2010

Репутация: нет
Всего: нет




Модератор: Сообщение скрыто.

PM MAIL   Вверх
DarkProg
Дата 14.1.2013, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: 2
Всего: 19




Модератор: Сообщение скрыто.



--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
bems
Дата 14.1.2013, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Модератор: давайте вернёмся к теме обсуждения


--------------------
Обижено школьников: 8
PM MAIL   Вверх
DarkProg
Дата 15.1.2013, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: 2
Всего: 19



В общем, вот что у меня получилось. 

Это модуль с интерфейсами
Код

unit unInterfaces;

interface

uses Classes, SysUtils, uADCompClient;

type
  IDBModule = interface(IUnknown)
    ['{08F6AF43-8282-4FBD-96BF-BE789BCC58F4}']
    function GetDatabase():TADConnection;
    procedure AddItem();
    procedure EditItem();
  end;

  IfrmBase = interface(IUnknown)
    ['{D53528D8-D3D2-43F1-A5CA-5BDA68862759}']
    procedure SetCaption(NewCaption:string);
    function GetCaption():string;
    function ShowModal():integer;
  end;

implementation

end.


Модуль отвечающий за соединение с БД и некоторые операции с базами
Код

type
  TDBDataBase = class(TDataModule, IDBModule)
    ADConnection: TADConnection;
  private
    { Private declarations }
  public
    function GetDatabase():TADConnection;
    procedure AddItem();
    procedure EditItem();
  end;

var
  DBDataBase: TDBDataBase;

implementation

{$R *.dfm}

{ TDBDataBase }

procedure TDBDataBase.AddItem;
begin
  ShowMessage('AddItem');
end;

procedure TDBDataBase.EditItem;
begin
  ShowMessage('EditItem');
end;

function TDBDataBase.GetDatabase: TADConnection;
begin
  Result:=ADConnection;
end;


Вот такая вот базовая форма(форма от которой наследуются все основные формы проекта и которые поддерживают универсальные методы)
Код

type
  TfrmBase = class(TForm, IfrmBase)
  private
    { Private declarations }
  public
    procedure SetCaption(NewCaption:string);
    function GetCaption():string;
  end;

var
  frmBase: TfrmBase;

implementation

{$R *.dfm}

{ TfrmBase }

function TfrmBase.GetCaption: string;
begin
  Result:=Self.Caption;
end;

procedure TfrmBase.SetCaption(NewCaption: string);
begin
  Self.Caption:=NewCaption;
end;


Вот и самое интересное, я сделал ещё одну форму(наcледник от TfrmBase) и записал её в DLL. В Dll я присоединил модуль с базовой формой и модуль с интерфейсами.
Вызов формы из Dll я сделал вот так
Код

Var ChildForm:IfrmBase;
begin
  ChildForm:=CreateNewForm('TfrmFromDLL');
  ChildForm.SetCaption('Это чудо форма из библиотеки :)))');
  ChildForm.ShowModal;
end;


TfrmFromDLL - это класс формы, т.е. я создал один экземпляр нужного класса и вернул себе интерфейс. 
В качестве параметра  функция из dll CreateNewForm принимает WideString, что нормально.
Меня немного беспокоит сам метод SetCaption, он принимает string, но насколько я понял это нормально и проблем не будет, верно?
И у IDBModule метод GetDatabase возвращает ссылку на объект который держит соединение, это тоже при работе через интерфейсы проблем не вызовет, так?

Так вот, правильно ли я всё понял?

P.S. проект не прикладываю, потому что он навряд ли у кого-то скомпилируется из-за используемых мною компонентов, а без них было бы неполным тестирование :(

Это сообщение отредактировал(а) DarkProg - 15.1.2013, 20:07


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0630 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.