2026/2/17 3:26:07
网站建设
项目流程
做网站的步骤,怎样下载模板网站,网站建设3a模型是什么,微软手机做网站服务器吗文章目录一、什么是贫血模型#xff1a;数据与逻辑分离的典型模式MVC 三层架构的典型实现贫血模型的定义贫血模型的本质二、什么是充血模型#xff1a;符合 OOP 的封装设计充血模型的实现方式充血模型的核心特征三、为什么贫血模型违反 OOP#xff1a;破坏了封装原则封装原则…文章目录一、什么是贫血模型数据与逻辑分离的典型模式MVC 三层架构的典型实现贫血模型的定义贫血模型的本质二、什么是充血模型符合 OOP 的封装设计充血模型的实现方式充血模型的核心特征三、为什么贫血模型违反 OOP破坏了封装原则封装原则的核心要求贫血模型如何违反封装违反 OOP 的后果四、为什么贫血模型如此流行简单直观的代价简单直观易于理解学习成本低适合快速开发框架和工具的支持流行的代价五、什么时候使用充血模型复杂业务的领域建模什么是领域驱动设计DDD充血模型与 DDD 的关系什么时候考虑使用充血模型1. 业务逻辑复杂2. 需要领域建模3. 微服务拆分DDD 不是银弹实际应用建议总结核心观点贫血模型将数据与业务逻辑分离虽然违反了面向对象的封装原则但因为简单直观、易于上手成为了主流的开发模式。只有在业务复杂、需要领域建模的场景下才应该考虑使用基于充血模型的 DDD 开发模式。核心要点贫血模型将数据和业务逻辑分离到不同类中本质是面向过程编程充血模型将数据和业务逻辑封装在一起符合面向对象封装特性贫血模型流行是因为简单直观、学习成本低、适合快速开发复杂业务场景下充血模型能更好地表达业务逻辑降低维护成本一、什么是贫血模型数据与逻辑分离的典型模式核心结论贫血模型是指只包含数据、不包含业务逻辑的类它将数据与操作分离破坏了面向对象的封装特性。MVC 三层架构的典型实现MVC 三层架构将项目分为展示层、逻辑层、数据层。在前后端分离的 Web 项目中通常演化为Repository 层负责数据访问如UserRepositoryService 层负责业务逻辑如UserServiceController 层负责暴露接口如UserController这种分层方式下数据对象和业务逻辑被分离到不同的类中。贫血模型的定义以用户管理为例// UserBo只包含数据不包含业务逻辑publicclassUserBo{privateLongid;privateStringname;privateStringemail;// 只有 getter/setter没有业务方法}// UserService包含业务逻辑publicclassUserService{publicvoidcreateUser(UserBouser){...}publicvoidupdateUser(UserBouser){...}publicbooleanvalidateEmail(Stringemail){...}}像UserBo这样只包含数据、不包含业务逻辑的类就是贫血模型Anemic Domain Model。同样UserEntity数据访问层、UserVo接口层也都是基于贫血模型设计的。贫血模型的本质贫血模型将数据与操作分离本质上是面向过程的编程风格。数据对象只是数据的容器业务逻辑集中在 Service 层这破坏了面向对象的封装特性——数据和操作应该封装在一起。二、什么是充血模型符合 OOP 的封装设计核心结论充血模型中数据和对应的业务逻辑被封装到同一个类中满足面向对象的封装特性是典型的面向对象编程风格。充血模型的实现方式在充血模型中业务逻辑不再集中在 Service 层而是封装在领域对象内部// User包含数据和业务逻辑publicclassUser{privateLongid;privateStringname;privateStringemail;// 业务逻辑封装在对象内部publicvoidchangeEmail(StringnewEmail){if(!isValidEmail(newEmail)){thrownewIllegalArgumentException(Invalid email);}this.emailnewEmail;}publicvoidactivate(){if(this.statusStatus.INACTIVE){this.statusStatus.ACTIVE;this.activatedAtLocalDateTime.now();}}privatebooleanisValidEmail(Stringemail){// 邮箱验证逻辑returnemail!nullemail.contains();}}充血模型的核心特征数据和业务逻辑封装在一起对象不仅包含数据还包含操作这些数据的方法符合封装原则对象的内部状态和行为被封装外部只能通过公开的方法访问面向对象编程风格对象是活的有自己的行为而不是被动的数据容器三、为什么贫血模型违反 OOP破坏了封装原则核心结论贫血模型将数据与操作分离破坏了面向对象的封装特性本质上是面向过程的编程风格。封装原则的核心要求面向对象编程的核心原则之一是封装Encapsulation将数据和对数据的操作封装在一起隐藏内部实现细节只暴露必要的接口。贫血模型如何违反封装在贫血模型中数据与操作分离UserBo只包含数据UserService包含操作两者分离无法保护数据完整性任何地方都可以直接修改UserBo的属性无法保证数据的一致性业务逻辑分散相关的业务逻辑可能分散在多个 Service 方法中难以维护例如在贫血模型中修改用户邮箱的逻辑可能在UserService中// 贫血模型业务逻辑在 Service 中publicclassUserService{publicvoidupdateEmail(UserBouser,StringnewEmail){if(!isValidEmail(newEmail)){thrownewIllegalArgumentException(Invalid email);}user.setEmail(newEmail);// 直接修改数据无法保护数据完整性}}而在充血模型中业务逻辑封装在对象内部可以保护数据完整性// 充血模型业务逻辑在对象内部publicclassUser{privateStringemail;publicvoidchangeEmail(StringnewEmail){if(!isValidEmail(newEmail)){thrownewIllegalArgumentException(Invalid email);}this.emailnewEmail;// 通过方法修改可以添加验证逻辑}}违反 OOP 的后果数据完整性无法保证外部代码可以直接修改对象属性绕过业务规则代码重复相同的业务逻辑可能在多个 Service 方法中重复难以维护业务逻辑分散修改时需要找到所有相关的地方四、为什么贫血模型如此流行简单直观的代价核心结论贫血模型虽然违反 OOP但因为简单直观、学习成本低、适合快速开发成为了主流的开发模式。简单直观易于理解贫血模型的结构非常清晰数据层Entity/Bo 只包含数据逻辑层Service 包含所有业务逻辑接口层Controller 负责暴露接口这种分层方式直观明了新手也能快速理解数据在哪里逻辑在哪里接口在哪里。学习成本低对于大多数开发者来说不需要深入理解 OOP只需要知道如何定义数据类和编写 Service 方法不需要领域建模不需要思考业务对象的职责和行为快速上手按照固定的模板就能开发功能适合快速开发在业务需求频繁变化的场景下快速迭代添加新功能只需要在 Service 中添加方法易于调试逻辑集中在 Service 层问题定位简单团队协作不同开发者可以并行开发不同的 Service 方法框架和工具的支持主流框架如 Spring默认支持贫血模型ORM 框架Entity 只需要定义数据字段框架自动处理持久化依赖注入Service 层可以方便地注入 Repository 和其他 ServiceAOP 支持可以在 Service 方法上添加事务、日志等横切关注点流行的代价虽然贫血模型简单直观但在复杂业务场景下会带来问题Service 层臃肿随着业务增长Service 类会变得越来越大业务逻辑分散相关逻辑可能分散在多个 Service 方法中难以表达业务概念无法通过代码清晰地表达业务领域的核心概念五、什么时候使用充血模型复杂业务的领域建模核心结论在业务复杂、需要领域建模的场景下应该考虑使用基于充血模型的 DDD 开发模式。什么是领域驱动设计DDD领域驱动设计Domain-Driven DesignDDD主要用来指导如何解耦业务系统、划分业务模块、定义业务领域模型及其交互。DDD 被广泛认知很大程度上是因为微服务的兴起。微服务拆分需要合理地划分业务边界而 DDD 恰好提供了划分服务的指导方法。充血模型与 DDD 的关系DDD 强调领域模型是业务的核心应该用代码清晰地表达业务概念。充血模型将业务逻辑封装在领域对象中正好符合 DDD 的要求。在 DDD 中实体Entity有唯一标识的对象包含业务逻辑值对象Value Object没有唯一标识的对象通过值来区分领域服务Domain Service不适合放在实体中的业务逻辑什么时候考虑使用充血模型1. 业务逻辑复杂当业务逻辑复杂、涉及多个业务规则时贫血模型会导致Service 层方法过长难以理解业务规则分散难以维护无法清晰地表达业务概念例如电商系统中的订单对象// 充血模型订单对象包含复杂的业务逻辑publicclassOrder{privateOrderStatusstatus;privateListOrderItemitems;privatePaymentpayment;// 业务逻辑封装在对象内部publicvoidcancel(){if(statusOrderStatus.SHIPPED){thrownewIllegalStateException(Cannot cancel shipped order);}if(payment!nullpayment.isPaid()){// 退款逻辑refund();}this.statusOrderStatus.CANCELLED;}publicvoidaddItem(Productproduct,intquantity){// 验证库存、计算价格等逻辑validateStock(product,quantity);items.add(newOrderItem(product,quantity,calculatePrice(product,quantity)));}}2. 需要领域建模当需要清晰地表达业务领域的核心概念时充血模型能够通过代码表达业务概念订单对象的行为就是业务规则降低理解成本代码即文档业务逻辑一目了然提高可维护性业务规则变更时只需要修改领域对象3. 微服务拆分在微服务架构中DDD 可以帮助划分服务边界通过领域模型识别服务的职责定义服务接口领域对象的行为就是服务的接口降低服务耦合每个服务有自己的领域模型DDD 不是银弹做好领域驱动设计的关键是看你对自己所做业务的熟悉程度而并不是对领域驱动设计这个概念本身的掌握程度。不要把 DDD 当银弹不要花太多时间过度研究它。对于简单的 CRUD 应用使用贫血模型可能更合适只有在业务复杂、需要领域建模时才应该考虑使用充血模型。实际应用建议简单业务使用贫血模型快速开发复杂业务考虑使用充血模型通过领域建模表达业务逻辑渐进式重构不要一开始就使用 DDD可以在业务复杂度增加时逐步重构总结贫血模型将数据与业务逻辑分离虽然违反了面向对象的封装原则但因为简单直观、易于上手成为了主流的开发模式。充血模型将数据和业务逻辑封装在一起符合面向对象的设计原则适合在业务复杂、需要领域建模的场景下使用。选择哪种模式取决于业务复杂度简单业务用贫血模型快速开发复杂业务用充血模型进行领域建模。关键是要理解业务而不是过度追求某种设计模式。