Главная » Microsoft SQL Server, Базы данных » Объекты доступа к данным

0

Все примеры программного кода, приведенные в настоящей главе, были созданы на основе VB.NET 2005. Их можно найти на сайте книги.

В шаблоне доступа к данным DAO наследование и полиморфизм используются для построения иерархии объектов данных. Общая модель продемонстрирована на рис. 54.1.

Рис. 54.1. В этом примере модели DAO показано, как управляется отдельная реализация и как клиент может ссылаться на каждую из них

I       В объектно-ориентированной среде полиморфизмом называют способность

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

Модель DAO для обеспечения функциональности низлежащих классов полага- На заметку ется на технологии наследования. В этой модели всегда существуют базовые абстрактные классы, специфичные для объектов каждого типа данных, которые должен поддерживать разработчик. Специализированный класс создается для каждого объекта доступа к базе данных, который необходимо поддерживать, и содержит весь необходимый код SQL для своей базы данных. Обычно имя класса включает в себя имя базы данных, например AddressSQLDAO или AddressAccessDAO. Любой программный код, который обеспечивает использование этих объектов, должен изначально знать, какой тип DAO создавать.

Как работают сценарии DAO

Рассмотрим один из сценариев DAO. Основная задача заключаются в том, чтобы поддерживались базы данных Microsoft SQL Server 2005 и Microsoft Access. Определение типа объектов данных, который должен поддерживаться, основывается на внешнем флаге, содержащемся в файле конфигурации.

Базовый класс DAO Address, приведенный в следующем фрагменте программного кода, обеспечивает функциональность всех потомков, поддерживающих конкретную базу данных. Различные свойства членов будут общими. Единственным фактическим отличием является способ загрузки данных из источника.

Базовый класс DAO Address

Public Mustlnherit Class Address

1 Определены различные закрытые переменные-члены,

1 такие как City, State, Streetl, Street2, и их общие члены.

1,          1 В каждом классе-наследнике будет реализован метод Load 111 для уникального источника данных, к которому осуществляется доступ.

I I I_____________________________________

Public MustOverride Sub Load(ByVal strld As String)

End Class

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

AddressSQLDAO.vb

Public Class SqlAddressDAO Inherits Address ‘ Определение значения ключа файла конфигурации.

Private Const SQL_BINDING_INFO As String = "Sql_BindingInfo"

‘ Переменные класса унаследованы от базового класса Address.

I I I__________________________________________________

11 Замещение метода Load, определенного в классе Address.

I I I__________________________________________________

Public Overrides Sub Load(ByVal strld As String)

Dim cmd As SqlCommand = Nothing

Dim conn As SqlConnection = Nothing Dim dr As SqlDataReader = Nothing Try

‘ Определение подключения к базе данных.

conn = New SqlConnection(PropertyLoader.Instance _

.GetProperty(SQL_BINDING_INFO)) conn.Open()

‘ Настройка и выполнение команды SQL.

cmd = New SqlCommand(PropertyLoader.Instance . GetProperty ([2] Sql_Address_Select" ) . Replace ( " %1" , strld) , conn) dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)

If dr.Read Then 1 Загрузка переменных-членов чтения.

End If

Catch ex As Exception ‘ Пример обработки ошибок.

Throw (ex)

Finally 1 Закрытие переменных

If cmd IsNot Nothing Then cmd.Dispose()

If conn IsNot Nothing Then conn.Close()

If dr IsNot Nothing Then dr.Close()

End Try End Sub End Class

В версии VB.NET 2005 было введено ключевое слово IsNot, реализующее более понятную форму условных логических проверок. Функционально это ключевое слово идентично предыдущему синтаксису— Not <переменная> Is <значение>.

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

Практические советы относительно абстрагирования доступа к базе данных в программном коде см. в главе 25.

Когда переменные-члены определены в абстрактном родительском классе Address, класс AddressSQLDAO должен инициализировать только собственные переменные-члены. Класс AddressAccessDAO обеспечивает ту же функциональность, но содержит специфичный для программы Microsoft Access код подключения и инструкции SQL.

В примере, приведенном ниже, продемонстрирован клиентский программный код, использующий классы AddressSqlDAO и AddressAccessDAO для сбора информации из источников данных SQL Server и Access.

TestMain.vb

Public Class TestMain i i i____________________________

Sub Main()

Try

‘ Локальная переменная, хранящая ссылку на общий адрес.

Dim objAddr As Address 1 Получение данных из базы данных SQL Server и их отображение. objAddr = New SqlAddressDAO obj Addr.Load("2")

Call PrintAddress( objAddr )

1 Получение данных из базы данных Access и их отображение. objAddr = New AccessAddressDAO obj Addr.Load("1")

Call PrintAddress( objAddr )

Catch ex As Exception Console.WriteLine(ex.Message)

End Try End Sub

1 Вывод информации об адресе.

I I I______________________________________________

Private Sub PrintAddress( ByVal objAddr As Address )

Console.WriteLine(objAddr.Streetl)

Console.WriteLine(objAddr.City)

‘ Остальные атрибуты выводятся аналогичным образом.

End Sub End Class

Посмотрев на фактическое использование объектов DAO, становится совершенно очевидным, что доступ к данным SQL Server и Access реализован единообразно, поскольку управляется одним и тем же классом — Address. В то время как полиморфизм является гарантом доступа клиента к объектам данных SQL Server и Access, сохраняется необходимость знать, с каким конкретно источником данных ведется работа. Как было продемонстрировано в программном коде Test Main, соответствующие объекты данных создавались явным образом, и эта зависимость могла вызвать проблемы в случае подцержки другой базы данных или внесения изменений в существующую.

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

Достоинства модели DAO

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

Public Mustlnherit Class Address

I i i___________________________________________________________

1,                1 В этом классе реализуется та же функциональность,

1‘ что и в классе Address, описанном выше,

1 однако добавлен метод Getlnstance(),

”’ определяющий источник данных

I I I___________________________________________________________

Public Shared Function Getlnstance() As Address If PropertyLoader.Instance.GetProperty("UseSql"). _

Equals("True") Then

Return New AddressSqlDAO Else

Return New AddressAccessDAO End If

End Function

‘ Вся остальная функциональность описана выше.

End Class

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

Возникает вопрос, как изолировать клиента от решения этих вопросов. Модель фабрики позволяет вынести бизнес-логику Get Instance () в отдельный класс и скрыть различия баз данных от клиентского программного кода.

Фабрики

Примеры программного кода, описываемые в настоящем разделе, созданы на языке VB.NET 2005; их можно найти на сайте книги на странице f iles .htm.

Фабрика является централизованной точкой создания объектов. Когда клиентский программный код нуждается в объектах данных, он выполняет запрос к фабрике, которая реализует их создание и инициализацию. К тому же фабрика может содержать бизнес-логику, определяющую, какие именно типы объектов следует создать. В примере, показанном на рис. 54.2, эта логика определяет, какая база данных используется: SQL Server или Access.

Фабрики представляют собой довольно простую конструкцию, изолирующую На заметку процесс создания экземпляров класса от клиентского приложения. Фабрики могут также выступать в качестве промежуточного уровня доступа к другим фабрикам. На рис. 54.2 оба способа доступа к данным были реализованы с помощью первичной фабрики— DataObjectFactory. Именно в ней реализована бизнес-логика определения конкретной базы данных и передача запросов на создание объектов к соответствующей фабрике баз данных.

В данном случае модель фабрики помогла отделить бизнес-логику от объектов доступа к данным и предоставила клиентскому программному коду возможность формирования единого подхода к созданию новых объектов данных. Преимущество этого подхода заключается в том, что при изменении логики источника данных вся модификация выполняется в одном месте, а не в каждом базовом классе DAO. Это упрощает поддержку и приводит программный код в соответствие с общими принципами объектно-ориентированного проектирования.

Создание классов DAO в специфичных для конкретных баз данных фабриках и использование их в качестве подчиненных фабрик позволяет добиться большей инкапсуляции и единообразия. К тому же это упрощает добавление новых баз данных — создается подходящая новая подчиненная фабрика и вносятся необходимые изменения в главную фабрику.

Рис. 54.2. В этом примере фабрики продемонстрировано взаимодействие клиентов и зависимости фабрик

Представленный выше программный код, использующий класс Address, остается пригодным. Фабрика просто консолидирует ответственность за создание объектов данных в едином месте. Это продемонстрировано в следующем примере.

Главная фабрика

Public Class DataObjectFactory

Inherits Factory i i i_____________________________________

111 Делегирование запроса к объекту подчиненной фабрики.

I I I__________________________________________________

Public Shared Shadows Function GetDAO(ByVal typeRequested _

As Factory.SupportedDAOs) As Object Try

If CBool( PropertyLoader.Instance.GetProperty("UseSql") ) Then Return SqlServerFactory.GetDAO(typeRequested)

Else

Return AccessFactory .GetDAO (typeRequested)

End If Catch ex As Exception 1 Здесь обрабатывается ситуация, когда флаг или значение 1"UseSql" недоступны. Данное значение должно определяться 1 в файле конфигурации приложения.

Throw New ApplicationException( "Invalid UseSql value." )

End Try End Function End Class

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

Следующий фрагмент кода демонстрирует обработку этого делегирования фабрикой Sql Server Factory. Фактическая работа выполняется в приспособленной к конкретному источнику данных фабрике. Фабрика Access выполняет работу аналогичным образом.

Фабрика SqlServerFactory

Public Class SqlServerFactory Inherits Factory i i i__________________________________

1” Создание запрошенного объекта DAO.

I i i____________________________________________________________

Public Shared Shadows Function GetDAO(ByVal typeRequested _

As Factory.SupportedDAOs) As Object Select Case typeRequested

Case Factory.SupportedDAOs.Address Return New AddressSqlDAO Case Else

Return Nothing End Select End Function End Class

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

В VB.NET общие методы не могут замещаться в подчиненных классах. Для На заметку достижения нужного эффекта они должны объявляться с использованием клю- чевого слова Shadows.

Теперь займемся вопросом использования фабрик в программном коде клиентских приложений. Рассмотрим пример.

MainTester.vb

Public Class MainTester i i i______________________________________________

11 Главный метод запрашивает объект данных у фабрики.

1 1 1 Так как фабрика возвращает тип данных Objects,

1 1 ‘ тип возвращаемого значения должен быть соответствующим ”1 образом преобразован.

I 1 I___________________________________________________________

Sub Main()

Try

Dim objAddr As Address

objAddr = CType( SmarterDaoFactory.GetDAO( _

Factory.SupportedDAOs.Address), Address) objAddr.Load("1")

Call PrintAddress(objAddr)

Catch ex As Exception Console.WriteLine(ex.Message)

End Try End Sub

i i i____________________________________________________________

11 Вывод информации об адресе.

I I I___________________________________________________________

Private Sub PrintAddress( ByVal objAddr As Address )

Console.WriteLine(objAddr.Streetl)

Console.WriteLine(objAddr.City)

‘ Остальные атрибуты можно вывести тем же способом.

End Sub End Class

Обратите внимание на то, что создание специфичного для источника данных объекта в клиентском коде было опущено — вместо этого вызывался метод Factory. GetDAO (…). Этот метод содержит логику, определяющую, какая база данных должна использоваться, и направляющую запрос на создание объекта соответствующей подчиненной фабрике. Это существенный шаг в направлении изолирования клиента от тонкостей создания источника и объекта данных.

В следующем разделе мы обсудим все достоинства и недостатки использования фабрик. После этого будет показано, как сделать доступ к данным в клиентском программном коде полностью прозрачным.

Достоинства фабричной модели

Как уже говорилось ранее, одним из преимуществ использования фабрик является централизация бизнес-логики определения источника данных (класс SmarterDAOFactory). Главная фабрика обрабатывает запрос с помощью привязанных к конкретным источникам данных фабрик. Таким образом, фабрика SmarterDAOFactory выступает в роли посредника между клиентским кодом и специфичными для баз данных фабриками. Клиент, всегда работающий с одним и тем же источником данных, может направлять запрос к специфичным фабрикам напрямую, в обход главной фабрики. Дополнительные достоинства заключены в упрощении поддержки, облегченной концептуализации проекта, повышении удобочитаемости программного кода. К тому же разработчики еще на этапе проектирования знают, какие объекты поддерживаются, поскольку функция среды .NET IntelliSense отображает списки значений объектов фабрики. Более того, эта конструкция способна работать с большим числом объектов и баз данных, чем позволяет DAO.

Недостатки фабричной модели

Все недостатки, связанные с использованием фабричной модели, касаются реализации. Рассмотренный в настоящей главе пример очень прост, и использование подчиненных фабрик на самом деле не требовалось. В то же время на практике приходится иметь дело с большим количеством объектов и потенциальных источников данных, и использование подчиненных фабрик превращается в естественную потребность. В данном случае использование главной фабрики в качестве посредника требует дополнительной координации работы с подчиненными фабриками при добавлении новых баз и объектов данных. Все подчиненные фабрики должны программироваться таким образом, чтобы обслуживать запросы к неизвестным источникам данных. Еще одним недостатком является то, что главная фабрика должна предоставлять все множество доступных объектов; и это может вызвать проблемы, если подчиненные фабрики не поддерживают эти объекты.

Проект Factory в полном объеме можно найти на странице files.htm сайта книги. В него включен также и класс BasicDaoFactory. vb, требующий от клиента указания типа источника данных запрашиваемого объекта. Этот подход не рекомендуется использовать по той же причине, что и модель DAO. Он включен в проект только для наглядности.

Источник: Нильсен, Пол. Microsoft SQL Server 2005. Библия пользователя. : Пер. с англ. — М. : ООО “И.Д. Вильямс”, 2008. — 1232 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии