DDD(领域驱动设计)与 MVC(模型-视图-控制器)的区别

DDD(领域驱动设计)与 MVC(模型-视图-控制器)的区别

维度MVCDDD解析
核心目标分离界面与业务逻辑解决复杂业务领域问题MVC关注技术分层,DDD专注业务建模
设计起点数据库/技术实现业务领域模型MVC常以数据表设计开始,DDD从业务概念和规则出发
模型定义数据容器(常为贫血模型)富含行为的业务实体MVC模型多为getter/setter,DDD模型封装业务规则
分层逻辑技术分层(视图-控制-模型)业务分层(领域/应用/基础设施/接口)DDD通过分层保护核心业务不受技术实现污染
架构重心请求-响应流程领域模型演进MVC优化请求处理,DDD优化业务知识沉淀
数据访问直接调用ORM(如Eloquent)通过仓储抽象DDD用接口隔离持久化细节,支持多实现
业务逻辑位置常分散在控制器/服务类内聚在领域模型中DDD确保业务规则与数据绑定,避免贫血模型
代码组织按技术角色(Controllers, Models等)按业务子域(Order, User, Payment)DDD的结构映射业务语义,便于定位功能
适用场景CRUD应用/简单业务高复杂性业务系统(电商、金融等)DDD的复杂度在中小型项目中可能过度

核心区别深度解析

1. 模型本质差异

MVC模型(贫血模型):

// MVC典型模型 (贫血)
class Order extends Model {
    // 仅有属性和简单访问方法
    protected $fillable = ['total', 'status'];
    
    public function user() {
        return $this->belongsTo(User::class); 
    }
}

// 业务逻辑泄漏到控制器
class OrderController {
    public function complete(Order $order) {
        if($order->status !== 'paid') { // 业务规则暴露在控制器
            abort(403, '订单未支付');
        }
        $order->update(['status' => 'completed']); // 简单数据操作
    }
}

DDD领域模型(充血模型):

// DDD领域模型
class Order {
    private OrderId $id;
    private Money $total;
    private OrderStatus $status;
    
    public function __construct(OrderId $id, Money $total) {
        $this->id = $id;
        $this->total = $total;
        $this->status = OrderStatus::PENDING;
    }
    
    // 业务行为内聚在模型中
    public function complete(): void {
        if(!$this->status->canBeCompleted()) { // 规则封装在值对象中
            throw new OrderCompletionException();
        }
        $this->status = OrderStatus::COMPLETED;
        $this->addEvent(new OrderCompleted($this->id)); // 领域事件
    }
}

// 应用层协调
class CompleteOrderService {
    public function execute(OrderId $id) {
        $order = $this->repository->find($id);
        $order->complete(); // 调用领域行为
        $this->repository->save($order);
    }
}
2. 数据访问方式对比

MVC直接耦合持久化:

// 直接使用Eloquent
$orders = Order::where('status', 'completed')->with('user')->get();

DDD通过仓储抽象:

// 领域层定义接口
interface OrderRepository {
    public function findCompletedOrders(): Collection;
}

// 基础设施层实现
class EloquentOrderRepository implements OrderRepository {
    public function findCompletedOrders() {
        // 返回领域对象而非Eloquent模型
        return OrderModel::completed()->get()->map(fn($model) => $this->toDomain($model));
    }
}

// 应用层调用
$orders = $orderRepository->findCompletedOrders(); // 不依赖具体ORM
3. 业务规则处理差异

MVC的典型问题:

// 业务规则分散在服务类
class OrderService {
    public function applyDiscount(Order $order, Discount $discount) {
        // 业务逻辑泄漏到服务层
        if($order->created_at->diffInDays() > 30) {
            throw new DiscountExpiredException();
        }
        $newTotal = $order->total - $discount->amount; // 计算放在服务层
        $order->update(['total' => $newTotal]);
    }
}

DDD的正确实践:

// 领域模型中封装规则
class Order {
    public function applyDiscount(Discount $discount): void {
        if(!$discount->isApplicableTo($this)) { // 规则委托给值对象
            throw new DiscountNotApplicableException();
        }
        $this->total = $this->total->subtract($discount->amount); // 计算内聚
    }
}

// 值对象维护业务规则
class Discount {
    public function isApplicableTo(Order $order): bool {
        return $this->validPeriod->contains($order->createdAt);
    }
}

演进关系图解

传统MVC:
  请求 → 控制器 → 服务类 → 贫血模型 → 数据库

DDD分层:
  请求 → 控制器(接口层)
        → 应用服务(应用层)
            → 领域模型/领域服务(领域层)
                ← 仓储接口(领域层)
                    → 仓储实现(基础设施层)
                        → 数据库

何时选择哪种架构?

场景推荐架构原因
管理后台/简单CRUD✅ MVC快速开发,避免过度设计
中等复杂度业务系统⚠️ 改良MVC增加服务层,部分引入DDD概念
核心复杂业务域✅ DDD应对业务复杂度,保持代码可维护性
微服务中的核心服务✅ DDD清晰边界,独立演进
遗留系统重构✅ 渐进式DDD从核心子域开始逐步改造

关键洞察:DDD不是替代MVC,而是在复杂业务场景下对MVC的深化演进。Laravel项目中可混合使用:非核心模块用MVC,核心业务用DDD。


混合架构实践(Laravel特定)

app/
├── Http/                     # MVC部分 (简单模块)
│   ├── Controllers/Admin     # 后台控制器
│   └── Requests/             
│
└── Domains/                  # DDD部分 (核心业务)
    └── Inventory/            # 库存子域
        ├── Models/           # 领域模型
        ├── Repositories/     # 仓储接口
        ├── Services/         # 领域服务
        └── Actions/          # 应用层操作

这种结构允许团队:

  1. 对商品管理等复杂功能使用DDD
  2. 对日志查看等简单功能保持MVC
  3. 逐步重构关键业务到Domains目录
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值