领域驱动设计: Community discussion and Personal understanding

Service

Service历来是争论的焦点. 批评者认为Service的存在表明了职责的不清晰, 认为Service里的代码是没放对位置的代码, 都应该放到相关的Domain对象如Entity中. 总而言之Service不够OO. Service是Transaction Script. 事实上这未必是Service这个building block的问题, 而是传统的面向对象编程范式的问题. OO长于表达行为, 但局限于单个对象. OO在捕捉对象间的交互方面, 并没什么有力的指导原则. 比如, 当在储蓄账户和信用账户之间转帐的时候, 我是在储蓄账户上定义转出呢, 还是在信用账户上定义转入?

有人认识到了OO的这种缺陷, 试图将交互作为系统概念的一等公民, 与数据等并列, 比如DCI(DataContextInteraction)这种新的范式. 我觉得可以把DDD里的Domain Service作为DCI中Interaction的实现方式.

既然是交互, 命名上就应该是动词. 比如应该是TransferService, 而不是AccountService. 这样更具体的命名可以避免Service通常带来的另外一个问题: 因为名字太过General, 导致越来越多但凡沾点边乱七八糟的代码都往里放, Service成了垃圾箱.

简单一点就是:Action/Interaction 未必是某个class的method,也可以(并且更多情况下是更好的选择)是一个单独的class只带一个execute方法. 这不只是简单的代码级别的不同,而是业务概念的显式表达和隐式表达的区别, 尤其是当这个action涉及多个业务对象的时候, 放在哪个class里也不合适. DCI也是这么看的.

 

Application Logic vs. Business Logic

应用逻辑与业务逻辑. 业务逻辑是当你不用软件而完全手工人工来完成业务时依然存在的逻辑. 应用逻辑是当你用IT系统来优化你的业务时额外引入特定于你当前软件实现的逻辑. 保持这两部分的分离有助于保持核心业务逻辑模型和代码的稳定性. See<<领域驱动设计: More Practice>> for more details

 

Value Object

通常是Immutable的.这样你就不用考虑是Copy还是Refer, 是存个Snapshot还是保证Up-to-date. 你只能换掉它而不是改变它. Value Object 不是 DTO, 它们是完全不同的概念服务于完全不同的目的, 只是凑巧有时实现看起来相同:

In general I'm not fond of DTOs since they provide no additional meaning over pure data structures. In most cases I prefer keeping DTOs outside the domain. -- from ddd google group.

 

DoD (Duplication over Dependency), RoR (Replication over Reuse)

这里说的是Bounded Context. 在同一个Context内部, 我们不会容忍重复. 但不同Context之间, 有时重复是解依赖的手段. 更根本的原则是, 当重复出现的时候, 我们需要搞清楚它们概念上是否就是一回事, 还是两个不同概念只是偶然实现在目前相同.

这里还有很多没想清楚的.

 

Entity + Repository = Active Record

如果把Entity和它的Repository放在一个类里实现就跟Active Record看起来类似了. Repository负责集合操作

 

Query over physical collection

用查询来实现集合, 可以lazy load, 可以解决循环引用. 这个其实跟DDD无关, 只是应用ORM框架时对performance问题的solution.

 

Layered Architecture

这里不是说UI/Domain/DataAccess, 单就模型本身也可能分层. 模型反映解决问题的思路, 但对问题直观的理解和解决往往随着细节的深入而出现各种变化, 对此, 模型可以有不同层次. 高层的模型表达高层的解决方案, 很可能寥寥几个接口和概念就足够; 底下的层次则对应反映深入的问题

 

From DDD google group discussion:

Context

As a point to start to discover the contexts I often look to the organization chart of the company to see which kind of roles/point of view they have. The areas that you identified could be contexts.

Aggregates

Aggregates can be used as a technical tool or a modeling one.

  • As atechnical toolit cope with limits of OR/M and the so in persisting and retrieving objects efficiently.
  • As amodeling toolit cope with entities thatcontainsother entities in the modelled domains (that are quite rare, if you consider that an entity is something that is identifiable by domain expert). the state of aggregated objects can be changed (or observed) only through the aggregated root object.

Aggregates are about controlling consistency and invariants, not about restricting the use of types.

 

Technical vs. Non-technical

  • Parts of DDD that are non-technical, which in my opinion are the most important
  • Howerer, the most expensive errors I have experienced are not related to technical details get wrong (we have very high skilled devs and archs), but in non technical decision taken toohurriedly. These "conceptual aspects" of DDD are the more risky ones.
  • ...(ddd) but it is little related to technique, but learning and understanding, exercise and practise: improved communication through the ubiquitous language,reduced complexity and added flexibility

 

Transaction Script vs. Domain Modeling

By using DDD we are turning the focus away from technical concerns and instead focus our effort to the business domain.I think TransactionScript have their proper place and use, but implementing them in a way mixing business logic with technical concerns is never right. Hence "undisciplined".


In this project I've heard people complain about different things they think is complex. Those people being unfamilliar with DDD but having a long history of working on the system thinks the TS code with mixed concerns and very few abstractions is fine since they see exactly what is going on and they "know" what the context is and how everything works on a detailed level. And they think the DDD approach of separating things into different layers and building abstractions for business concepts just adds complexity. Then we have the newcommers, that don't have any prior DDD-experience either, that struggle with understanding of the domain. Even though DDD is new to them they pretty quickly pick up on the concepts and think it is a great help in understanding the domain. To them it is the TS code that is most complex since it doesn't make any difference between lines of business logic and those of database interaction

 

Utility API for specific usage scenario

The model is the core of the application, not the application itself. If you try to model a domain with an api that mimic the applicative context that will use the model, you poison the domain itself. Actually this was another thing that we learnt the hard way: at first, modelers did add methods (or even extension methods) to entities with the desire to help the application developers. But such helpers, turned to be a source of confusion, unnecessary dependencies and rigidity. Thus the signature you suggested could be useful for some clients of a service using the domain, but such async service api would work like an adapter, a façade to the model itself.

 

 

你可能感兴趣的:(unity)