Как спроектировать объект, содержащий списки?
От: boriskr  
Дата: 18.06.08 16:12
Оценка:
Пишу в Kylix.
Есть несколько типов списков, они наследуют от базового класса TBaseList примерно так:
type
 TStorage=class;  // опережающее определение
 TList1=class(TBaseList)
   public
    parent:TStorage;
    ... // тут функции которые работают со Storage
  end;


И есть объект, содержащий несколько таких списков:
type
 TStorage=class
   public
    list1:TList1;
    list2:TList2;
    ....
    listN:TList1;
    .. // куча всякой бузинес-логики    
  end;


Все это работает, если находится в одном pas файле, а я хочу разделить TStorage и списки... тогда опережающее определение не работает!

как быть с объявлением parent, который сейчас TStorage?
... << RSDN@Home 1.2.0 alpha 4 rev. 1091>>
Re: Как спроектировать объект, содержащий списки?
От: Сергей Савостин Украина  
Дата: 18.06.08 18:42
Оценка:
пардон за оффтоп: поделитель Kylix если он моложе 3-го
Re[2]: Как спроектировать объект, содержащий списки?
От: boriskr  
Дата: 18.06.08 19:17
Оценка:
Здравствуйте, Сергей Савостин, Вы писали:

СС>пардон за оффтоп: поделитель Kylix если он моложе 3-го

В наличии есть только 3й. А ранние лучше?
... << RSDN@Home 1.2.0 alpha 4 rev. 1091>>
Re: Как спроектировать объект, содержащий списки?
От: ylem  
Дата: 19.06.08 01:36
Оценка: 1 (1)
Storage и BaseList у Вас очень тесно связаны. Разносить их по разным юнитам неправильно.
А вот перетащить ссылку на Parent в BaseList надо.

Почитайте про паттерн Composite.

Буду рад, если помог.
Re[3]: Как спроектировать объект, содержащий списки?
От: Сергей Савостин Украина  
Дата: 19.06.08 06:49
Оценка:
долго думал как правильно выразиться и таки выразился неправильно.
Имел в виду более поздние версии (к сожалению не в курсе были ли такие в природе).
Спасибо, 3-й сам нашел.
Re: Как спроектировать объект, содержащий списки?
От: __Azeroth Россия  
Дата: 19.06.08 10:20
Оценка: 2 (1)
B>как быть с объявлением parent, который сейчас TStorage?
если TStorage выносить в отдельный модуль, то парент придётся объявить нейтрально например как TObject, а во всех функциях работающих с парентом использовать кастинг, так все делают
Re[2]: Как спроектировать объект, содержащий списки?
От: boriskr  
Дата: 24.06.08 20:34
Оценка:
Здравствуйте, __Azeroth, Вы писали:

B>>как быть с объявлением parent, который сейчас TStorage?

__A>если TStorage выносить в отдельный модуль, то парент придётся объявить нейтрально например как TObject, а во всех функциях работающих с парентом использовать кастинг, так все делают

я сам до этого почти догадался, придумал такое решение: Создать абстрактный класс TStorageInterface,базовый для TStorage и находящийся в отдельном файле. Использовать так же как предлагаемый TObject.
IMHO:
+ не запутаеmься в TObject'aх и касты не надо делать.
— еще один файл и класс.
Re[2]: Как спроектировать объект, содержащий списки?
От: ylem  
Дата: 25.06.08 01:14
Оценка:
Здравствуйте,

__A>так все делают


А для чего так делают?
Для того, что б текст юнитов покороче получался?
Или еще чего-то этим можно добиться?

Андрей
Re: Как спроектировать объект, содержащий списки?
От: int64 Россия  
Дата: 25.06.08 12:18
Оценка:
Здравствуйте, boriskr, Вы писали:

B>Пишу в Kylix.

B>Есть несколько типов списков, они наследуют от базового класса TBaseList примерно так:
B>
B>type
B> TStorage=class;  // опережающее определение
B> TList1=class(TBaseList)
B>   public
B>    parent:TStorage;
B>    ... // тут функции которые работают со Storage
B>  end;
B>


B>И есть объект, содержащий несколько таких списков:

B>
B>type
B> TStorage=class
B>   public
B>    list1:TList1;
B>    list2:TList2;
B>    ....
B>    listN:TList1;
B>    .. // куча всякой бузинес-логики    
B>  end;
B>


B>Все это работает, если находится в одном pas файле, а я хочу разделить TStorage и списки... тогда опережающее определение не работает!


B>как быть с объявлением parent, который сейчас TStorage?


Интерфейсы спасут отца русской демократии.
Re[2]: Как спроектировать объект, содержащий списки?
От: int64 Россия  
Дата: 25.06.08 12:29
Оценка:
Здравствуйте, __Azeroth, Вы писали:

B>>как быть с объявлением parent, который сейчас TStorage?

__A>если TStorage выносить в отдельный модуль, то парент придётся объявить нейтрально например как TObject, а во всех функциях работающих с парентом использовать кастинг, так все делают
Лучше какой-нибудь TAbstractStorage. Чтоб без кастингов.
Re: Как спроектировать объект, содержащий списки?
От: SnowBlast Казахстан  
Дата: 27.06.08 09:41
Оценка:
Здравствуйте, boriskr, Вы писали:

B>Пишу в Kylix.

B>Есть несколько типов списков, они наследуют от базового класса TBaseList примерно так:
B>
B>type
B> TStorage=class;  // опережающее определение
B> TList1=class(TBaseList)
B>   public
B>    parent:TStorage;
B>    ... // тут функции которые работают со Storage
B>  end;
B>


B>И есть объект, содержащий несколько таких списков:

B>
B>type
B> TStorage=class
B>   public
B>    list1:TList1;
B>    list2:TList2;
B>    ....
B>    listN:TList1;
B>    .. // куча всякой бузинес-логики    
B>  end;
B>


B>Все это работает, если находится в одном pas файле, а я хочу разделить TStorage и списки... тогда опережающее определение не работает!


B>как быть с объявлением parent, который сейчас TStorage?

Посмотри в исходниках VCL, как это сам борланд сделал.
Поиск по слову Hack. Например ClxEditors.pas
Как улитка с параличем мчится мысль неудержимо, центр речи возбуждая
Re[2]: Как спроектировать объект, содержащий списки?
От: boriskr  
Дата: 27.06.08 17:29
Оценка:
Здравствуйте, SnowBlast, Вы писали:

SB>Посмотри в исходниках VCL, как это сам борланд сделал.

SB>Поиск по слову Hack. Например ClxEditors.pas
Я не понял, зачем они там перед функцией CreateAction объявляют
 type
  THackAction = class(TCustomAction);

и потом делают
THackAction(Result).FMask.Free;

если можно сразу
TCustomAction(Result).FMask.Free;
Re[3]: Как спроектировать объект, содержащий списки?
От: Danchik Украина  
Дата: 01.07.08 10:23
Оценка:
Здравствуйте, boriskr, Вы писали:

B>Здравствуйте, SnowBlast, Вы писали:


SB>>Посмотри в исходниках VCL, как это сам борланд сделал.

SB>>Поиск по слову Hack. Например ClxEditors.pas
B>Я не понял, зачем они там перед функцией CreateAction объявляют
B>
 type
B>  THackAction = class(TCustomAction);
B>

B>и потом делают
B>
THackAction(Result).FMask.Free;

B>если можно сразу
B>
TCustomAction(Result).FMask.Free;


ПАтАму чтА в Object Pascal доступ к protected полям разрешается всем класам и методам юнита в котором клас задекларирован. Тоесть THackAction в этом юните значит доступ будет открыт. А вот TCustomAction задекларирован совсем в другом месте, значит к protected полям мы не доступимся.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.