training_ Refactoring from Anemic Domain Model Towards a Rich One (Decoupling the Domain Model from Data Contracts)

attribution for json

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 暴露的api =》model contract

=》无法对api中已暴露的 方法、模型 进行重构

=》 变成了基石,无法变更。紧密耦合

 

如何解耦?

Introduce Data transfer Objects(DTOs)

 

Domain model:

1. all domain logic & knowledge => competitive advantage => focus the most of your efforts

2. => fully encapsulated

3. => a good unit test coverage

4.=> refactor as often as needed => keep it up-to-date with the change in the requirements

5.=> a safe space: sure all data is consistent and no invariants are voilated

 

external world: 

1. a wild space where anything can happen  & know nothing about it

2. have no control over it.

 

communicate:

1. using mesages.

2. messages are guranteed to have a particular structure: data contract (translation : domain model vs data contracts)

3. translation: keep evolvimng domain model & preserve the data contract for backward compatibility

=>refactor domain model, only modify the mappings,but keep the contracts themselves unchanged

 

 

 

 

 

output data contracts = DTO: data transfer object 

**  model/request = input data contracts = DTO: data transfer object 

 

 

add DTO

1. no validate

2. enum =>string

3. delete virtual keyword

4. properties:  

=> Id property: no meaning in it

  backward compatibility => add it.

  if develop from scratch => delete it

=> remove properties with attribution: JsonIgnore

5. IList => List

6. remove heritage: Entity

 

 

 

 

 

 

from: domain model as output data contract

to: DTO as output data contract (translation : AutoMapper)

 

 

 

 

 

 不同的接口,返回 相同数据的不同属性 =》不同的DTO

eg:删除 List<PurchaseMovieDto>

 

1. domain model 中删除 json相关的attribution: JsonConverter, JsonIgnore => 不在 serialize domain model

2. 删除与输出相关的logic=》转移到 translation between domain model and DT0

 

from

 

to

 

 

 =>

重构 domain model ,只需修改 translation 部分即可。对外部的引用 无影响

 

 

 

 

Fiddle: 模拟 api 请求 =》debugging & composing web traffic

api历史记录 拖拽到 composer区域

 

修改 =》 正常请求

 

 

 非法请求 =》 不完整,不cohesion:

 

没有购买电影,却 花了钱:

=》没有清晰的数据隔离(domain module & data contract),导致 异常数据

 

=》即使override moneySpent字段,仍旧可能有其他属性漏掉;或者加入新属性后,此部分的修改被遗漏

=》 没有封装好。应该:明确api请求的属性,并且request只包含必须的属性,然后 convert between domain model and data contract

 

 

 

 

 =》创建新的DTO(model/request/response)

from

 

 to

1. DTO 删除无关属性 

2. DTO 包含 validation

 

domin class 删除 validation

 

 

 

from:

 

to

即使 新增属性,也不会带来 数据完整性 的风险

 

总结:

提取 input data contracts =》domin model 和 data contract 解耦

1. 去除 数据完整性 风险 =》fix 安全性 风险(create、update 获取的数据 多于 应该操作的数据 =》引入 脏数据、错误数据)

2. 增加了 可读性(what data 需要 what operations)

3. 利于 未来的重构,同时 使得接口 可以向后兼容(domin model 的变动 不会影响 data contract  => 调用方 无需修改代码)

 

posted @ 2022-05-28 10:37  PanPan003  阅读(14)  评论(0编辑  收藏  举报