Смотрел сервис микро-времени и дизайн домена управляемой DDD, следующий, чтобы найти примеры упражнений.
Каталог Читать
Каталог Читать
DDD Domain-Driven Design Study 1
Введение: есть почти половина месяца не написать что - нибудь, и чувствовал себя очень жалко себя , как это. Сегодня видел сообщение в блоге , который писал: Чем больше тем больше занятых людей есть время , чтобы написать блог. О, это , кажется , немного правда, блогеры для того , чтобы доказать себе занятых людей, он не должен узнать такую вещь на следующий DDD высоких звуков. Введенный перед знаний по MEF и АОП, последний намерен поделиться Automapper, режим хранения, WCF и другие вещи, но каждый раз , когда руки готовы написать что - то, писать демо был поставлен в тупик, например, режим хранения, через своих друзей , вы должны знать , что если ваш проект не в соответствии с DDD проектирования архитектуры и внедрения хранилища, он будет делать это очень «слабый», с плохой будет очень болезненным, прежде чем читать этот блог большой сад крупного рогатого скота , которые вы виктимизации, Entity Framework никогда не нужно писать Repository дизайн шаблонов друзей статьи следует помнить не только автор статьи, много друзей в комментариях внутри парка также отметил , используя его в плохом настроении. Блоггеры проекта также столкнулись с подобными проблемами, несмотря на введение режима хранения, но отсутствие хорошей архитектуры, интерфейс и реализации хранения на едином уровне доступа к данным, что приводит позже написать код более трудно поддерживать полное ощущение складирование принесли мало пользы. Так блоггеры думают просто способ хранения доли очень легко для читателя , чтобы неправильно понять «режим в режим», вместе с недавно глядя на «Domain Driven Design: сложность программного обеспечения дорожного .Eric.Eva ядро контрмер» Эта книга и серии Daniel dax.net Park DDD блога, так что я планирую поделиться демо - режиме , чтобы проиллюстрировать складирование, Automapper, WCF и другие точки знаний.
Во-первых, основная концепция дизайна домена управляемой
В соответствии с «Домен-Driven Design: Дорога .Eric.Eva сложность программного ядра, чтобы иметь дело с» видом книги, модель предметной области является ядром общего языка программных проектов, является универсальным языком правил экспертов и разработчиков домена соблюдать, то DDD в важности моделирования Излишне говорить, так что для того, чтобы лучше понять домен управляемого проектирует, строит понимание и раздел модель предметной области становится совершенно необходимой. DDD Первый взгляд внутри некоторых из наиболее важных понятий:
1, модель домена: различные области модели к модели данных, которые выражают соотношение между полем и каждым классом . С точки зрения области управляемой точки зрения дизайна, база данных является лишь механизмом для хранения внешней сущности, это то , что принадлежит к техническому уровню. Модель данных в основном используются для постоянной модели режима поля описания объекта, должна быть первой модель домена, только модель данных, потребности в модели предметной области , возникающие из соответствующей модели данных через какое - то отображение, с этой точкой, последней из EF Code First является хорошим выражением. Модель домена объектов в субъект, объекты стоимости и услуги.
2, компания: в которой дизайн поле с приводом, предприятие является необходимость различать отдельные объекты модели. Здесь сущность и EntityFramework внутри объект не является концепция, EF объект для данных сущности, не включают в себя поведение объекта. Поняли блоггеры, DDD понятие, сущность представляет собой данные сущности , включающая комбинацию (модель EF) , и поведение .
3, значение объекта: объект идентифицируется значением атрибута объекта, который представляет собой комбинацию из множества атрибутов, относящихся к общей концепции. Сравниваемые объекты, ценностные объекты только один меньше, чем физическая идентичность. Сравнить расчетное значение объекта спора, Давайте вспомним, что величина разности между объектами и субъектами: (1) организация имеет уникальный идентификатор, а значение объекта не; (2) предприятие может меняться, но не допускает изменения в стоимости объекта; (3) судьи два объекта равны равно идентификация лиц определяется, и определенное значение объекта равно две внутренние стандартные значения равны для всех значений атрибутов объекта;
4、聚合(以及聚合根):聚合表示一组领域对象(包括实体和值对象),用来表述一个完整的领域概念。而每个聚合都有一个根实体,这个根实体又叫做聚合根。举个简单的例子,一个电脑包含硬盘、CPU、内存条等,这一个组合就是一个聚合,而电脑就是这个组合的聚合根。博主觉得关于聚合的划分学问还是挺大的,需要在实践中慢慢积累。同一个实体,在不同的聚合中,它可能是聚合根,也可能不是,需要根据实际的业务决定。聚合根是聚合所表述的领域概念的主体,外部对象需要访问聚合内的实体时,只能通过聚合根进行访问,而不能直接访问。
5、领域服务:博主的理解,领域模型主张富领域模式,也就是说把领域逻辑尽量写在领域实体里面,也就是常说的“充血模式”,而对于业务逻辑,最好是以服务的形式提供。至于领域逻辑和业务逻辑的界定,这个要根据实际情况来定。总之,领域服务是用来处理那些领域模型里面不好定义或者某些可变逻辑的的时候才会用到。待验证!
6、工厂、仓储等概念留在Demo里面说明。
二、领域驱动设计开始之旅
1、项目分层
领域驱动设计将软件系统分为四层:基础结构层、领域层、应用层和表现层。来看看书中的分层:
其实在dax.net的系列中这张图更能说明这种架构
2、项目架构
博主打算用权限系统的案例说明的领域驱动设计的项目架构。项目严格按照表现层、应用层、领域层、基础设施层来划分。
表现层:MVC的Web项目,负责UI呈现。
应用层:WCF服务,负责协调领域层的调用,向UI层提供需要的接口。
领域层:定义领域实体和领域逻辑。
基础设施层:一些通用的技术,比如AOP、MEF注入、通用的工具类、DTO模型层,这里为什么要有一个DTO模型层,DTO是用于UI展现用的纯数据Model,它不包含实体行为,是一种贫血的模型。
整个项目的调用方式严格按照DDD设计来进行,UI层通过WCF服务调用应用层的WCF接口,WCF服务通过仓储调用领域层里面的接口,基础设施层贯穿其他各层,在需要的项目中都可以引用基础设施层里面的内库。
3、代码示例
接下来,博主就根据自己的理解,从零开始使用这种架构写一个简单的权限管理系统。由于是领域驱动设计,所以,文章的重点会放在领域层,项目使用了EF的Model First来进行,先设计实体,后生成数据库。
3.1 首先来看看表结构
首先建好对应的表实体,然后根据模型生成数据库
将生成的sql语句执行后就可以得到对应的表结构。
3.2 聚合的划分
在领域层里面我们新建一个BaseModel,里面有三个类
这三个类IEntity、IAggregateRoot、AggregateRoot分别定义了实体的接口、聚合根的接口、聚合根的抽象实现类。
//用作泛型约束,表示继承自该接口的为领域实体 public interface IEntity { }
/// <summary> /// 聚合根接口,用作泛型约束,约束领域实体为聚合根,表示实现了该接口的为聚合根实例,由于聚合根也是领域实体的一种,所以也要实现IEntity接口 /// </summary> public interface IAggregateRoot:IEntity { }
/// <summary> /// 聚合根的抽象实现类,定义聚合根的公共属性和行为 /// </summary> public abstract class AggregateRoot:IAggregateRoot { }
这里定义接口的作用是定义实体和聚合根的泛型约束,抽象类用来定义聚合根的公共行为,目前为止,这些接口和类里面都是空的,后面会根据项目的需求一步一步往里面加入逻辑。
在EF里面由edmx文件会生成实体的属性,前面说到领域模型主张充血模式,所以要在EF的实体model里面加入实体的行为,为了不改变EF生成实体的代码,我们使用partial类来定义实体的行为。我们来看Model文件夹下面的代码
public partial class TB_DEPARTMENT: AggregateRoot { public override string ToString() { return base.ToString(); } }
public partial class TB_MENU : AggregateRoot { }
/// <summary> /// 由于不会直接操作此表,所以TB_MENUROLE实体不必作为聚合根,只是作为领域实体即可 /// </summary> public partial class TB_MENUROLE:IEntity { }
public partial class TB_ROLE:AggregateRoot { }
public partial class TB_USERROLE:IEntity { }
public partial class TB_USERS:AggregateRoot { }
我们看到,这些实体,只有TB_MENUROLE和TB_USERROLE不是聚合根,其他实体都是聚合根。我这里大概划分为4个聚合:
聚合1:TB_DEPARTMENT实体
聚合2:TB_MENU实体
聚合3:TB_USERS、TB_USERROLE、TB_DEPARTMENT、TB_ROLE这4个为一个聚合,聚合根是TB_USERS。
聚合4:TB_ROLE、TB_USERS、TB_USERROLE、TB_MENUROLE、TB_MENU这5个表为一个聚合,聚合根是TB_ROLE。
可能这样分会有一定的问题,后续出现再慢慢纠正。
到这里,聚合的划分基本完了。