Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Использование интерфейсов (IInterface)


Автор: Caduser 22.4.2009, 11:56
Для сложного приложения содержащего много форм и фреймов есть необходимость централизовано управлять визуальными параметрами  этих форм и фреймов, например централизовано изменять размер шрифта.
Наиболее изящным решением видится использование Интерфейсов (IInterface). Сделал тестовое приложение Test_IInterface, однако до изящества пока далеко. Посоветуйте как улучшить код?

Например плохо что пришлось многократно повторять один и тот же код процедур AddToList и DeleteFromList.

Давайте отрефакторим!

Добавлено @ 12:00
Не дает  файл прицепить в формате zip

Проект создан в Delphi 2007

Автор: pseud 22.4.2009, 14:26
Цитата(Caduser @  22.4.2009,  11:56 Найти цитируемый пост)
Не дает  файл прицепить в формате zip

должно давать...
1. размер не более 1 мб (если более - то ifolder.ru в помощь)
2. вырезать из архива скомпилированные модули и ехе.
3. расскажи хоть на чем написано, чтоб мне например с моим Delphi6 не мучаться и не жечь трафик.

Автор: cemick 22.4.2009, 16:37
А какие моменты не красивы? Ну не красиво выглядит  глобальный L: TList. Лучши бы тогда уж было бы реализовать контроллер, который бы хранил список подписок и управлял ими, не надо будет и дублировать код с добавлением подписки.  
Так же можно было бы все реализовать на сообщениях, а уже в контролах ты бы решал надо ему обрабатывать сообщение изменения размера шрифта или нет.

Автор: Caduser 22.4.2009, 18:08
Цитата(cemick @ 22.4.2009,  16:37)
А какие моменты не красивы? Ну не красиво выглядит  глобальный L: TList. Лучши бы тогда уж было бы реализовать контроллер, который бы хранил список подписок и управлял ими, не надо будет и дублировать код с добавлением подписки.  
Так же можно было бы все реализовать на сообщениях, а уже в контролах ты бы решал надо ему обрабатывать сообщение изменения размера шрифта или нет.

Даже если реализовать контроллер то как избавиться от дублирования подписки?

Автор: Bose 23.4.2009, 01:44
Цитата(Caduser @  22.4.2009,  10:56 Найти цитируемый пост)
Например плохо что пришлось многократно повторять один и тот же код процедур AddToList и DeleteFromList.

Точно.

Почему бы не создать базовый класс
TMyForm = class(TForm, IOperations)
...

и не реализовать это в нём. А все остальные формы от него отнаследовать. 

????

А ещё лучше вынести реализацию интер
Код

фейса IOperations в отдельный класс. Например
type 
  TMyOperations = class(TInterfacedObject, IOperations)
  private
    FOwner:TControl; // минимальный класс, имеющий свойство Font
  protected  
    // Ioperations procedures
    procedure AddToList;virtual;
    procedure DeleteFromList;virtual;
    procedure SetFontSize(const FontSize: Integer);virtual;
  public
     constructor Create(aOwner: TControl);
  end;


А в базовой форме объявить так
Код

TMyForm = class(TForm, IOperations)
private
   FMyOperations: Ioperations; implements Ioperations;

И создавать FMyOperations := TMyOperations.Create(self) в конструкторе формы а убивать в деструкторе.

Ну и на самом деле, раз уж речь зашла о подписке, то лучше всего, вместо L:TList создать отдельный класс, выполняющий действия 
    procedure AddToList(aControl:TControl);virtual;
    procedure DeleteFromList(aControl:TControl);virtual;
    procedure SetFontSizeForAll(const FontSize: Integer);virtual;

Сделать для этого класса глобальную переменную. И из конструктора базовой формы просто вызывать метод AddToList(self), а из деструктора DeleteFromList. А при необходимости сменить фонт, просто вызывать SetFontSizeForAll, а этот класс уже пускай проходит по всем зарегенным формам и их контролам и меняет шрифт. 


Автор: Bose 23.4.2009, 02:05
p.s. интерфейсы хороши, когда классы, реализующие их имеют разных предков. А в случае, когда всё это формы в одной программе, проще создать предка и реализовать это в нём.
В смысле, интерфейсы здесь необязательны.

Автор: pseud 23.4.2009, 10:34
Цитата(Bose @  23.4.2009,  02:05 Найти цитируемый пост)
p.s. интерфейсы хороши, когда классы, реализующие их имеют разных предков. 
А в случае, когда всё это формы в одной программе, проще создать предка и реализовать это в нём.
В смысле, интерфейсы здесь необязательны.

истина

Автор: Caduser 23.4.2009, 13:08
Цитата(pseud @ 23.4.2009,  10:34)
Цитата(Bose @  23.4.2009,  02:05 Найти цитируемый пост)
p.s. интерфейсы хороши, когда классы, реализующие их имеют разных предков. 
А в случае, когда всё это формы в одной программе, проще создать предка и реализовать это в нём.
В смысле, интерфейсы здесь необязательны.

истина

Ага, в этом проекте есть хитрость, там не только формы реализуют интерфейс но и фрейм, т.е. именно разные классы! 

Автор: Bose 23.4.2009, 13:57
Цитата(Caduser @  23.4.2009,  12:08 Найти цитируемый пост)
Ага, в этом проекте есть хитрость, там не только формы реализуют интерфейс но и фрейм, т.е. именно разные классы!  

Но фрейм сам по себе не бывает, и обычно находится на форме - поэтому в данном примере - замену шрифтов может выполнять и сама форма рекурсивно проходя по всем MyForm.Controls[i].

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

Автор: Gwire 23.4.2009, 15:59
smile А еще у визуальный компонентов есть свойство ParentFont унаследованное от TControl
Устанавливаем где нужно в True. И все работает без interface-ров достаточно поменять шрифт на форме и вуаля...

Автор: Gwire 23.4.2009, 16:18
А если нет ParentFont в свойствах то, недавно узнал из http://forum.vingrad.ru/index.php?showtopic=256195&view=findpost&p=1846897,
Код

    if IsPublishedProp(Sender ,'ParentFont')
      then SetOrdProp(Sender, 'ParentFont', Integer(True)); // Uses TypInfo


Автор: pseud 23.4.2009, 16:29
Цитата(Gwire @  23.4.2009,  16:18 Найти цитируемый пост)
А если нет ParentFont в свойствах то, недавно узнал из этой темы,


а теперь вдумайся что вернет:
Код

if IsPublishedProp(Sender ,'ParentFont')

если 
Цитата(Gwire @  23.4.2009,  16:18 Найти цитируемый пост)
 нет ParentFont в свойствах


Автор: Caduser 23.4.2009, 18:03
Цитата(Gwire @ 23.4.2009,  15:59)
smile А еще у визуальный компонентов есть свойство ParentFont унаследованное от TControl
Устанавливаем где нужно в True. И все работает без interface-ров достаточно поменять шрифт на форме и вуаля...

В проекте есть еще одна хитрость - у некоторых  контролов свойство ParentFont = False т.к. изменен цвет и стиль шрифта. Если ParentFont установить в True то настройки цвета и стиля будут утеряны.
Кроме того, проблема не только в том что ParentFont = False но и в том, что при изменении размера шрифта может понадобиться например изменить высоту заголовка грида. Вообщем только сама форма "знает" как и что ей корректно изменить при изменении размера шрифта. 

Автор: Caduser 24.4.2009, 14:31
Цитата(Bose @ 23.4.2009,  01:44)
А ещё лучше вынести реализацию интер
Код

фейса IOperations в отдельный класс. Например
type 
  TMyOperations = class(TInterfacedObject, IOperations)
  private
    FOwner:TControl; // минимальный класс, имеющий свойство Font
  protected  
    // Ioperations procedures
    procedure AddToList;virtual;
    procedure DeleteFromList;virtual;
    procedure SetFontSize(const FontSize: Integer);virtual;
  public
     constructor Create(aOwner: TControl);
  end;


А в базовой форме объявить так
Код

TMyForm = class(TForm, IOperations)
private
   FMyOperations: Ioperations; implements Ioperations;

И создавать FMyOperations := TMyOperations.Create(self) в конструкторе формы а убивать в деструкторе.

Идея интересная, однако не до конца ее понял, реализовать ее не удалось. Предложите прям в проекте? чтоб скомпилировать можно было.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)