Применение модели предметной области поверх сущностей Linq2Sql - PullRequest
1 голос
/ 29 апреля 2010

Я пытаюсь отработать первый подход к модели и собираю модель предметной области. Мое требование довольно простое: UserSession может иметь несколько ShoppingCartItems.

Я должен начать с того, что я собираюсь применить интерфейсы модели предметной области к сгенерированным сущностям Linq2Sql (используя частичные классы). Мое требование переводится в три таблицы базы данных (UserSession, Product, ShoppingCartItem, где ProductId и UserSessionId - внешние ключи в таблице ShoppingCartItem). Linq2Sql генерирует эти объекты для меня. Я знаю, что на данном этапе я даже не должен иметь дело с базой данных, но думаю, что важно упомянуть.

Совокупным корнем является UserSession, так как ShoppingCartItem не может существовать без UserSession, но в остальном я неясен. Как насчет продукта? Это определенно сущность, но должна ли она быть связана с ShoppingCartItem?

Вот несколько предложений (все они могут быть неправильными реализациями):

public interface IUserSession {
    public Guid Id { get; set; }
    public IList<IShoppingCartItem> ShoppingCartItems{ get; set; }
}

public interface IShoppingCartItem {
    public Guid UserSessionId { get; set; }
    public int ProductId { get; set; }        
}

Еще один будет:

public interface IUserSession {
    public Guid Id { get; set; }
    public IList<IShoppingCartItem> ShoppingCartItems{ get; set; }
}

public interface IShoppingCartItem {
    public Guid UserSessionId { get; set; }
    public IProduct Product { get; set; }         
}

Третий:

public interface IUserSession {
    public Guid Id { get; set; }
    public IList<IShoppingCartItemColletion> ShoppingCartItems{ get; set; }
}

public interface IShoppingCartItemColletion {
    public IUserSession UserSession { get; set; }
    public IProduct Product { get; set; }      
}

public interface IProduct {
    public int ProductId { get; set; }      
}

У меня такое ощущение, что мой разум слишком тесно связан с моделями баз данных и таблицами, что затрудняет понимание этого. Кто-нибудь хочет отделить?

Ответы [ 2 ]

2 голосов
/ 29 апреля 2010

Похоже, вы на правильном пути. Половина "правильного DDD" имеет правильные базовые классы. Взгляните на этот замечательный DDD, примененный к ресурсу C #:

http://dddpds.codeplex.com/

Исходный код доступен и очень читабелен.

Итак, что касается наличия идентификатора в модели. Идентификатор - это элемент базы данных, и обычный подход заключается в том, чтобы исключить всю постоянство модели и ограничить модель бизнес-логикой. Однако обычно для идентификатора делают исключение и скрывают его в базовом классе Model следующим образом:

public class ModelBase {
  protected readonly object m_Key;
  public ModelBase(object key) {
    m_Key = key;
  }
}

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

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

public Class UserSession : ModelBase {
  public UserSession(Guid Id):base(Id) {}

  public Guid Id { get{ return m_Key as Guid;} }
  public IList<ShoppingCartItem> ShoppingCartItems{ get; set; }
}

public class ShoppingCartItem : ModelBase {
  public ShoppingCartItem ():base(null) {}

  public UserSession UserSession { get; set; }
  public Product Product { get; set; }         
}
1 голос
/ 30 апреля 2010

Типичная корзина покупок или примеры заказов клиентов предпочитают делать UserSession (или Order) корнем совокупности. Отдельные предметы должны быть детьми этого сеанса / заказа. Вам решать, должны ли отдельные элементы в корзине иметь значимый идентификатор. Я бы предпочел нет, так как 5 виджетов в корзине неотличимы от других 5 виджетов. Следовательно, я бы смоделировал элементы корзины как набор объектов стоимости.

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

Продукт должен окончательно сформировать совокупность сам по себе. Период.

Теперь я не знаю, легко ли все это реализовать в LINQ to SQL, но вы можете попробовать.

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