DDD - 业务规则
http://www.infoq.com/cn/articles/ddd-in-practice
1. Business rules are an important part of the business domain. They define data validation and other constraints that need to be applied on domain objects in specific business process scenarios. Business rules typically fall into the following categories:
- Data validation
- Data transformation
- Business decision-making
- Process routing (work-flow logic)
2. The context is very important in DDD world. Context specificity dictates(规定,命令,影响) the domain object collaboration as well as other run-time factors like what business rules to apply etc. Validation and other business rules are always processed in a specific business context. This means the same domain object, in a different business context, will have to process different set of business rules. For example, some attributes of a loan domain object (such as loan amount and interest rate) cannot be changed after the loan has been through the Underwriting step in the loan approval process. But the same attributes can be changed when the loan is just registered and locked for a specific interest rate.
注释:可知,在不同业务上下文,会处理不同的业务规则。
3. Even though all the domain specific business rules should be encapsulated in the domain layer, some application designs put the rules in facade classes, which leads to domain classes becoming "anemic(贫血的)" in terms of(在...方面) business rules logic. This may be an acceptable solution in small size applications, but it is not recommended for mid-size to large enterprise applications that contain complex business rules. A better design option is to put the rules where they belong, inside the domain objects. If a business rule logic spans(跨越) two or more Entity objects, then it should become part of a Service class.
注释:可知,业务逻辑应该放到相应的领域对象里,如果这个业务逻辑涉及多个实体,那就放到服务里。
4. Also, if we are not diligent in the application, design business rules will end up being coded in the form of several switch statements in the code. And over time as the rules get more complex, developers don't take time to refactor the code to move "switch" statements into a more manageable design. Hardcoding the complex routing or decision-making rules logic in the classes leads to longer methods in the classes, code duplication, and ultimately a rigid (死板的)application design which will become a maintenance nightmare in the long run. A good design is to place all the rules (especially complex rules that change frequently as the business strategy changes) into a Rules engine (using a rules framework like JBoss Rules, OpenRules, or Mandarax) and invoke them from the domain classes.
注释:可知,就是把所有的业务逻辑放到一个业务引擎里,然后通过领域类来调用。 "3"里不是说这样会造成业务逻辑的贫血吗?
5. Validation rules are usually implemented in different languages like Javascript, XML, Java code, and other scripting languages. But due to the dynamic nature of business rules, scripting languages such as Ruby, Groovy, or Domain Specific Languages (DSL) are a better choice to define and manage these rules. Struts (Application layer), Spring (Service) and Hibernate (ORM) all have their own validation modules where we can apply the validation rules on the incoming or outgoing data objects. In some cases, validation rules can also be managed as Aspects (link AOP rules article here) that can be weaved into different layers (e.g. Service and Controller) of the application.
注释: 验证规则一般用脚本来写和管理,也可以通过AOP来管理。 例子呢?
6. It's important to keep in mind the unit testing aspect when writing the domain classes to manage business rules. Any changes in the rules logic should be easily unit testable in isolation.
注释:时刻记得业务逻辑的可测试性。
7. The sample application includes a business rule set to validate the loan parameters are within the allowed product and rate specifications. The rules are defined in a scripting language (Groovy) and are applied on the loan data passed to FundingService object
Design:
1. From a design stand-point, the domain layer should have a well defined boundary to avoid the corruption of the layer from non-core domain layer concerns such as vendor-specific(特定供应商的) translations, data filtering, transformations, etc. Domain elements should be designed to hold the domain state and behavior correctly. Different domain elements are structured differently based on state and behavior. Table 2 below shows the domain elements and what they contain.
Domain Element | State/Behavior |
---|---|
Entity, Value Object, Aggregate | State and Behavior |
Data Transfer Object | State only |
Service, Repository |
Behavior only |
注释:领域层需要定义一个号的边界,这样可以避免领域被其它非核心的领域所污染。另外领域元素主要是基于 “状态” 和 “行为”。
2. Entities, Value Objects, and Aggregates which contain both state (data) and behavior (operations), should have clearly defined state and behavior. At the same time, this behavior should not extend beyond the limits of the object's boundaries. Entities should do most of the work in the use case acting on their local state. But they shouldn't know about too many unrelated concepts.
Sample Application:
1. The sample application used in this article is a home loan processing system and the business use case is to approve the funding request of a home loan (mortgage(抵押)). When a loan application is submitted to a mortgage lending company, it first goes through the Underwriting process where the underwriters(保险公司,担保人, 承诺支付者) approve or deny the loan request based on customer's income details, credit history and other factors. If the loan application is approved by underwriting(n 保险业 vt. 认购) group, it goes through Closing and Funding steps in the loan approval process.
注释:当用户提出借贷时,由担保人进行审核,当通过后才进行 关闭和出钱的流程。 Underwriting
2. Funding module in the loan processing system automates the process of disbursement(支付) of funds to the borrower(借款人). The funding process typically starts with mortgage lender (typically a bank) forwarding the loan package to a title company(产权公司). The title company then reviews the loan package and schedules a date with seller and buyer of the property for closing the loan. Borrower(买方) and the seller(卖方) meet with the closing agent at the title company to sign the paperwork to transfer the title of the property.
注释:贷方将钱交给产权公司,然后该公司与买卖双方商定一个还贷时间。
Entity:
.Loan
.Borrower
.UnderwritingDecision
.FundingRequest
Value:
.ProudctRate
.State
Services:
.FundingService
Repsoitory:
.LoanRepository
.BorrowerRepository
.FundingRepository
注释:对于实体,我们在分析的时候,往往关注的是看得见,摸得着的东西 比如(Borrower 和 Loan), 但是对于FundingRequest 和 UnderwringDecision 总是会忽略。如果以一个定会议的系统来作为demo的话,它的实体应该有(Room, Meeting Hoster, meeting, Request)