C# 充血模型和贫血模型如何理解

58 阅读4分钟
  1. 贫血模型(Anemic Domain Model)
  • 定义

    • 在贫血模型中,领域对象(Domain Object)主要是作为数据的载体,只包含了简单的属性(通常是用于存储数据的成员变量)和基本的访问器(get 和 set 方法)。业务逻辑主要被分离出来,放在专门的业务逻辑层(Business Logic Layer)中。例如,一个简单的用户(User)类可能只有像用户名(UserName)、密码(Password)等属性,以及对应的 get 和 set 方法,而用户的注册、登录等业务逻辑并不在这个类中。
  • 示例代码

public class User
{
    private string userName;
    private string password;
    public string UserName
    {
        get { return userName; }
        set { userName = value; }
    }
    public string Password
    {
        get { return password; }
        set { password = value; }
    }
}
    • 优点

      • 结构简单清晰:由于业务逻辑和数据结构分离,使得代码的层次结构比较清晰。开发人员可以很容易地理解数据的存储结构,并且在业务逻辑层集中处理业务规则,易于维护和修改业务逻辑部分。例如,当需要修改用户登录的验证规则时,只需要在业务逻辑层进行修改,而不需要在多个包含用户对象的地方进行改动。
      • 适合简单场景和快速开发:在一些业务逻辑不复杂的小型项目或者业务逻辑相对稳定的场景中,贫血模型能够快速地搭建数据结构,开发人员可以迅速地开始编写业务逻辑代码,提高开发效率。
    • 缺点

      • 对象职责不完整:领域对象仅仅作为数据容器,没有真正体现对象的行为和职责。从面向对象设计的角度来看,这种设计不符合对象应该具有行为和状态的理念。例如,用户对象不能自己完成验证登录这样的操作,感觉上对象的封装性不够好。
      • 可能导致代码分散和重复:业务逻辑分散在业务逻辑层,可能会导致大量的服务类(Service Class)出现。当业务逻辑变得复杂时,这些服务类可能会变得臃肿,并且在不同的服务类中可能会出现重复的代码,因为相同的业务逻辑可能会涉及多个领域对象,而每个对象的数据获取和操作都需要在业务逻辑层单独编写代码。
  1. 充血模型(Rich Domain Model)

    • 定义

      • 充血模型强调领域对象应该包含业务逻辑,即对象自身能够完成与自身相关的操作。领域对象不仅有数据属性,还包含了操作这些数据的方法,这些方法体现了对象的行为。例如,对于用户(User)类,除了有用户名和密码属性外,还会有登录(Login)方法、注册(Register)方法等,这些方法内部包含了验证用户名和密码、将用户信息保存到数据库等业务逻辑。
    • 示例代码

public class User
{
    private string userName;
    private string password;
    public string UserName
    {
        get { return userName; }
        set { userName = value; }
    }
    public string Password
    {
        get { return password; }
        set { password = value; }
    }
    public bool Login(string inputUserName, string inputPassword)
    {
        // 在这里进行用户名和密码的验证,比如和数据库中的用户信息进行比对
        if (userName == inputUserName && password == inputPassword)
        {
            return true;
        }
        return false;
    }
    public void Register()
    {
        // 在这里实现将用户信息保存到数据库等注册逻辑
    }
}
  • 优点

    • 符合面向对象设计原则:充血模型使得领域对象真正具有了行为和状态,更符合面向对象编程中对象的职责完整性。对象能够自我管理和执行与自身相关的操作,提高了对象的封装性和内聚性。例如,用户对象可以自己完成登录和注册操作,就像一个真正的 “用户” 实体在系统中能够进行自我操作一样。
    • 减少代码分散和重复:由于业务逻辑被封装在领域对象内部,避免了业务逻辑在多个服务类中分散的问题。当需要修改业务逻辑时,只需要在相应的领域对象内部进行修改即可,不需要在多个业务逻辑层的服务类中查找和修改相关代码,提高了代码的可维护性。
  • 缺点

    • 模型复杂度过高:对于复杂的业务场景,领域对象可能会包含大量的业务逻辑方法,导致对象变得庞大和复杂,难以理解和维护。例如,在一个大型电商系统中,商品(Product)对象可能需要包含定价策略、库存管理、促销活动等众多复杂的业务逻辑,这会使得商品对象的代码量和复杂度大幅增加。
    • 对开发人员要求较高:开发人员需要对领域知识和面向对象设计有更深入的理解,才能合理地将业务逻辑封装到领域对象中。否则,可能会出现业务逻辑封装混乱、对象职责划分不明确等问题,影响系统的质量和可维护性。