SlideShare ist ein Scribd-Unternehmen logo
1 von 29
www.keremet.com




      Паттерны проектирования
      источников данных
      Источник: работы Мартина Фаулера




                                           докладчик
                                   Тренкеншу Виталий
www.keremet.com




        •    Table Data Gateway
        •    Row Data Gateway
        •    Active Record
        •    Data Mapper
www.keremet.com




Table Data Gateway


            Шлюз таблицы данных
            Содержит в себе все команды SQL,
            необходимые для извлечения, вставки,
            обновления и удаления данных из таблицы
www.keremet.com
                              Table Data Gateway




Методы Шлюза таблицы данных используются
другими компонентами для взаимодействия с БД
www.keremet.com
                          Table Data Gateway




                  Обычно

Для каждой таблицы БД создается
собственный шлюз таблицы данных

Шлюз не имеет состояний, всего лишь
передает данные в таблицу и из неѐ
www.keremet.com
                               Table Data Gateway




                  Хорошо сочетается

с типовым решением Модуль таблицы
(Table Module)

с паттерном Сценарий транзакции
(Transaction Script)

                       Типовые решения для представления бизнес-логики
www.keremet.com
                         Table Data Gateway




                    Примеры


ProfileDataManager.cs

Хранимые процедуры
www.keremet.com




Row Data Gateway


            Шлюз записи данных
            Каждой строке таблицы базы данных
            соответствует свой
            экземпляр шлюза записи данных
www.keremet.com
                                                  Row Data Gateway


Шлюз выступает в роли
интерфейса к строке
данных


прекрасно подходит для
применения в
сценариях транзакции
(Transaction Script)

Типовое решение для представления бизнес-логики
www.keremet.com
                            Row Data Gateway




                   Пример

  create table people (
       ID int primary key,
       lastname varchar,
       firstname varchar,
       number_of_dependents int)
class PersonGateway...

private String lastName;
private String firstName;
private int numberOfDependents;

public String getLastName() { return lastName; }
public void setLastName(String lastName)
{ this.lastName = lastName; }

public String getFirstName() { return firstName; }
public void setFirstName(String firstName)
{ this.firstName = firstName; }

public int getNumberOfDependents()
{ return numberOfDependents; }
public void setNumberOfDependents(int numberOfDependents)
{ this.numberOfDependents = numberOfDependents; }
class PersonGateway...

private static final String updateStatementString = "UPDATE
people " + " set lastname = ?, firstname = ?,
number_of_dependents = ? " + " where id = ?";

public void update() {
  PreparedStatement updateStatement = null;
  try
  {
    updateStatement = DB.prepare(updateStatementString);
    updateStatement.setString(1, lastName);
    updateStatement.setString(2, firstName);
    updateStatement.setInt(3, numberOfDependents);
    updateStatement.setInt(4, getID().intValue());
    updateStatement.execute();
  } catch (Exception e) { throw new ApplicationException(e);
}
  finally {DB.cleanUp(updateStatement); }
}
private static final String insertStatementString =
         "INSERT INTO people VALUES (?, ?, ?, ?)";

  public Long insert() {
     PreparedStatement insertStatement = null;
     try {
        insertStatement = DB.prepare(insertStatementString);
        setID(findNextDatabaseId());
        insertStatement.setInt(1, getID().intValue());
        insertStatement.setString(2, lastName);
        insertStatement.setString(3, firstName);
        insertStatement.setInt(4, numberOfDependents);
        insertStatement.execute();
        Registry.addPerson(this);
        return getID();
     } catch (SQLException e) {
        throw new ApplicationException(e);
     } finally {DB.cleanUp(insertStatement);
     }
  }
class PersonFinder...

  private final static String findStatementString =
        "SELECT id, lastname, firstname, number_of_dependents " +
        " from people " +
        " WHERE id = ?";

  public PersonGateway find(Long id) {
     PersonGateway result = (PersonGateway) Registry.getPerson(id);
     if (result != null) return result;
     PreparedStatement findStatement = null;
     ResultSet rs = null;
     try {
        findStatement = DB.prepare(findStatementString);
        findStatement.setLong(1, id.longValue());
        rs = findStatement.executeQuery();
        rs.next();
        result = PersonGateway.load(rs);
        return result;
     } catch (SQLException e) {
        throw new ApplicationException(e);
     } finally {DB.cleanUp(findStatement, rs);
     }
  }

  public PersonGateway find(long id) {
     return find(new Long(id));
  }
В сценарии транзакции
PersonFinder finder = new PersonFinder();

Iterator people = finder.findResponsibles().iterator();

StringBuffer result = new StringBuffer();

while (people.hasNext()) {
   PersonGateway each = (PersonGateway) people.next();
   result.append(each.getLastName());
   result.append(" ");
   result.append(each.getFirstName());
   result.append(" ");
   result.append(String.valueOf(each.getNumberOfDependents()));
   result.append(" ");

}

return result.toString();
www.keremet.com




Active Record


            Активная запись
            Объект, выполняющий роль оболочки
            для строки таблицы.
            Он инкапсулирует доступ к базе данных и
            добавляет к данным логику домена.
www.keremet.com
                                     Active Record




Структура Активной записи должна в
точности соответствовать записи в
таблице БД:

каждое поле должно соответствовать
одному столбцу таблицы
www.keremet.com
                                                             Active Record




                                    Обычно
Активная запись включает в себя методы:
  •   создание экземпляра активной записи на основе строки, полученной в
      результате выполнения SQL-запроса;
  •   создание и обновление записи в таблице из значений активной записи;
  •   статические методы поиска, выполняющие стандартные SQL-запросы и
      возвращающие активные записи;
  •   извлечение и установка значений полей (get- и set-методы);
  •   реализация некоторых фрагментов бизнес-логики.
www.keremet.com
                       Table Data Gateway




                  Пример


Person.java
www.keremet.com




Data Mapper


            Преобразователь данных
            Слой преобразователей (Mapper),
            который осуществляет передачу данных
            между объектами и базой данных,
            сохраняя последние независимыми друг от
            друга и от самого преобразователя
www.keremet.com
                                  Data Mapper




                    Проблема

Как Вы можете уменьшить взаимосвязь между
классами вашего приложения и базой данных?

Например, как вы можете уменьшить
переписывание кода, если одно или несколько
полей в таблице сменили название?
www.keremet.com
                               Data Mapper




                  Решение

В большинстве случаев преобразователь
данных применяется для того, чтобы
схема базы данных и объектная модель
могли изменяться независимо друг от
друга.
www.keremet.com
                                         Data Mapper




Изменение модели предметной области не требует
изменения структуры базы данных и наоборот.

Что крайне важно при наличии сложных отображений,
особенно при использовании уже существующих баз
данных
www.keremet.com
                                  Data Mapper




                   Применение

Ес­ли бизнес-логика довольно проста, ее,
скорее всего, можно реализовать и без
примене­ния модели предметной
области или преобразователя данных.
www.keremet.com
                                Data Mapper




                  Применение

В свою очередь, реализация более сложной
логики невозможна без использования
модели предметной области и, как
следствие этого, преобразователя данных.
www.keremet.com
                                 Data Mapper




                   Преимущество

Основным преимуществом
преобразователя данных является
возможность работы с моделью
предметной области без учета структуры
базы данных как в процессе проектирования,
так и во время сборки и тестирования
проекта.
www.keremet.com
                  Data Mapper




                  Пример
www.keremet.com
                                  Data Mapper




                  Отличия от Active Record
Кратко говоря, объекты в шаблоне Data
Mapper никак не связаны со схемой БД, в то
время как Active Record на этой связи
построена.

Вся работа с БД осуществляется через
дополнительный слой.
www.keremet.com




      Спасибо за внимание
      Вопросы?



                              докладчик
                      Тренкеншу Виталий

Weitere ähnliche Inhalte

Ähnlich wie Паттерны проектирования источников данных

Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
GoSharp
 
Java осень 2012 лекция 8
Java осень 2012 лекция 8Java осень 2012 лекция 8
Java осень 2012 лекция 8
Technopark
 
Java осень 2013 лекция 8
Java осень 2013 лекция 8Java осень 2013 лекция 8
Java осень 2013 лекция 8
Technopark
 
базы данных в Delphi
базы данных в Delphiбазы данных в Delphi
базы данных в Delphi
Aeka227
 
Entity framework
Entity frameworkEntity framework
Entity framework
Scaiper
 
лекции спрг 6_семестр (1)
лекции спрг 6_семестр (1)лекции спрг 6_семестр (1)
лекции спрг 6_семестр (1)
djbelyakk
 
High Load 2009 Dimaa Rus Ready 16 9
High Load 2009 Dimaa Rus Ready 16 9High Load 2009 Dimaa Rus Ready 16 9
High Load 2009 Dimaa Rus Ready 16 9
HighLoad2009
 

Ähnlich wie Паттерны проектирования источников данных (20)

Metadata + JavaScript = ♥ Применение метаданных ViewModel для конфигурировани...
Metadata + JavaScript = ♥ Применение метаданных ViewModel для конфигурировани...Metadata + JavaScript = ♥ Применение метаданных ViewModel для конфигурировани...
Metadata + JavaScript = ♥ Применение метаданных ViewModel для конфигурировани...
 
Расширение библиотеки Slick
Расширение библиотеки SlickРасширение библиотеки Slick
Расширение библиотеки Slick
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)
 
Витрины данных - загрузка данных, разработка процессов ETL
Витрины данных - загрузка данных, разработка процессов ETLВитрины данных - загрузка данных, разработка процессов ETL
Витрины данных - загрузка данных, разработка процессов ETL
 
Java осень 2012 лекция 8
Java осень 2012 лекция 8Java осень 2012 лекция 8
Java осень 2012 лекция 8
 
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
 
JDBC
JDBCJDBC
JDBC
 
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API: SyntaxTree vs CodeDom, SemanticModel vs ReflectionRoslyn API: SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
 
Работа с БД в Java
Работа с БД в JavaРабота с БД в Java
Работа с БД в Java
 
Java осень 2013 лекция 8
Java осень 2013 лекция 8Java осень 2013 лекция 8
Java осень 2013 лекция 8
 
базы данных в Delphi
базы данных в Delphiбазы данных в Delphi
базы данных в Delphi
 
Архитектура корпоративных систем
Архитектура корпоративных системАрхитектура корпоративных систем
Архитектура корпоративных систем
 
DBD lection 4. Big Data, NoSQL. In Russian.
DBD lection 4. Big Data, NoSQL. In Russian.DBD lection 4. Big Data, NoSQL. In Russian.
DBD lection 4. Big Data, NoSQL. In Russian.
 
Лекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, LoaderЛекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, Loader
 
Entity framework
Entity frameworkEntity framework
Entity framework
 
лекции спрг 6_семестр (1)
лекции спрг 6_семестр (1)лекции спрг 6_семестр (1)
лекции спрг 6_семестр (1)
 
High Load 2009 Dimaa Rus Ready 16 9
High Load 2009 Dimaa Rus Ready 16 9High Load 2009 Dimaa Rus Ready 16 9
High Load 2009 Dimaa Rus Ready 16 9
 
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложениеASP.NET MVC - как построить по-настоящему гибкое веб-приложение
ASP.NET MVC - как построить по-настоящему гибкое веб-приложение
 

Паттерны проектирования источников данных

  • 1. www.keremet.com Паттерны проектирования источников данных Источник: работы Мартина Фаулера докладчик Тренкеншу Виталий
  • 2. www.keremet.com • Table Data Gateway • Row Data Gateway • Active Record • Data Mapper
  • 3. www.keremet.com Table Data Gateway Шлюз таблицы данных Содержит в себе все команды SQL, необходимые для извлечения, вставки, обновления и удаления данных из таблицы
  • 4. www.keremet.com Table Data Gateway Методы Шлюза таблицы данных используются другими компонентами для взаимодействия с БД
  • 5. www.keremet.com Table Data Gateway Обычно Для каждой таблицы БД создается собственный шлюз таблицы данных Шлюз не имеет состояний, всего лишь передает данные в таблицу и из неѐ
  • 6. www.keremet.com Table Data Gateway Хорошо сочетается с типовым решением Модуль таблицы (Table Module) с паттерном Сценарий транзакции (Transaction Script) Типовые решения для представления бизнес-логики
  • 7. www.keremet.com Table Data Gateway Примеры ProfileDataManager.cs Хранимые процедуры
  • 8. www.keremet.com Row Data Gateway Шлюз записи данных Каждой строке таблицы базы данных соответствует свой экземпляр шлюза записи данных
  • 9. www.keremet.com Row Data Gateway Шлюз выступает в роли интерфейса к строке данных прекрасно подходит для применения в сценариях транзакции (Transaction Script) Типовое решение для представления бизнес-логики
  • 10. www.keremet.com Row Data Gateway Пример create table people ( ID int primary key, lastname varchar, firstname varchar, number_of_dependents int)
  • 11. class PersonGateway... private String lastName; private String firstName; private int numberOfDependents; public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public int getNumberOfDependents() { return numberOfDependents; } public void setNumberOfDependents(int numberOfDependents) { this.numberOfDependents = numberOfDependents; }
  • 12. class PersonGateway... private static final String updateStatementString = "UPDATE people " + " set lastname = ?, firstname = ?, number_of_dependents = ? " + " where id = ?"; public void update() { PreparedStatement updateStatement = null; try { updateStatement = DB.prepare(updateStatementString); updateStatement.setString(1, lastName); updateStatement.setString(2, firstName); updateStatement.setInt(3, numberOfDependents); updateStatement.setInt(4, getID().intValue()); updateStatement.execute(); } catch (Exception e) { throw new ApplicationException(e); } finally {DB.cleanUp(updateStatement); } }
  • 13. private static final String insertStatementString = "INSERT INTO people VALUES (?, ?, ?, ?)"; public Long insert() { PreparedStatement insertStatement = null; try { insertStatement = DB.prepare(insertStatementString); setID(findNextDatabaseId()); insertStatement.setInt(1, getID().intValue()); insertStatement.setString(2, lastName); insertStatement.setString(3, firstName); insertStatement.setInt(4, numberOfDependents); insertStatement.execute(); Registry.addPerson(this); return getID(); } catch (SQLException e) { throw new ApplicationException(e); } finally {DB.cleanUp(insertStatement); } }
  • 14. class PersonFinder... private final static String findStatementString = "SELECT id, lastname, firstname, number_of_dependents " + " from people " + " WHERE id = ?"; public PersonGateway find(Long id) { PersonGateway result = (PersonGateway) Registry.getPerson(id); if (result != null) return result; PreparedStatement findStatement = null; ResultSet rs = null; try { findStatement = DB.prepare(findStatementString); findStatement.setLong(1, id.longValue()); rs = findStatement.executeQuery(); rs.next(); result = PersonGateway.load(rs); return result; } catch (SQLException e) { throw new ApplicationException(e); } finally {DB.cleanUp(findStatement, rs); } } public PersonGateway find(long id) { return find(new Long(id)); }
  • 15. В сценарии транзакции PersonFinder finder = new PersonFinder(); Iterator people = finder.findResponsibles().iterator(); StringBuffer result = new StringBuffer(); while (people.hasNext()) { PersonGateway each = (PersonGateway) people.next(); result.append(each.getLastName()); result.append(" "); result.append(each.getFirstName()); result.append(" "); result.append(String.valueOf(each.getNumberOfDependents())); result.append(" "); } return result.toString();
  • 16. www.keremet.com Active Record Активная запись Объект, выполняющий роль оболочки для строки таблицы. Он инкапсулирует доступ к базе данных и добавляет к данным логику домена.
  • 17. www.keremet.com Active Record Структура Активной записи должна в точности соответствовать записи в таблице БД: каждое поле должно соответствовать одному столбцу таблицы
  • 18. www.keremet.com Active Record Обычно Активная запись включает в себя методы: • создание экземпляра активной записи на основе строки, полученной в результате выполнения SQL-запроса; • создание и обновление записи в таблице из значений активной записи; • статические методы поиска, выполняющие стандартные SQL-запросы и возвращающие активные записи; • извлечение и установка значений полей (get- и set-методы); • реализация некоторых фрагментов бизнес-логики.
  • 19. www.keremet.com Table Data Gateway Пример Person.java
  • 20. www.keremet.com Data Mapper Преобразователь данных Слой преобразователей (Mapper), который осуществляет передачу данных между объектами и базой данных, сохраняя последние независимыми друг от друга и от самого преобразователя
  • 21. www.keremet.com Data Mapper Проблема Как Вы можете уменьшить взаимосвязь между классами вашего приложения и базой данных? Например, как вы можете уменьшить переписывание кода, если одно или несколько полей в таблице сменили название?
  • 22. www.keremet.com Data Mapper Решение В большинстве случаев преобразователь данных применяется для того, чтобы схема базы данных и объектная модель могли изменяться независимо друг от друга.
  • 23. www.keremet.com Data Mapper Изменение модели предметной области не требует изменения структуры базы данных и наоборот. Что крайне важно при наличии сложных отображений, особенно при использовании уже существующих баз данных
  • 24. www.keremet.com Data Mapper Применение Ес­ли бизнес-логика довольно проста, ее, скорее всего, можно реализовать и без примене­ния модели предметной области или преобразователя данных.
  • 25. www.keremet.com Data Mapper Применение В свою очередь, реализация более сложной логики невозможна без использования модели предметной области и, как следствие этого, преобразователя данных.
  • 26. www.keremet.com Data Mapper Преимущество Основным преимуществом преобразователя данных является возможность работы с моделью предметной области без учета структуры базы данных как в процессе проектирования, так и во время сборки и тестирования проекта.
  • 27. www.keremet.com Data Mapper Пример
  • 28. www.keremet.com Data Mapper Отличия от Active Record Кратко говоря, объекты в шаблоне Data Mapper никак не связаны со схемой БД, в то время как Active Record на этой связи построена. Вся работа с БД осуществляется через дополнительный слой.
  • 29. www.keremet.com Спасибо за внимание Вопросы? докладчик Тренкеншу Виталий