导读:本期聚焦于小伙伴创作的《面向对象系统设计选贫血模型还是充血模型?业务变量分配场景实战选型指南》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《面向对象系统设计选贫血模型还是充血模型?业务变量分配场景实战选型指南》有用,将其分享出去将是对创作者最好的鼓励。

在面向对象系统设计中,贫血模型与充血模型是两种核心的领域建模思路,二者的差异会直接影响业务逻辑的承载方式和系统的长期可维护性。在业务变量分配这类需要频繁调整规则、关联多业务实体的场景中,选型的正确性尤为重要。

面向对象系统设计选贫血模型还是充血模型?业务变量分配场景实战选型指南

两种模型的核心定义与差异

贫血模型

贫血模型是指领域对象仅作为数据载体,只包含属性和对应的getter、setter方法,所有业务逻辑都放在服务层(Service)中实现。这种模型将数据和行为分离,领域对象本身不具备业务能力。

充血模型

充血模型是指领域对象不仅包含属性,还封装了和自身相关的所有业务逻辑,领域对象本身是行为的主体,服务层仅负责协调领域对象、处理跨领域的流程编排。

核心差异对比

对比维度贫血模型充血模型
逻辑承载位置服务层领域对象自身
数据与行为耦合度低,二者分离高,二者绑定
代码复用性低,逻辑集中在服务层,难以跨场景复用高,领域对象的方法可被多个场景调用
学习成本低,符合传统分层架构习惯高,需要理解领域驱动设计思想

业务变量分配场景的需求分析

业务变量分配通常指根据预设规则,将可分配的变量(如优惠额度、任务配额、资源权重等)分配给对应的业务实体(如用户、部门、商户等)。这类场景通常有以下特点:

  • 分配规则可能随业务发展频繁调整,比如新增分配维度、修改权重计算逻辑
  • 分配过程需要校验多个前置条件,比如用户是否满足参与资格、变量余量是否充足
  • 可能涉及到多个实体之间的关联计算,比如部门配额需要汇总下属用户的分配量

两种模型的实战实现示例

贫血模型实现

首先定义数据载体类:

// 业务变量实体
public class BusinessVariable {
    private String variableId;
    private String variableName;
    private Integer totalAmount;
    private Integer usedAmount;

    // getter和setter方法
    public String getVariableId() {
        return variableId;
    }
    public void setVariableId(String variableId) {
        this.variableId = variableId;
    }
    public String getVariableName() {
        return variableName;
    }
    public void setVariableName(String variableName) {
        this.variableName = variableName;
    }
    public Integer getTotalAmount() {
        return totalAmount;
    }
    public void setTotalAmount(Integer totalAmount) {
        this.totalAmount = totalAmount;
    }
    public Integer getUsedAmount() {
        return usedAmount;
    }
    public void setUsedAmount(Integer usedAmount) {
        this.usedAmount = usedAmount;
    }
}

// 用户实体
public class User {
    private String userId;
    private String userName;
    private Integer level;

    // getter和setter方法
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public Integer getLevel() {
        return level;
    }
    public void setLevel(Integer level) {
        this.level = level;
    }
}

服务层实现分配逻辑:

public class VariableAssignService {
    // 分配业务变量
    public void assignVariable(BusinessVariable variable, User user, Integer assignAmount) {
        // 校验变量余量
        if (variable.getUsedAmount() + assignAmount > variable.getTotalAmount()) {
            throw new RuntimeException("变量余量不足");
        }
        // 校验用户资格
        if (user.getLevel() < 2) {
            throw new RuntimeException("用户等级不符合要求");
        }
        // 执行分配
        variable.setUsedAmount(variable.getUsedAmount() + assignAmount);
        // 这里可以补充记录分配流水等逻辑
        System.out.println("为用户" + user.getUserName() + "分配" + assignAmount + "个" + variable.getVariableName());
    }
}

充血模型实现

定义封装逻辑的领域对象:

// 业务变量领域对象
public class BusinessVariable {
    private String variableId;
    private String variableName;
    private Integer totalAmount;
    private Integer usedAmount;

    // 构造方法
    public BusinessVariable(String variableId, String variableName, Integer totalAmount, Integer usedAmount) {
        this.variableId = variableId;
        this.variableName = variableName;
        this.totalAmount = totalAmount;
        this.usedAmount = usedAmount;
    }

    // 校验余量是否充足
    public boolean hasEnoughAmount(Integer assignAmount) {
        return this.usedAmount + assignAmount <= this.totalAmount;
    }

    // 执行分配,更新自身状态
    public void doAssign(Integer assignAmount) {
        if (!hasEnoughAmount(assignAmount)) {
            throw new RuntimeException("变量余量不足");
        }
        this.usedAmount += assignAmount;
    }

    // getter方法,不提供setter,保证状态只能通过内部方法修改
    public String getVariableId() {
        return variableId;
    }
    public String getVariableName() {
        return variableName;
    }
    public Integer getTotalAmount() {
        return totalAmount;
    }
    public Integer getUsedAmount() {
        return usedAmount;
    }
}

// 用户领域对象
public class User {
    private String userId;
    private String userName;
    private Integer level;

    public User(String userId, String userName, Integer level) {
        this.userId = userId;
        this.userName = userName;
        this.level = level;
    }

    // 校验是否有分配资格
    public boolean canAssign() {
        return this.level >= 2;
    }

    public String getUserId() {
        return userId;
    }
    public String getUserName() {
        return userName;
    }
    public Integer getLevel() {
        return level;
    }
}

服务层仅做协调:

public class VariableAssignService {
    public void assignVariable(BusinessVariable variable, User user, Integer assignAmount) {
        // 调用领域对象自身的校验逻辑
        if (!user.canAssign()) {
            throw new RuntimeException("用户等级不符合要求");
        }
        // 调用领域对象的分配逻辑
        variable.doAssign(assignAmount);
        System.out.println("为用户" + user.getUserName() + "分配" + assignAmount + "个" + variable.getVariableName());
    }
}

业务变量分配场景的选型建议

在实际的业务变量分配场景中,选型可以参考以下维度:

  • 如果业务规则简单、长期变动少,且团队对领域驱动设计不熟悉,优先选择贫血模型,开发效率高,学习成本低
  • 如果业务规则复杂、需要频繁调整分配逻辑,且团队具备领域建模能力,优先选择充血模型,逻辑内聚在领域对象中,后续规则修改只需要调整对应领域对象的方法,不会影响服务层的其他逻辑,可维护性更强
  • 如果是中小型项目,业务复杂度中等,可以采用折中方案:将基础校验、状态更新的逻辑放在领域对象中,复杂的跨实体编排逻辑放在服务层,兼顾开发效率和可维护性

需要注意的是,无论选择哪种模型,都要保持项目内模型风格的统一,避免部分模块用贫血模型、部分模块用充血模型,增加代码的认知成本。

贫血模型充血模型面向对象设计业务变量分配修改时间:2026-06-12 13:27:37

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。