Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.06.08;
Скачать: [xml.tar.bz2];

Вниз

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

 
Василий Василич Пупкинд   (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 выражения


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

> по поводу профана в ооп - юмор мимо кассы.

Ну что ж, Вам виднее. Хотя вызывается почему-то все же метод потомка.

Полиморфизьм, панимашь... тудыть его в качель... мимо кассы...
;o)



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

Форум: "Начинающим";
Текущий архив: 2008.06.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.046 c
15-1208981134
@!!ex_
2008-04-24 00:05
2008.06.08
Кому не лень - помогите.


2-1209999304
TStas
2008-05-05 18:55
2008.06.08
Что такое class of ?


2-1211177784
WebSQLNeederr
2008-05-19 10:16
2008.06.08
AnsiReplaceText несколько раз и разные замены - как?


15-1209268074
sauron
2008-04-27 07:47
2008.06.08
Разработчикам...


3-1199896167
AlexeyMir
2008-01-09 19:29
2008.06.08
Cвойства полей базы Firebird.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский