public abstract class BoundedDomainModel<UnboundedModel extends IUnboundedDomainModel> extends Object
具体场景相关,运营相关,承载对应场景下的(数据,规则,行为),不能脱离IUnboundedDomainModel
独立存在,高内聚:它的代码改动只来源于该场景上下文需求
如果对象的某些行为在任何场景都是通用的,那么就放在IUnboundedDomainModel
,将其绑定,这是尊重"共性"的约束;如果某些行为依赖于具体场景,就赋予相应角色形成BoundedDomainModel
,这是尊重"个性"的自由.
IUnboundedDomainModel
通过扮演某个角色进入某个特定场景时拥有的属性或独立行为,成为BoundedDomainModel
IUnboundedDomainModel
回答了"它是什么"这个问题,不易变;BoundedDomainModel
回答了"它做了什么"这个问题,易变,聚焦于场景特有行为
IUnboundedDomainModel
的多个BoundedDomainModel
间要满足正交性,不能有重叠:不能角色错位if xxx order.asXxx() else if yyy order.asYyy()
,这样使用角色对象允许吗?不允许。角色对象解决确定性场景问题,不确定性问题交给扩展点IDomainExtension
解决多态问题。区别不同角色的是Role Method(扮演各自角色时,只能做出符合自己角色身份的行为),而不是同一个Method的不同实现(怎么做)
class User implements IUnboundedDomainModel {
Buyer asBuyer() {
return new Buyer(this);
}
Contact asContact() {
return new Contact(this);
}
Debtor asDebtor() {
return new Debtor(this);
}
}
// 电商上下文,用户角色是Buyer
class Buyer extends BoundedDomainModel<User> {
void placeOrder() {}
}
// 社交上下文,用户角色是Contact
class Contact extends BoundedDomainModel<User> {
List<Friend> myFriends() {}
void makeFriend(Contact whom) {}
}
// 金融上下文,用户角色是债务人
class Debtor extends BoundedDomainModel<User> {
void loan(Money amount) {}
void repay() {}
}
interface UserRepository {
User get(Long userId);
Buyer asBuyer(User user);
Contact asContact(User user);
}
进阶应用:不仅普通的IDomainModel
可以设计出角色对象,IBag
也可以。
class ShipmentOrderBag implements IUnboundedDomainModel {
// gateway是远程RPC的防腐层
public ShipmentOrderBagContextRemote inContextOfRemote(ShipmentOrderGateway gateway) {
return new ShipmentOrderBagContextRemote(this, gateway);
}
}
// 这个订单集合数据存在远程的【订单中心】,通过RPC交互
class ShipmentOrderBagContextRemote extends BoundedDomainModel<ShipmentOrderBag> {
private final ShipmentOrderGateway gateway;
ShipmentOrderBagContextRemote(ShipmentOrderBag model, ShipmentOrderGateway gateway) {
super(model);
this.gateway = gateway;
}
// 获取订单许可:其实是锁单,返回失败的单号
public ShipmentOrderBag acquireProductionLicence() {
Set<String> abnormalSoNoSet = gateway.acquireProductionLicence(OrderProductionNode.GENERATE_PACKAGE, model.orderNos(), model.warehouseNo());
ShipmentOrderBag abnormalShipmentOrderBag = model.filterOf(abnormalSoNoSet);
return abnormalShipmentOrderBag;
}
public void releaseProductionLicense() {}
}
class AppService {
void doSth() {
ShipmentOrderBagContextRemote remote = shipmentOrderBag.inContextOfRemote(shipmentOrderGateway);
// 远程模型被显性化了,而不是隐藏在过程式方法里;而且,它内部可以有状态
ShipmentOrderBag abnormalBag = remote.acquireProductionLicence();
shipmentOrderRepository.modifyStatusToException(abnormalBag);
}
}
限定符和类型 | 字段和说明 |
---|---|
protected UnboundedModel |
model |
构造器和说明 |
---|
BoundedDomainModel() |
protected UnboundedModel extends IUnboundedDomainModel model
public UnboundedModel unbounded()
Copyright © 2020–2023. All rights reserved.