Дата публикации статьи: 12.05.2006 09:02

Инкапсуляция в мире баз данных

Автор: John Bailo
[Оригинал статьи] [Обсудить в форуме]
Перевод с английского: Виталий Готовцов
WWW: http://www.vitgot.narod.ru

Что такое инкапсуляция?

Одним из четырех свойств объектно-ориентированной парадигмы является инкапсуляция. В то время как наследование, абстрагирование и полиморфизм широко используются в объектно-ориентированном программировании (ООП), особенно в Visual Basic, можем ли мы сказать, что инкапсуляция используется в той же степени?
Поиск в библиотеке MSDN дал мне такое определение инкапсуляции (из статьи, озаглавленной «One Minute Terminologist»):

Инкапсулированные объекты – это такие объекты, которые содержат и код, и данные, что делает их легче для сопровождения, чем традиционные способы написания кода.

Статья MSDN Object Oriented Programming in Visual Basic.NET дает такое новое определение инкапсуляции (неправильное):

Инкапсуляция скрывает внутреннюю реализацию абстракции внутри отдельного объекта.

Я уверен, что первое определение правильное, и действительное, основа истинного ООП, однако текущая практика разработки редко использует инкапсулированные объекты, предпочитая гетерогенные структуры данных в традиционных реляционных серверных dbms-системах.

Инкапсулируем ли мы?

Одним из первых языков программирования, который я изучил, был ФОРТРАН (используя JCL на перфокартах), и пока мы не узнали о файле I/O, мы добавляли входящие данные с помощью команды DATA в конце программы. Я думаю, что вы можете сказать, что мои упакованные программы на ФОРТРАНе были инкапсулированы. Фактически они были более инкапсулированы, чем большинство сегодняшних объектно-ориентированных программ, которые редко, если вообще когда-нибудь, содержат данные. Моя деятельность в последние четыре года была далека от пакетного программирования. Как разработчик многозвенной системы, я работал над созданием веб-приложений и приложений для многозвенной клиент-серверной сети, которая включала использование объектов среднего слоя, компонентно-ориентированных клиентов в скриптах и компилированном коде, которые широко использовали внешние источники данных.
    Последнее вызывает во мне некоторый диссонанс. Вместо того, чтобы внедрять инкапсуляцию, прогресс последние несколько лет стремится объединить внешние объекты с традиционными реляционными базами данных и разными соединяющими программами (ODBC, JDBC и так далее). Эти объекты принимают форму COM+ объектов (первоначально MTS), которые, несомненно, помогают в определении бизнес-логики. Конечно, одной из сильных сторон Visual Basic является его удобочитаемость как языка программирования.
    Моделирование бизнес-логики или других систем на VB значительно более распространено, чем на других языках, таких как C/C++, или с использованием не-ОО скриптовых языков (таких как HTML). XML, очень удачные языки разметки данных, очевидно создают инкапсуляцию и внедряют идеи наследования – но они не имеют процедурного синтаксиса; и в связи с передачей информации между машинами вручную, не имеют большого распространения в построении данных любого рода.

Почему инкапсуляция данных?

Ок, вот мое мнение: инкапсуляция редко используется, если вообще используется, в Visual Basic многозвенных информационных системах. Следующий вопрос более позитивный. Почему ее нужно использовать? Давайте подумаем о примерах… представим так, будто мы создаем систему связи с покупателем, но мы хотим максимальной гибкости. Мы, в самом деле, хотим знать наших покупателей. Фактически, мы взваливаем на себя непосильную задачу (представьте себе универмаг «Нордстрем»), зная, что каждый покупатель обладает отдельными характеристиками. Ответ обычной реляционной базы данных может включать поле «Comments», которое дополнит имя, адрес – обычные поля. Следовательно, мы получим ответ, похожий на этот:

Name		City	State	Comments
John Bailo	Kent	WA	Likes color green

    Ладно, это не очень показательный пример, потому что его с трудом можно использовать в программном коде и он вызывает проблемы при выборе формулировок, индексировании и тому подобное. Вероятнее всего, поле «Comments» будет заполняться, но по нему никогда не будет осуществляться выборка. И сколько DBMS-инструментов будет предложено разработчиком базы данных, чтобы добавить «специальные поля» связывающие таблицу с покупателем. Пример. Верхняя таблица:

ID	Name		City	State
1	John Bailo	Kent	WA

Таблица дополнительных полей:

ID	Field	Value
200	Favorite Color	Green
200	Favorite Ice Cream	Vanilla

    По меньшей мере, каждому, кто найдет время посмотреть на таблицу дополнительных полей, придет в голову идея типов информации, которая относится к данному покупателю. Проблема здесь заключается в противопоставлении объектов, каждый раз, когда мы добавляем покупателю особое свойство, мы применяем это поле ко всем покупателям! Теперь мое предложение инкапсуляции.
    Предположим, что мы держим базу данных для того, что она умеет делать хорошо – моделирование, поиск и сортировка гомогенных структур данных. В их число входит то, что мы считаем общим – имена, адреса, города, адреса электронной почты. Однако базы данных зацикливаются на деталях. Я предлагаю в качестве примера компоненты VB.NET COM+, очень хорошее место для размещения деталей, – как свойства и методы отдельных классов, которые могут быть применены к отдельным лицам (в случае CRM).
«Смешанный» инкапсулированный и поддерживающий ADO класс в VB.NET, который может представлять пользователя, может выглядеть так:

Imports System
Imports Microsoft.VisualBasic

Public Class JohnBailo

    Sub getBasics()

        Dim connSql As SqlConnection
        Dim cmSql As SqlCommand

        Dim dremp As SqlDataReader
        connSql = New SqlConnection( _
            "server=webserver;uid=sa;pwd=;database=license")
        cmSql = New SqlCommand("s_getAllCustInfo", connSql)
        cmSql.commandtype = CommandType.StoredProcedure
        Try
            connSql.Open()
            dremp = cmSql.ExecuteReader()
            Do While dremp.Read()
                Console.WriteLine(dremp("ename").ToString())
            Loop
        Catch err As SqlException
            Console.WriteLine(err.ToString())
        Finally
            connSql.Close()
        End Try

    End Sub

    
    Public Function getFavoriteColor() As String
        Return favoriteColor = "blue"
    End Function


End Class

    Где getAllCustInfo получает всю информацию из пользовательской таблицы на SQL сервере. Самое красивое здесь то, что когда мы пишем клиентское приложение, мы видим или предоставляем getFavoriteColor. Это позволяет гетерогенным данным быть частью отдельного класса, который является частью COM+ компонента, который может быть вызван или преобразован с уникальным пользовательским ключом – но в то же время не от всех покупателей требуется приносить такие данные, если данные не релевантны для этого покупатели! Эта модель выглядит так:

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