Шаблон загрузки субъекта бизнеса - PullRequest
0 голосов
/ 01 октября 2008

В проекте, над которым я работаю, используется многоуровневая архитектура. Наши слои следующие:

  • Доступ к данным
  • Бизнес-логика
  • Бизнес-структуры
  • Презентация

Business Logic вызывает вниз на уровень доступа к данным, а уровень Presentation вызывает вниз на уровень Business Logic, и все они ссылаются на бизнес-объекты.

Наши бизнес-объекты в основном соответствуют нашей модели данных 1-1. Для каждой таблицы у нас есть класс. Первоначально, когда была разработана структура, не учитывалось управление отношениями master-detail или child-parent. Таким образом, вся бизнес-логика, доступ к данным и бизнес-объекты ссылаются только на одну таблицу в базе данных. Как только мы начали разработку приложения, быстро стало очевидно, что отсутствие этих отношений в нашей объектной модели причиняет нам серьезный вред.

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

Вопрос в том, каков наилучший способ загрузки или отложенной загрузки отношений в наших объектах. Например, допустим, у нас есть класс person, имеющий отношение master-child к таблице адресов. Это проявляется в бизнес-объекте как свойство коллекции адресов в объекте Person. Если у нас есть отношение «один к одному», это будет отображаться как одно свойство объекта. Каков наилучший подход для заполнения и сохранения объектов отношений? Наши бизнес-объекты не знают уровня бизнес-логики, поэтому это невозможно сделать внутренне, когда свойство get вызывается.

Я уверен, что для этого есть какой-то стандартный шаблон. Есть предложения?

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

Ответы [ 3 ]

2 голосов
/ 01 октября 2008

Я настоятельно рекомендую взглянуть на книгу Фаулера Patterns of Enterprise Architecture . Есть несколько различных подходов к решению этой проблемы, которые он хорошо описывает, в том числе отношения сущностей.

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

Редактировать: Дополнительная информация

Этот является связью с базовой структурой класса Единицы работы ... на самом деле не самая захватывающая вещь в мире. Фаулер приводит более подробную информацию в своей книге, некоторые из которых вы можете увидеть здесь . Вы также можете посмотреть на объект Session из NHibernate как на возможную реализацию (я смог отследить интерфейс ISession ... не уверен, где находится реализация)

Надеюсь, это поможет.

1 голос
/ 01 октября 2008

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

public class Relation<T>
{
  private T _value;

  private void FetchData()
  {
    if( LoadData != null ) {
      LoadDataEventArgs args = new LoadDataEventArgs(typeof(T), /* magic to get correct object */);
      LoadData(this, args);
      _value = (T)args.Value;
    }
  }

  public event EventHandler<LoadDataEventArgs> LoadData;

  public T Value {
    get {
      if( _value == default(T) )
        FetchData();
      return _value; 
    }
    set { /* Do magic here. */ }
  }
}

Затем вы объявляете это для вашей сущности как:

[RelationCriteria("ID", EqualsMyProperty="AddressID")]
public Relation<Address> Address {
  get; set;
}

И загрузчик типа, который объявляет свойство Address, добавляет обработчик в событие LoadData.

Подобный класс реализует IList, чтобы дать вам отношение один ко многим.

0 голосов
/ 01 октября 2008

Какой язык вы используете? То, что вы описали, это именно то, что Entity Framework делает в .Net. Но вы не поделились тем языком, который использовали, и я предполагаю, что вы не хотите переписывать ни один из ваших слоев данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...