本文转载自【何以解耦】:https://codedecoupled.com/ane…
畛域模型
畛域模型是一种用于解决简单业务逻辑的建模工具 / 思维。大神 Martin Fowler 定义其为蕴含行为和数据的对象模型。
应用畛域模型时,咱们的指标是建设丰盛的充血畛域模型,但因为某种原因,一种不被提倡的模式(贫血模型)被宽泛应用。
贫血畛域模型
贫血模型是一种家喻户晓的反模式(anti-pattern),然而要摈弃这种思维却不是简略的事件。因为这种设计开发迅速,易于了解。不经意间,它就可能呈现在咱们的代码中。
举个例子,咱们的利用中有一个激活用户性能:
class User extends OrmModel
{public setStatus($status)
{$this->status = $status;}
public getStatus()
{return $this->status;}
}
class UserService
{public activate(User $user)
{if ($user->getStatus() === 'blacklisted') {throw new \Exception('User is blacklisted');
}
$user->setStatus('active');
$user->save();}
}
乍一看,这种模式有模有样:数据库表通过映射建造一些 ORM 类,各类之间存在肯定的关系,而且还应用了服务层(Service layer)进行分层治理。
然而让咱们认真想想。User 类无非一些 getter 和 setter,合乎了畛域模型蕴含数据的规范,却缺失了最重要的局部:行为。而将业务逻辑放入服务类(Service class)中,造成了一种相似于事务处理脚本的面向过程的编程形式,与畛域模型所提倡的面向对象编程南辕北辙。一个衰弱的服务层应该是很薄的,其主要职责是调用充血的畛域模型实现业务流程。
这种贫血模型建设在畛域模型的老本上,却没有带来畛域模型的益处。
充血畛域模型
充血畛域模型是畛域模型所提倡的建模形式。顾名思义,充血畛域模型是蕴含行为和数据的对象模型。
举个例子,上文中的激活用户性能:
class User extends OrmModel
{public function activate()
{if ($user->status === 'blacklisted') {throw new \Exception('User is blacklisted');
}
$this->status = 'active';
}
}
class UserService
{public function activate(User $user)
{$user->activate();
$user->save();}
}
一个欠缺的充血畛域模型能升高 Bug 危险,帮忙咱们更直观的建设业务模型。
建设充血畛域模型须要开发者具备良好的面向对象思维。可能精确划分服务层逻辑和畛域层(Domain Layer)逻辑。
教训法令是,在建设服务层时候,业务逻辑应被封至畛域层,事务逻辑封装应被封至服务层,因而服务层应该是很薄的。此处的薄不能齐全代表代码量,而是指业务逻辑含量。
隔靴搔痒
畛域模型的目标是简化一个简单的问题,而不是将一个简略的问题复杂化。正如 Martin Fowler 所说,畛域模型并非包治百病的灵丹妙药,开发者在解决问题时还需隔靴搔痒:
如果你解决的问题应用增删改查即可实现,那么应用譬如 Active Record 这种数据驱动模式才是更适宜的计划。应用畛域模型来解决简略的 CURD 问题,那就成了牛刀割鸡,得失相当。
本文转载自【何以解耦】:https://codedecoupled.com/ane…,如果你也对 TDD,DDD 以及简洁代码感兴趣,欢送关注公众号【何以解耦】,一起摸索软件开发之道。