Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
9-1175779923
ElectriC
2007-04-05 17:32
2008.12.07
Запрет нажатия системных клавиш


2-1225093757
Иван
2008-10-27 10:49
2008.12.07
Загрузка страницы со скриптами в TWebBrowser


2-1225359412
Thor234
2008-10-30 12:36
2008.12.07
Массив


2-1225432186
Uno-84
2008-10-31 08:49
2008.12.07
Как выделить дату в MonthCalendar?


1-1202923120
Ukrainec
2008-02-13 20:18
2008.12.07
Как отослать комбинацию клавиш Ctrl+V Opere?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский