В статье «Сильный Delphi RTTI - обсуждение необходимости понимания нескольких языков разработки», я сказал, что использовал RTTI Delphi для реализации простой объективации наборов данных. Эта статья подробно представляет мой метод реализации.
Давайте начнем с простого примера: предположим, что есть управление Adodataset, которое подключается к базе данных Roswen, а SQL:
Выберите * от сотрудника
Теперь вам нужно отобразить четыре поля сотрудника, FirstName, Lastname и DateDate в своем контенте в ListView. Традиционный код заключается в следующем:
С Adodataset1, начинайте открыться; FieldByName (LastName '). Asstring);
Здесь есть несколько основных проблем:
1. Прежде всего, есть много кодов, которые очень многословны. Например, FieldByName и ASXXX и т. Д., В частности, ASXXX, вы всегда должны помнить, что такое тип каждого поля, что легко совершать ошибки. Более того, если некоторые несовместимые типы не могут быть автоматически преобразованы, ошибки не будут найдены до среды выполнения.
2. Вам нужно обработать текущее движение записи самостоятельно. Как и следующее выше, в противном случае мертвая петля произойдет, как только вы ее забудете.
3. Самое главное, что имя поля проходит через параметр строки. FieldByName, это, вероятно, сделает такое, что проблема появится только в том случае, если она будет отложена клиенту. Этот вид неверных имен поля легко случиться, особенно когда в программе используются несколько таблиц, легко путать имена поля разных таблиц.
В эту эпоху управляет ОО, когда мы сталкиваемся с операциями, связанными с наборами данных, мы все равно должны часто попадать в детали реляционной базы данных, упомянутой выше. Конечно, есть также способ избавиться от них сейчас, то есть картирование O/R, но картирование O/R слишком отличается от традиционных методов развития, особенно для некоторых небольших приложений, нет необходимости преувеличивать Это.
Вдохновленный Java и другими динамическими языками, я подумал об использовании мощных RTTI Delphi для реализации этой простой схемы объективации набора данных. Ниже приведено код приложения, объектифицированный набор данных, который реализует те же функции, что и традиционный код:
Тип TDSpemployee = Class (TmdatasetProxy). SetVariant; (emp.mployeeid); emp.free;
Использование очень простое. Самое главное - сначала определить класс прокси, который использует опубликованный атрибут для определения всех полей, включая их типы, а затем вы можете манипулировать набором данных по объектному способу. Этот прокси -класс получен из TmdatasetProxy, который использует RTTI для реализации отображения от операций атрибутов в полевые операции. Подразделения реализации этого класса будут подробно объяснены ниже.
На первый взгляд, существует дополнительный класс прокси, который определяет набор данных, который, по-видимому, имеет больше кода, но это одноразовая вещь, особенно когда программа необходимо повторно использовать одну и ту же структуру наборов данных много раз, код будет сделано. Более того, определение этого прокси -класса очень просто. Функции доступа к атрибуту GETXXX/SETXXX все реализованы в базовом классе TMDatasetProxy.
Теперь давайте посмотрим на цикл, соответствующий исходному коду:
1. FieldbyName и ASXXX не нужны, и они стали операциями атрибутов на классах прокси. это. Если используется неправильный тип, во время компиляции сообщается об ошибке.
2. Используйте Foreach, чтобы выполнить рекордсмену, и больше не нужно беспокоиться о том, чтобы забыть о порочной петле, вызванной следующим.
3. Самое большое преимущество заключается в том, что имя поля становится свойством, поэтому вы можете пользоваться преимуществами проверки поля во время компиляции.
Теперь начните обсуждать tmdatasetproxy. Код его реализации заключается в следующем:
(******************************************* ************* •Дата: 28-05 января ************************************** ******************) (Aindex: Integer): ShortString; ; ; ; : Tdataset); ClassInfo)^. Propcount; (Fproplist) затем Freemem (Fproplist); Tmproplist.getpropname (aindex: Integer): ShortString; начало результат: = getProp (aindex)^ ; end; Процедура tmdatasetproxy.beginEdit; begin if (fdataset.state <> dsedit) и (fdataset.state <> dsinsert), затем fdataset.edit; end; процедура tmdatasetproxy.enditit; begin if (fdataset.state = dsedit) или (fdataset; .State = dsinsert) затем fdataset.post; end; функция tmdatasetproxy.getinteger (aindex: Integer): Integer; : Integer): Double; начало результат: = fdataset.fieldbyname (fproplist.propnames [aindex]). aindex]) .asstring; end; function tmdatasetproxy.getvariant (aindex: integer): variant; begin result: = fdataset.fieldbyname (fproplist.propnames [aindex]). ); ]. Aindex: Integer; Начинать;
Класс TMProplist представляет собой инкапсуляцию некоторых функций операции атрибута RTTI. Его функция состоит в том, чтобы использовать некоторые функции RTTI, определенные Delphi в устройстве Typinfo для реализации полученного класса Tpersistent для поддержания опубликованной информации о списке свойств. Класс прокси получает имя атрибута через этот список атрибутов и, наконец, работает через это имя атрибута и соответствующие поля в наборе данных.
TmdatasetProxy - это базовый класс класса прокси -сервера набора данных. Наиболее важной частью является создание списка недвижимости в AfterConsulcure.
Работа атрибутов реализует только четыре типа данных: целое число, двойное/плавание, строка и вариант. При необходимости вы можете получить свой собственный базовый класс прокси на этой основе для реализации других типов данных. Реализация его замены. Однако для типов, которые не очень часто используются, рекомендуется определить фактический класс прокси перед его реализацией. Например, в предыдущем примере, предполагая, что tdateTime не является широко используемым типом, вы можете сделать это:
TDSpemployee = Class (TmdatasetProxy) GetDateTime (Const Index: Integer): TdateTime; Читать getString write setString; (GetVariant (index)); end; Процедура tdspemployee.setDateTime (const index: integer; const value: tdateTime);
Таким образом, вы можете напрямую использовать дату рождения в качестве типа tdateTime.
Кроме того, используя это преимущество, можно предоставить унифицированные операции для некоторых специальных типов данных.
Кроме того, BearDit был вызван перед всеми SetXXX, чтобы избежать ошибок времени выполнения, вызванных забыванием использовать DataSet.edit.
Foreach реализуется для повторного использования. Кроме того, EndEdit вызывается практически для автоматического отправки изменений.
Эта схема объективации набора данных является очень простым решением. Это связано с тем, что Delphi по -прежнему является нативным языком развития. Нет динамики, поэтому вы можете использовать только текущий метод для регистрации.