Форум: "Прочее";
Текущий архив: 2008.12.07;
Скачать: [xml.tar.bz2];
ВнизОткрытие методов класса внутри другого класса Найти похожие ветки
← →
Буум (2008-10-02 15:18) [0]Иногда возникает такая ситуация - допустим, есть некий класс, выполняющий некий функционал:
TLittleClass = class
function Delete ;
function Paint;
end;
Есть класс, который внутри имеет экземпляр данного класса:TBigClass = class
private/public
FLittle: TLittleClass;
public
function Delete;
function Paint;
...
end;
А реализация аля типа такого:function TBigClass.Delete;
begin
FLittle.Delete;
TextToLog("Delete Complete");
end;
function TBigClass.Paint;
begin
FLittle.Paint;
end;
Если словами - то в классе (TBigClass) есть экземпляр другого класса (TLittleClass), который выполняет некий функционал.
При этом TBigClass должен ИНОГДА знать, когда дергаются методы TLittleClass. Возникает вопрос как это все организовать.
С одной стороны экземпляр TLittleClass можно вывести в public секцию TBigClass, вызовы будут аля:TBigClass.Little.Delete;
Тогда BigClass не узнает о вызове методов LittleClass.
Можно сделать в BigClass прослойки в виде методов. Но если метод:function TBigClass.Delete;
begin
FLittle.Delete;
TextToLog("Delete Complete");
end;
Выглядит еще более менее, то чисто прослойки:function TBigClass.Paint;
begin
FLittle.Paint;
end;
выглядят глупо.
Еще можно в TLittleClass делать события, на которые подписывать TBigClass... Но как-то сложновыглядит.
Кто какой способ выбирает (возможно иные)?
P.S. Логично было б сказать, что TBigClass нужно наследовать от TLittleClass, но это невозможно по причине того, что TBigClass уже наследовался от какого-то базового класса, а множественного наследования вроде как нету в D...
← →
KSergey © (2008-10-02 15:22) [1]> Буум (02.10.08 15:18)
> P.S. Логично было б сказать, что TBigClass нужно наследовать
> от TLittleClass, но это невозможно по причине того, что
> TBigClass уже наследовался от какого-то базового класса,
> а множественного наследования вроде как нету в D...
А наследование может быть очень даже глубоко вложенным и его множественность тут ни при чем.
← →
Плохиш © (2008-10-02 15:35) [2]
> P.S. Логично было б сказать, что TBigClass нужно наследовать
> от TLittleClass, но это невозможно по причине того, что
> TBigClass уже наследовался от какого-то базового класса,
> а множественного наследования вроде как нету в D...
Ты больше такой литературы не кури.
← →
Ega23 © (2008-10-02 15:39) [3]
> С одной стороны экземпляр TLittleClass можно вывести в public
> секцию TBigClass, вызовы будут аля:
> TBigClass.Little.Delete;
> Тогда BigClass не узнает о вызове методов LittleClass.
type
TLittleClassEvent = procedure () of object;
TLittleClass = class
private
FOnDelete : TLittleClassEvent;
public
procedure Delete;
property OnDelete : TLittleClassEvent read FOnDelete write FFOnDelete;
end;
TBigClass = class
private
FLittle := TLittleClass;
procedure OnLittleDelete;
public
constructor Create;
destructor Destroy; override;
property Littlte : TLittleClass read FLittle;
end;
procedure TLittleClass.Delete;
begin
// удаляем чо надо
if Assigned(FOnDelete) then
FOnDelete;
end;
constructor TBigClass.Create;
begin
inherited;
FLittle := TLittleClass.Create;
FLittle.OnDelete := OnLittleDelete;
end;
destructor TBigClass.Destroy;
begin
FLittle.Free;
inherited;
end;
procedure TBigClass.OnLittleDelete;
begin
TextToLog("Delete Complete");
end;
Как-то так.
← →
Плохиш © (2008-10-02 15:42) [4]
> Ega23 © (02.10.08 15:39) [3]
Зачем городить такой геморрой, если есть возможность изменить исходный класс TLittleClass?
← →
pasha_golub © (2008-10-02 15:44) [5]
> Еще можно в TLittleClass делать события, на которые подписывать
> TBigClass... Но как-то сложновыглядит.
Разработчики VCL так не считают. Например, TQuery.SQL: TStrings. Подвешен обработчик на изменение.
← →
jack128_ (2008-10-02 15:46) [6]
ILittle = interface
function Delete ;
function Paint;
end;
TLittle = class(TObject, ILittle)
function Delete ;
function Paint;
end
TBigClass = class(TObject, ILittle)
private
FLittle: TLIttle;
property Little: TLittle read FLittle implements ILIttle;
procedure ILittle.Delete = MyDelete;
procedure MyDelete;
end
procedure TBigClass.MyDelete;
begin
FLittle.Delete;
TextToLog("Delete Complete");
end;
соответственно вместо TBigClass используешь ILittle
← →
pasha_golub © (2008-10-02 15:50) [7]Ну, Жека, намудрил. :0)
← →
KSergey © (2008-10-02 15:51) [8]> pasha_golub © (02.10.08 15:44) [5]
Это да, но есть подозрение, что в описанной задаче автору оно не нужно.
Т..к если класс вложен в другой как private, то каждый из них совершенно точно знает когда и какой из его методов вызывается. Так же внешний класс всегда точно знает когда и какие методы вложенного вызывается.
А если начать уведомлять при такой схеме вложенный класс о вызовах методов родителя - то возникнет дикая каша.
← →
jack128_ (2008-10-02 15:52) [9]
> Ega23 © (02.10.08 15:39) [3]
будет 10 таких методов - будешь десять событий делать ?? не многовато ?
← →
Плохиш © (2008-10-02 15:53) [10]
> jack128_ (02.10.08 15:46) [6]
[4]
← →
oxffff © (2008-10-02 15:53) [11]
> function TBigClass.Paint;
> begin
> FLittle.Paint;
> end;
function TBigClass.Paint;inline
begin
FLittle.Paint;
end;
← →
Ega23 © (2008-10-02 15:56) [12]
> будет 10 таких методов - будешь десять событий делать ??
> не многовато ?
Я проектировать так не буду... :)
← →
oxffff © (2008-10-02 15:57) [13]
> Выглядит еще более менее, то чисто прослойки:
>
> function TBigClass.Paint;
> begin
> FLittle.Paint;
> end;
>
> выглядят глупо.
Я бы не стал употреблять слово глупо. Есть понятия агрегирования, делегирования, наследования,использования. Это не глупые понятия. :)
← →
Игорь Шевченко © (2008-10-02 16:07) [14]гуру рекомендуют следующее: тот, кто использует внешний класс, не должен знать об его устройстве. То есть, BigClass.FLitteClass.Paint - это есть ересь, за которую гореть в вечном адском огне.
Но тем не менее, это наиболее простой и быстрый способ.
← →
{RASkov} © (2008-10-02 16:08) [15]> P.S. Логично было б сказать, что TBigClass нужно наследовать
> от TLittleClass, но это невозможно по причине того, что
> TBigClass уже наследовался от какого-то базового класса,
> а множественного наследования вроде как нету в D...
А если вот так:TBigClass = class(TBaseClass)
.....
end;
TClass = class(TBigClass)
procedure Delete;
procedure Paint;
end;
?
Что-то я не в теме наверное :(
Но если так не пойдет, то в [0] вроде тоже нормально..... А как иначе? [6] - тоже придется структуру менять... т.е. как и тут я предлогаю...
← →
oxffff © (2008-10-02 16:11) [16]
> Игорь Шевченко © (02.10.08 16:07) [14]
oxffff © (02.10.08 15:53) [11]
Позволяет при сходной скорости вызова, не раскрывать тайны делегата.
← →
oxffff © (2008-10-02 16:17) [17]
> jack128_ (02.10.08 15:46) [6]
> ILittle = interface
> function Delete ;
> function Paint;
> end;
> TLittle = class(TObject, ILittle)
> function Delete ;
> function Paint;
> end
>
> TBigClass = class(TObject, ILittle)
> private
> FLittle: TLIttle;
> property Little: TLittle read FLittle implements ILIttle;
>
> procedure ILittle.Delete = MyDelete;
> procedure MyDelete;
> end
>
> procedure TBigClass.MyDelete;
> begin
> FLittle.Delete;
> TextToLog("Delete Complete");
> end;
> соответственно вместо TBigClass используешь ILittle
Можно просто
TLittle = class(TObject)
function Delete ;
function Paint;
end
← →
jack128_ (2008-10-02 16:35) [18]
> oxffff © (02.10.08 16:17) [17]
а как тогда использовать TBigClass ??
← →
DVM © (2008-10-02 16:56) [19]
> то чисто прослойки:
>
> function TBigClass.Paint;
> begin
> FLittle.Paint;
> end;
>
> выглядят глупо.
Нормально выглядит. Особенно хорошо это выглядит, когда используешь чужой класс и не приходится изучать что внутри него надо дергать.
← →
Буум (2008-10-02 17:02) [20]
> А наследование может быть очень даже глубоко вложенным и
> его множественность тут ни при чем
причем здесь вложенное. Я говорю про множественное наследование, что нельзя наследоваться сразу от двух классов.
Ega23, тебя я понял. Ты реализовал:
>Еще можно в TLittleClass делать события, на которые подписывать TBigClass
jack128_, тебя тоже понял, множественное наследование через интерфейсы.
> тот, кто использует внешний класс, не должен знать об его
> устройстве. То есть, BigClass.FLitteClass.Paint - это есть
> ересь, за которую гореть в вечном адском огне
так а каков ваш вариант?
← →
Буум (2008-10-02 17:04) [21]
> Особенно хорошо это выглядит, когда используешь чужой класс
> и не приходится изучать что внутри него надо дергать
вот именно ;) Но если таких прослоек-методов много (с десяток допустим), при этом "перекрыты" только пара - выглядит не кузяво ;)
← →
oxffff © (2008-10-02 17:19) [22]
> jack128_ (02.10.08 16:35) [18]
>
> > oxffff © (02.10.08 16:17) [17]
>
> а как тогда использовать TBigClass ??
Я имею ввиду, что ты делаешь geletate to class type property
Вместо TLittle = class(TObject, ILittle) в твоем коде достаточно,
TLittle = class(TObject)
Таким образом ты еще не вмешиваешься в класс делегат.
← →
jack128_ (2008-10-02 17:26) [23]а. Ну да.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2008.12.07;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.006 c