Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.06.08;
Скачать: CL | DM;

Вниз

Ищется элегантное решение.   Найти похожие ветки 

 
Василий Василич Пупкинд   (2008-05-15 17:53) [0]

Имеется иерархия форм отображения данных бд.
Весь функционал и окончательный внешний вид реализован в предпоследних элементах иерархии (форма для конкретных данных).
В последних элементах иерархии (наследниках предпоследних) добавлены компоненты доступа к бд и переопределены некоторые методы зависимые от движка.
Как сделать доступным в методах предпоследнего элемента датасеты последнего элемента иерархии?


 
Palladin ©   (2008-05-15 17:57) [1]

Ожерелье для свиньи ищешь?


 
Игорь Шевченко ©   (2008-05-15 17:57) [2]

интерфейс реализовать ?


 
DrPass ©   (2008-05-15 17:58) [3]


> Как сделать доступным в методах предпоследнего элемента
> датасеты последнего элемента иерархии?

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


 
Юрий Зотов ©   (2008-05-15 18:04) [4]

Вынести датасеты в модуль данных.


 
Василий Василич Пупкинд   (2008-05-15 18:07) [5]

Объявить в предпоследнем элементе свойства соответствующего типа,

Не все так просто.

создается экземпляр последнего элемента и вызывается унаследованный метод(ы) предпоследнего. У него все методы тоже виртуальные но толку-то от этого, если они вызываются из методов предка.  свои же предковые методы и вызываются хотя все они переопределены в последнем.


 
Василий Василич Пупкинд   (2008-05-15 18:07) [6]

интерфейс реализовать ?

Дык как?


 
Василий Василич Пупкинд   (2008-05-15 18:09) [7]

Ожерелье для свиньи ищешь?

Хочу обмануть судьбу (иметь возможность за 20 минут портировать приложение под другие либы доступа)


 
Василий Василич Пупкинд   (2008-05-15 18:12) [8]

Вынести датасеты в модуль данных.

Не подойдет.
суть идеи в том, что все алгоритмы обработки реализованы в предпоследнем элементе, который ничего не должен знать о библиотеке доступа.


 
Palladin ©   (2008-05-15 18:14) [9]


> Как сделать доступным в методах предпоследнего элемента
> датасеты последнего элемента иерархии?

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


 
Palladin ©   (2008-05-15 18:15) [10]


> суть идеи в том, что все алгоритмы обработки реализованы
> в предпоследнем элементе, который ничего не должен знать
> о библиотеке доступа.

а вот эта самое суть есть "свинья"... на которую ожерелье ищется...


 
Василий Василич Пупкинд   (2008-05-15 18:20) [11]

Тем не менее ищется способ быстро переходить с одной библиотеки доступа на другую. Малой кровью.


 
Василий Василич Пупкинд   (2008-05-15 18:22) [12]

а вот эта самое суть есть "свинья"... на которую ожерелье ищется...

Это не свинья, а заветная мечта по имени "повторное использование кода"


 
Palladin ©   (2008-05-15 18:24) [13]


> Василий Василич Пупкинд   (15.05.08 18:22) [12]

я не вник в то что ты написал конкретно, показалось что ты хочешь ближе к вершинам иерархии связку приложить...

про ввод ассоциации с источником данных я тебе уже написал


 
Василий Василич Пупкинд   (2008-05-15 18:31) [14]

Пока есть одно решение моей задачи.
Сделаю нечто похожее на класс TDBFeatures из EhLib"а.
Там грид ничего не зная о классе датасета, тем не менее может работать с его свойствами и методами.


 
ANB   (2008-05-15 18:57) [15]


> Там грид ничего не зная о классе датасета, тем не менее
> может работать с его свойствами и методами.

Дык это любой грид умеет. Как и любой DB контрол в делфи.


 
Василий Василич Пупкинд   (2008-05-15 19:02) [16]

Ага щас. Любой.
Берем грид + датасорс.
датасорс смотрит либо на TADODataset либо на TQuery.
Задача: Внутри методов грида узнать текст sql результаты которого в гриде.


 
Василий Василич Пупкинд   (2008-05-15 19:15) [17]

В общем придумал. Счастье есть.
Все будет даже проще чем у большакова.
В модуле предпоследнего класса заводим паблик переменную типа предпоследнего класса.
при создании экземпляра наследника инициализируем её экземпляром наследника. Теперь когда в предпоследнем эшелоне потребуется конкретный датасет, буду вызывать виртуальный метод гет_ми_нужныйдатасет через эту переменную.

Вопрос по существу: как по английски назвать переменную "обманщик судьбы"?
:)))


 
Василий Василич Пупкинд   (2008-05-15 19:20) [18]

var destiny_fucker : TOlmostLastClassInHierarchy = nil;

вопрос закрыт, всем спасибо за внимание.


 
Юрий Зотов ©   (2008-05-15 19:33) [19]

> Василий Василич Пупкинд   (15.05.08 19:15) [17]

> В модуле предпоследнего класса заводим паблик переменную
> типа предпоследнего класса. при создании экземпляра наследника
> инициализируем её экземпляром наследника.

Который будет точно равен Self. Решение поистине элегантнейшее. LOL.

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

Нет, это будет вызов не через переменную, а через другое место. А через нормальное место это делается, например, так:

type
 предпоследний_класс = class(...)
 protected
   function гет_ми_нужныйдатасет; virtual; abstract;
 end;


 
Василий Василич Пупкинд   (2008-05-15 19:52) [20]

Который будет точно равен Self. Решение поистине элегантнейшее. LOL.

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

Нет, это будет вызов не через переменную, а через другое место. А через нормальное место это делается, например, так:

type
предпоследний_класс = class(...)
protected
  function гет_ми_нужныйдатасет; virtual; abstract;
end;


Да вот хренушки вам, а не нормалоьное место.
Вызов-то делает не наследник, а предок, который ничего не знает о классе наследника. Это если не классовый метод.
Если метод классовый как у вас, то модуль предпоследнего класса должен знать все библиотеки доступа.
То есть с чем боролись, на то и напоролись.

Впрочем я уже опробовал свой метод. Все работает как часы.


 
Василий Василич Пупкинд   (2008-05-15 19:56) [21]

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


 
Юрий Зотов ©   (2008-05-15 20:07) [22]

Василий Василич, скажите, а Вам слова "наследование", "полиморфизм" и "виртуальный метод" знакомы?

И понятны?

Очень похоже, что нет.

По крайней мере, из Ваших слов "Если метод классовый как у вас" (то есть, у меня в [19]) следует однозначный вывод о том, что термин "классовый метод" Вы точно не понимаете.

Поскольку в [19] ни одного классового метода просто нет.


 
Василий Василич Пупкинд   (2008-05-15 20:12) [23]

Да мне-то они знакомы хорошо знакомы и известны.
Как и то, что метод предложенный вами не прокатит.

Подозреваю, что вы просто не врубились в то, что мне нужно было реализовать.
С классовым методом - да. Глаз под вечер замылен, не заметил. Что впрочем никоим образом не меняет сути сказанного.


 
Юрий Зотов ©   (2008-05-15 20:16) [24]

> Василий Василич Пупкинд   (15.05.08 19:56) [21]

Немного поясню: человек, который понимает, что такое полиморфизм м виртуальный метод ни за что не напишет вот такого:

> хоть ты запереопределяйся методы гетми в последнем классе, но
> диспетчиризация то вызовет метод предпоследнего класса, а не
> последнего.

Василий Василич, будет вызван метод ПОСЛЕДНЕГО класса, уверяю Вас. Надо только сделать его виртуальным (как и было показано).


 
Василий Василич Пупкинд   (2008-05-15 20:16) [25]

Чтобы было совсем понятно объясняю "на пальцах" :
откройте любую демку от делфи из папке db.
возьмите любую форму с гридом у которой создаются экземпляры на рантайме.
уберите из нее все датасеты (или почистите юзес если все они в модуле данных)
создайте наследника этой формы и положите туда скажем TpFIBDataset

после чего найдите способ сохранить весь фукционал в предке так, чтобы он был независим от фибсов.


 
Василий Василич Пупкинд   (2008-05-15 20:18) [26]

Василий Василич, будет вызван метод ПОСЛЕДНЕГО класса, уверяю Вас. Надо только сделать его виртуальным (как и было показано).

А если у меня десять наследников, то метод какого из них будет вызван?
ЗЫ кнопка-то в предке лежит и обработчик нажатия там же.
И переносить этот код в последние классы мне не улыбается.


 
Василий Василич Пупкинд   (2008-05-15 20:25) [27]

Ну или чтоб не блазнил мой пример с глобальной переменной (самого воротит от нее) скажите как установить значение поля класса предка при том, что его экземпляра не существует.


 
Юрий Зотов ©   (2008-05-15 20:39) [28]

> Василий Василич Пупкинд   (15.05.08 20:16) [25]

Для таких детских игрушек даже и Delphi не нужна. Ловите готовый код, вот прямо здесь его щас и напишу.

type
 TАncestorForm = class(TForm) // Можно поместить в репозиторий
   Grid: TDBGrid;
   Button: TButton;
   procedure ButtonClick(Sender: TObject);
   // Добавить обработчик OnClose с Action := caFree
 protected
   function GetDataSource: TDataSource; virtual; abstract;
 end;

procedure TАncestorForm.ButtonClick(Sender: TObject);
begin
 Grid.DataSource := GetDataSource;
 Grid.DataSet.Open;
end;

===============  

type
 TDescendantForm = class(TАncestorForm)
   DataSet: TQuery; // Или какой Вам нужен. Настроить в design-time.
   DataSource: TDataSource; // Настроить в design-time.
 protected
   function GetDataSource: TDataSource; override;
 end;

function TDescendantForm.GetDataSource: TDataSource;
begin
 Result := DataSource;
end;
     
============

В программе создаем рабочую форму:
TAncestorForm.Create(Application).Show;
И жмем  на ней кнопку.


 
Юрий Зотов ©   (2008-05-15 20:44) [29]

> Василий Василич Пупкинд   (15.05.08 20:25) [27]

> как установить значение поля класса предка при том, что его экземпляра
> не существует.

Написать виртуальный сеттер и перекрыть его в потомке.


 
Юрий Зотов ©   (2008-05-15 20:54) [30]

> Василий Василич Пупкинд

Но вообще-то, Вам сказали правильно - надо делать наоборот. Предки (или модули данных) должны определять данные, а потомки - визуальную часть.


 
Игорь Шевченко ©   (2008-05-15 21:11) [31]


> Берем грид + датасорс.
> датасорс смотрит либо на TADODataset либо на TQuery.
> Задача: Внутри методов грида узнать текст sql результаты
> которого в гриде.


Тоже мне, бином Ньютона:

function GetSQLText (DataSet: TdataSet): string;
var
 SQL: TStrings;
begin
 Result := "";
 if IsPublishedProp(DataSet, "SQL") then
 begin
   SQL := GetObjectProp(DataSet, "SQL") as TStrings;
   if Assigned(SQL) then
     Result := SQL.Text;
 end;
end;


 
Palladin ©   (2008-05-15 21:22) [32]

Вот, Юр, наглядный пример мартышки и очков... все знаем, но чет сделать не можем...


 
Юрий Зотов ©   (2008-05-15 21:40) [33]

> Palladin ©   (15.05.08 21:22) [32]

Не... тут другое. Никто же Delphi не ругает (а мартышка ругала очки). Тут довольно сильное завышение оценки собственного понимания ООП и знания Delphi.

В частности, вот это меня просто убило:

> В модуле предпоследнего класса заводим паблик переменную
> типа предпоследнего класса. при создании экземпляра наследника
> инициализируем её экземпляром наследника.

И не понимает человек элементарнейше вещи - что это будет просто тот же самый Self. Хотя слов произносит много, и все они такие умные, и спорит еще...

Ппц. Полный.

PS
Василий Василич, уж извините великодушно за обидные, возможно, слова, но ведь правда это. Да ведь и сами Вы виноваты, если уж честно-то.


 
Palladin ©   (2008-05-15 21:54) [34]


> Никто же Delphi не ругает (а мартышка ругала очки).

а :)... в этом плане да... не похоже... но подход... ему говорят одень, а он - "так не надевается, неыозможно" и продолжает нюхать...


 
Василий Василич Пупкинд   (2008-05-15 23:09) [35]

Тоже мне, бином Ньютона:

function GetSQLText (DataSet: TdataSet): string;
var
SQL: TStrings;
begin
Result := "";
if IsPublishedProp(DataSet, "SQL") then
begin
  SQL := GetObjectProp(DataSet, "SQL") as TStrings;
  if Assigned(SQL) then
    Result := SQL.Text;
end;
end;


Открыл чайнику америку ртти.
А откуда знаем-то что текст sql лежит в свойстве с именем SQL?


 
Игорь Шевченко ©   (2008-05-15 23:15) [36]

Василий Василич Пупкинд   (15.05.08 23:09) [35]

Ты из произвольного потомка DataSet желаешь достать SQL ?


 
Василий Василич Пупкинд   (2008-05-15 23:20) [37]

Разумеется.


 
Юрий Зотов ©   (2008-05-15 23:39) [38]

> Василий Василич Пупкинд   (15.05.08 23:20) [37]

А если его там и нет вовсе? Например, потомок TDataSet, который и не с БД работает вовсе, а с XML-файлом, или с IStorage каким-нибудь? И никакие SQL ему и на фиг не нужны?


 
Василий Василич Пупкинд   (2008-05-15 23:44) [39]

Но вообще-то, Вам сказали правильно - надо делать наоборот. Предки (или модули данных) должны определять данные, а потомки - визуальную часть.

кому надо наоборот? мне не надо. мне надо так, как задумано.
по поводу профана в ооп - юмор мимо кассы.

в чем действительно была причина возникшего недоразумения? объясняю.

был специализированных модуль данных (под конкретную библиотеку)
на основе его был написан универсальный модуль-предок всех модулей данных.
в исходном модуле была куча процедур с шаблоном вида:
with TAdoDataSet.Create(self) do
try
...
finally
 Free;
end;

в универсальном предке они были изменены на нечто подобное :
if createdatasetcomponent(ASQLtext, DSComp) then
 try
 finally
  Free;
 end;

то есть после копипаста и стирания with по невнимательности в одном месте остался висячий Free, который грохал модуль данных.

Вот из за этой ерунды мне и причудилось странное.


 
Василий Василич Пупкинд   (2008-05-15 23:46) [40]

А если его там и нет вовсе? Например, потомок TDataSet, который и не с БД работает вовсе, а с XML-файлом, или с IStorage каким-нибудь? И никакие SQL ему и на фиг не нужны?

<Цитата>
и в чем проблема? ехлибовский метод получения sql просто ничего не вернет. А метод ИШ будет перебирать все известные на момент написания грида имена свойств в которых могут находится sql выражения



Страницы: 1 2 вся ветка

Текущий архив: 2008.06.08;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.019 c
2-1210690049
wnix
2008-05-13 18:47
2008.06.08
Работа с файлом


15-1208945641
Armond
2008-04-23 14:14
2008.06.08
Компоненты


15-1209382158
Ega23
2008-04-28 15:29
2008.06.08
Криптостойкость AES - что взломать проще?


15-1209062198
Palladin
2008-04-24 22:36
2008.06.08
Кибепрнетика


15-1209092932
azamatufa
2008-04-25 07:08
2008.06.08
Нужна защита от СПАМА!!! Админы, сделайте цифорки!!!