thinkphp只能做网站,大连制作公司网站,自适应响应式网站源码,网站整站开发教程文章目录 架构区别MVC三层架构DDD四层架构 贫血模型代码示例 充血模型代码示例 架构区别
MVC三层架构
MVC三层架构是软件工程中的一种设计模式#xff0c;它将软件系统分为 模型#xff08;Model#xff09;、视图#xff08;View#xff09;和控制器#xff08;Contro… 文章目录 架构区别MVC三层架构DDD四层架构 贫血模型代码示例 充血模型代码示例 架构区别
MVC三层架构
MVC三层架构是软件工程中的一种设计模式它将软件系统分为 模型Model、视图View和控制器Controller 三个核心部分。具体如下
模型Model模型代表的是数据和业务逻辑它负责管理应用程序的数据和定义操作数据的规则。模型直接与数据库进行交互处理如数据库查询、更新等操作并返回结果给视图或控制器。视图View视图是用户界面元素它负责显示模型层提供的数据。视图通常不包含程序的逻辑而是专注于数据的展示和用户交互的界面。一个模型可以对应多个视图即相同的数据可以以不同的方式展现给用户。控制器Controller控制器是模型与视图之间的协调者它处理用户的输入和系统的事件执行相应的业务逻辑并选择相应的视图来展示模型处理后的数据。控制器确保模型和视图之间的同步和数据的一致性。
DDD四层架构
DDD的四层架构旨在通过明确的层次划分来组织代码结构促进模块化、可维护性和可扩展性。尽管DDD本身并未严格定义必须使用四层架构不过在实践中开发者常参考以下四层来构建DDD应用 表示层Presentation Layer 这一层负责用户界面的展示和用户交互。它包括Web页面、移动应用的界面或是命令行界面等。此层的主要职责是接收用户的输入并展示处理结果同时调用领域层的服务来完成业务操作。 应用层Application Layer 应用层是领域层和表示层之间的桥梁它负责协调领域对象执行业务操作处理事务边界以及执行任何与具体技术框架相关的任务如安全、权限控制等。应用层中的服务通常很薄主要封装领域逻辑的入口点而不包含业务规则。 领域层Domain Layer DDD的核心所在封装了复杂的业务规则和逻辑。这一层包含了领域模型、实体Entities、值对象Value Objects、聚合Aggregates、领域事件Domain Events等概念。领域层的设计关注于反映业务领域的本质使得业务逻辑清晰、可维护。 基础设施层Infrastructure Layer 提供底层技术支持如数据库访问、消息队列、外部服务调用等。这一层实现了技术细节如ORM映射、数据库访问接口、日志记录等为上层提供必要的服务同时也隐藏了技术实现细节使得领域层和应用层能更加专注于业务逻辑。
贫血模型
在MVCModel-View-Controller架构中模型Model负责管理应用程序的数据和业务逻辑。如果模型的实现过于简单仅仅作为数据的容器而没有包含足够的业务逻辑就可能导致所谓的“贫血模型”。 在这种情况下控制器Controller可能会变得过于臃肿因为它需要处理大量的业务逻辑而这些逻辑本应该由模型来管理。这种设计问题被称为“贫血模型膨胀控制器”Anemic Model, Bloated Controller其中“贫血模型”指的是缺乏业务逻辑的模型而“膨胀控制器”则指代承担了过多职责的控制器。 MVC架构中的贫血模型会降低代码的可维护性将导致以下问题
业务逻辑分散由于业务逻辑主要在控制器中实现而不是封装在模型中这导致业务逻辑分散在多个控制器中。当需要修改或扩展业务逻辑时开发者需要找到并修改所有相关的控制器这使得维护变得更加困难和耗时。代码复用性差模型层如果只是简单的数据容器而没有包含业务逻辑那么这些模型就很难在不同的上下文中重用。每个新的应用场景都需要重新编写控制器逻辑这增加了开发的工作量并且可能导致重复代码的产生。违反单一职责原则理想情况下每个类应该只有一个引起变化的原因。但在贫血模型中控制器既处理用户输入和交互又处理业务逻辑这违反了单一职责原则。当一个类承担了过多的职责时它变得难以理解和修改。
代码示例
下面是一个示例展示了一个基本的银行账户BankAccount领域对象包含了存款deposit和取款withdraw的业务逻辑
public class BankAccountService {public void deposit(BankAccount account, double amount) {if (amount 0) {throw new IllegalArgumentException(Deposit amount must be positive.);}double newBalance account.getBalance() amount;account.setBalance(newBalance);}public void withdraw(BankAccount account, double amount) {if (amount 0) {throw new IllegalArgumentException(Withdrawal amount must be positive.);}if (account.getBalance() amount) {throw new IllegalStateException(Insufficient funds.);}double newBalance account.getBalance() - amount;account.setBalance(newBalance);}
}充血模型
在DDD中充血模型Rich Model是一种设计哲学它强调将业务逻辑和规则尽可能地集中在领域模型中而不是分散在服务层或控制器中。这种设计方法与贫血模型Anemic Model形成对比后者的领域模型通常只包含数据结构而业务逻辑则被放置在其他地方如控制器或服务层。 充血模型的特点包括
丰富的领域逻辑领域模型包含与该领域相关的所有业务逻辑和行为这使得模型具有丰富的功能和表现力。封装性通过将业务逻辑封装在领域模型中这些逻辑对外部是不可见的只能通过模型提供的接口进行交互。领域专家的语言领域模型使用领域专家的语言来表达概念和规则这有助于确保软件设计与业务需求紧密匹配。可维护性和可扩展性由于业务逻辑集中在领域模型中当业务规则发生变化时只需要修改相应的模型而不需要在整个应用程序中寻找和修改逻辑。高度的内聚性领域模型是围绕业务概念构建的这使得相关的业务逻辑和数据高度内聚
充血模型的优点在于它能够更好地反映和处理复杂的业务需求同时提高了代码的可读性、可维护性和可测试性。然而它也可能需要更多的设计和抽象工作特别是在项目的早期阶段。
代码示例
下面是一个简化的充血模型示例展示了一个基本的银行账户BankAccount领域对象包含了存款deposit和取款withdraw的业务逻辑
// 银行账户领域对象 - 充血模型示例
public class BankAccount {private String accountId;private double balance;// 构造函数public BankAccount(String accountId, double initialBalance) {if (initialBalance 0) {throw new IllegalArgumentException(Initial balance cannot be negative.);}this.accountId accountId;this.balance initialBalance;}// 存款业务逻辑public void deposit(double amount) {if (amount 0) {throw new IllegalArgumentException(Deposit amount must be positive.);}addAmountToBalance(amount);}// 取款业务逻辑包含校验余额public void withdraw(double amount) {if (amount 0) {throw new IllegalArgumentException(Withdrawal amount must be positive.);}checkSufficientFunds(amount);subtractAmountFromBalance(amount);}// Getter方法通常在充血模型中只用于展示非业务逻辑的一部分public double getBalance() {return balance;}// 增加余额public void addAmountToBalance(double amount){return balance amount;}// 扣减余额public void subtractAmountFromBalance(double amount){return balance - amount;}// 检查余额public boolean checkSufficientFunds(double amount){if (balance amount) {throw new IllegalStateException(Insufficient funds.);}return true;}} public class Main {public static void main(String[] args) {BankAccount account new BankAccount(123456, 0);account.deposit(500); try {account.withdraw(300);} catch (IllegalStateException e) {System.out.println(e.getMessage());}}
}BankAccount 类不仅包含了账户的属性如 accountId 和 balance还直接实现了业务操作如存款和取款并包含了相关的业务规则检查比如不能存取负数金额取款不能超过余额。这就是充血模型的核心思想即领域对象本身是富含业务逻辑的。