Розробка db-aware компонентів

Структура DB-Aware компонентів
клас TDataLink
Вибір способу організації каналу даних.
Розробка компонентів, що відображають набір даних
Розробка компонентів, що модифікують набір даних

Розробка db-aware компонентів

Структура DB-Aware компонентів

Для здійснення цього перетворення необхідно всього лише включити в наявний клас компонента додаткове поле і написати кілька методів, що забезпечують зв'язок між компонентом і набором даних.

Іншими словами, щоб створити DB-A, потрібно підібрати найбільш відповідний нашим вимогам компонент, після чого описати поведінкову модель зв'язки компонент-дані. Необхідно зауважити, що ніяких особливих вимог до наявного компоненту не пред'являється, це може бути графічний або віконний елемент керування, невізуальний компонент, діалог і так далі.

  • компоненти, тільки відображають дані
  • компоненти, здатні модифікувати набори даних.

Природно, що перший тип компонентів влаштований простіше, ніж другий.

У загальному випадку схема побудови компонентів, які працюють з даними, може бути представлена ​​наступним чином (малюнок 1):

Перейдемо до розгляду реалізації DataLink. Для неї існує відповідний клас TDataLink, йому присвячений наступний розділ.

клас TDataLink

Клас TDataLink є базовим класом для ієрархії класів зв'язку з БД. Клас забезпечує комунікаційний канал для читання / запису в БД.

Даний клас описаний в модулі DB, а його інтерфейсна частина виглядає наступним чином (private-секція опущена):

Зв'язок для управління наборами даних, пов'язаними відносинами головний - підлеглий.

Вибір способу організації каналу даних.

Як було сказано вище, існує безліч готових каналів зв'язку для різних цілей. Таким чином, для організації зв'язку вашого компонента з набором даних завжди можна взяти готовий клас. В цьому випадку при створенні компонента необхідно призначити динамічно обробники подій обраного каналу даних.

Давайте розглянемо, як реалізована ця концепція в одному з найбільш часто використовуваних класів - TDEdit, «усічений» варіант опису якого наведено нижче:

Як було сказано вище, канал зв'язку створюється в конструкторі. Методи обслуговування подій набору даних реалізовані у вигляді обробників подій.

Як видно з опису конструктора, в компоненті активно використовується динамічне призначення подій, що в принципі не є хорошим тоном в програмуванні компонентів. Однак в цьому випадку поле FDataLink є приватним і перепризначити події користувачеві не вдасться.

Список подій TFieldDataLink наведено в таблиці:

Зміни даних викликані однієї з наступних причин: - Перехід до нового запису або столбцу- Перехід в режим редагування набору даних-Зміни властивостей DataSource або DataField -Відновлення старих значень викликом Cancel

Вхід або вихід в / з режиму редагування набору даних

Запис змін в БД

Зміна властивості Active підключеного набору даних

В силу своєї простоти такий спосіб організації DB-AWARE-компонентів є оптимальним при створенні досить простих рішень, однак він має кілька недоліків, серед яких:

  • У успадкованих класах поведінку компонента важко модифікувати;
  • У разі проектування складних компонентів виходить досить мають важко код, так як код, пов'язаний з обробкою даних, і код безпосередньо компонента знаходяться всередині однієї сутності.

Другим поширеним підходом є написання свого каналу зв'язку для компонентів. Це набагато більш трудомістка процедура, але вона того варта. Подальші приклади цієї глави демонструють розробку DB-Aware-компонентів саме таким способом.

Розробка компонентів, що відображають набір даних

Компоненти цього типу роду є найбільш простими для розуміння, проте їх розробка потребує чіткого розуміння деталей роботи комунікаційного каналу між набором даних і компонентом.

У бібліотеці стандартних компонентів Delphi є цікавий контрол - DBRadioGroup, як значення для радіокнопок він використовує список типу TStrings, який можна форматувати як на етапі проектування, так і на етапі розробки. Однак досить часто (наприклад, при розробці систем тестування) необхідно цей список запускати з БД, що даний компонент робити не в змозі.

Ми напишемо RadioGroup-компонент, який зможе заповнювати список радіокнопок згідно з даними з поля таблиці.

Тепер розглянемо реалізацію класу зв'язку з даними:

Наш компонент повинен працювати в двох режимах - оновлення списку радіокнопок і безпосередня робота користувача з компонентом. Саме тому потрібно чітко визначити, коли ми будемо оновлювати список кнопок. У нашому прикладі ми робимо це тільки при відкритті / закритті набору даних, а також при модифікації поля, значення з якого беруться в якості значень радіокнопок.

Метод RecordChanged вимагає досить обережного поводження - він викликається дуже часто (при переміщенні від одного запису до іншого, зміні стану набору даних і т.д.). У певному сенсі цей метод нагадує контролер обслуговування події руху мишкою, так як обидва повинні обслуговувати величезну кількість подій і, природно, повинні працювати дуже швидко.

Тепер настав час розглянути компонент, який буде відображати дані:

Зауваження до коду:

  1. Властивість DataSource компонента насправді - однойменне властивість TDataLink
  2. DB-Aware компонент виступає батьком для класу-зв'язки, а, отже, створює і знищує його.
  3. Для того, щоб відключити / включити TDataLink необхідно викликати методи DisableControls / EnableControls набору даних.

Зауваження з приводу правил хорошого тону:

  • Похідний від TDataLink клас повинен в назві містити назву компонента, де він використовується, а також свою основну функцію.
  • Для назви джерел даних, а також для властивостей, що містять імена полів даних, потрібно намагатися використовувати імена, який вже стали стандартом де - факто, крім цього, повинні бути видні зв'язку між джерелами даних і полями. (DataSource - DataField, ListSource - ListField).

Розробка компонентів, що модифікують набір даних

Раніше ми розглянули компонент, який може відображати дані з набору, тепер спробуємо створити ще один компонент, який зможе модифікувати набір даних.

Коли набір даних не знаходиться в режимі редагування, то компонент не може бути активним, однак він зобов'язаний синхронізувати положення обраної кнопки зі значенням поля даних набору:

Коли ж набір даних переходить в режим редагування або додавання нового запису компонент приймає наступний вигляд і дозволяє автоматично занести вибране значення в поле даних:

Для цього нам необхідно ввести ще один канал даних, орієнтований вже на модифікацію даних.

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

Давайте розглянемо реалізацію каналу зв'язку для модифікації даних:

На особливу увагу заслуговують такі методи:

procedure TmmRGWriteDataLink.EditingChanged - реагує на активізацію / деактивацію режимів набору даних (вставка, редагування) іпереводіт компонент в режим модифікації набору даних.

Тепер можна перейти до розгляду самого компонента:

В даному випадку виникла всього одна складність - TCustomRadioGroup на перший погляд не має методу, який був би контролером події призначеного для користувача введення.

Вирішити цю проблему допомогло вивчення вихідних кодів TCustomRadioGroup. Зверніть особливу увагу на реалізацію методу Click, який власне і виконує необхідні нам дії.

Схожі статті