zoukankan      html  css  js  c++  java
  • DDD:谈谈数据模型、领域模型、视图模型和命令模型

    背景

    一个类型可以充当多个角色,这个角色可以是显式的(实现了某个接口或基类),也可以是隐式的(承担的具体职责和上下文决定),本文就讨论四个角色:数据模型、领域模型、视图模型和命令模型。

    四个角色

    1. 数据模型:面向持久化,数据的载体。
    2. 领域模型:面向业务,行为的载体。
    3. 视图模型:面向UI(向外),数据的载体。
    4. 命令模型:面向UI(向内),数据的载体。

    这是四种角色,可以由一至四个类型来承担,具体选择几个类型需要考虑项目的上下文,但不同的选择对编程的要求是不同的,下面举几个例子。

    数据模型和领域模型采用统一个类型,采用EntityFramework进行持久化。

    这种设计毫无疑问对这个类型是有侵入性的,即使采用了POCO,如果需要延时加载,也只能做到编译时的POCO,运行时还是会生成代理类型,某些成员需要生命为virtual,你还需要记得默认构造方法和属性的setter都会被EntityFramework在重建对象时候调用。一个类型承担了两个角色,就要完成两份职责(持久化和封装业务逻辑),这或许违背了单一职责原则,不过某些情况下这是最好的选择了。

    四个角色采用一个类型

    这种设计适合业务逻辑不是很复杂的场景,系统中只有CRUD,以四色原型为例,PPT和Des适合采用这种模式。因为这个类型要承担四个角色,所以没办法采用显式的封装技术,所有成员都是Public { get; set; },考虑到很多动态语言其实是没法封装的(是按照约定),或许C#开发者可以接受这种设计,比如:虽然集合被公开了,但是我们还是可以采用封装集合模式,外部调用的时候要根据约定采用封装过的接口,TDD有利于强制这种约定,示例代码:

    1 public class Order
    2 {
    3    public List<OrderItem> Items { get; set; }
    4 
    5    public void AddItem(OrderItem item) {}
    6 }

    为视图模型引入单独的类型

    你采用了WCF技术,你的UI期望的数据和领域模型非常不匹配(也是一种阻抗不匹配),这时你就会引入视图模型。如何构造视图模型呢?一般来说有两种思路:一、用AutoMapper之类的工具从领域模型映射;二、采用轻量级的框架(PetaPoco)直接从表、视图和存储过程返回。

    备注

    今天只是大概聊了聊这样一个想法,下一步会写一些Demo验证几种不同的组合。

  • 相关阅读:
    linux安装git
    安装tidb数据库
    docker的简单操作和端口映射
    zabbix的简单操作(查看监控,自定义监控和钉钉监控报警)
    zabbix简单的操作(添加主机)
    LINQ 函数的实战演练测试
    C#基础:LINQ 查询函数整理
    C#中的LINQ
    C#高级编程笔记 2016年10月26日 MVC入门 Controller
    委托、Lambda表达式和事件
  • 原文地址:https://www.cnblogs.com/happyframework/p/3242183.html
Copyright © 2011-2022 走看看