根据我在 http://www.jdon.com/44626/15#23140500中提出,场景似乎应该是有行为发生的场合,虽然也是一种混合体,但不同于聚合这种结构性混合体,场景应该也是行为混合体,那么看看这里bounded context有界上下文是否就是场景呢?

下面的SalesContext是继承了DBContext,这与楼主表达的意思一致,我想注意这个SalesContext中除了有Customers等实体模型,也应该存在这些实体相互调用的行为,否则对不起"Sales销售"这个称号,与销售有关的活动需要在这个场景(有界上下文)中表达吧?



续上,不同场景中都有Customer,问题来了,不同场景对Customer要求的字段多少不一样,这不是因为个性应用破坏了共性Customer?



2012-10-19 14:27 "@banq"的内容
这不是因为个性应用破坏了共性Customer? ...

Customer出现了多个版本,有的只需要三个字段,而有的则需要十几个字段,如果解决这个不同场景下同一个模型胖瘦不一样的问题呢?

下面的解决方案体现两种思维的解决办法,教材中是通过静态结构思维方式来解决,根据不同场景创建不同的类,比如顾客名单类CustomerReferenceList;Customer类继承Person类等等。这样设计出来的结果是几个Customer类让人眼花缭乱,产生歧义,其实这也是静态结构性思维的固有缺点。

如果我们换一种思维,认为这是Person在不同场景下扮演不同的角色,从而具备了不同性质字段,那么是否更加优雅和简单灵活呢?



那两个图边界范围,在这个边界内需要用到哪些对象,才能完成需求范围内的业务过程,里面有若干个聚合根,除了数据对象之外,还需要若干的服务,描述业务过程,比如有“订单退货”,如果上下文分别为SalesContext和ReturnsContext,这个过程应该在SalesContext与ReturnsContext反映出来。
订单生成退货
SalesOrder -> SalesContext -> SalesOrderReturnService ->ReturnsContext -> ReturnOrder
退货完成反馈给订单(更新退货数量)
ReturnOrder -> ReturnContext -> ReturnOrderConfirmService -> OrderContext -> SalesOrder
---------------------------------------------------------------------------------------
其实从上一个图来看,因为两个行为的主体是SalesOrder和ReturnOrder都在ReturnsContext下,领域之间交互就比较简单,不需要领域间上下文的交互服务,但是订单退货的是从UI层发起,需要应用层服务定义SalesOrderServie.Return(OrderId, ProductId, Quantity)等


[该贴被clonalman于2012-10-20 08:07修改过]

属性分成多组应该取决于业务,可能对应不同上下文,但并不意味着可以分开,如果要分属多个对象,应该是有对应的业务对象来定义,上面那个“蛇”与“大象”的意思应该是上下文(语境)来避免歧义。。。通过上下文(语境),讲Customer的时候,大家都是知道是“蛇”而不是“大象”,或者是“大象”而不是“蛇”..
[该贴被clonalman于2012-10-20 07:55修改过]

关于有界上下文,从技术架构来看,基本是公说公有理,婆说婆有理,盲人摸象,只摸到了大象的局部而已,既然是领域驱动设计,还得回归领域的实例来说明.


public class Variant
{
public string Code;
public string Name;
public VariantCollection Inclusions;
}

public class Product
{
public string Code;
public string Name;
public ProductCollection Parts;
public VariantCollection Variants
}

class ProductVariant extends Variant
{
ProductCollection Exclusions;
VariantCollection Selections;
VariantCollection Combinations;
}

这是我实际设计模型代码实现大概样子,对产品的生产规格(BOM属性)与销售规格(SKU属性、其他属性)进行抽象,
分别用在生产与销售模块,功能需求上是实现产品BOM与商品SKU等,反映产品结构或商品组合,是两个不同需求,我设计上用同一个模型去实现,为区别不同的应用,设计上很自然的引入上下文场景。
[该贴被clonalman于2012-10-27 17:11修改过]

上述Product虽然在不同场景下的属性是一样的,
但每个属性在不同场景下的业务含义都不一样,这是设计抽象的结果。

不知道有没有这种体会,当我们根据用户需求,分析的场景角色交互行为的后,
匆匆忙忙的进行实现,没有进不一步的设计抽象,功能上也是能实现,但存储的数据都是比较零散的,
在后续做分析决策的业务,就变的相当棘手,有时后需要对数据重新进行清洗整理或者我们的SQL语句异常的复杂。
如果设计做的好话的,原来分散的数据(原来可能在多张表的),可以呈现在相对集中的地方(如一张表中)。
这些集中的数据是不同场景下具有一定的演进关系,做分析决策时就相对容易一点。


[该贴被clonalman于2012-11-06 21:33修改过]

2012-10-27 20:25 "@clonalman"的内容
这些集中的数据是不同场景下具有一定的演进关系 ...

这个问题很有代表性,我以前也有思考,如何设计这些在不同场景下有微小字段区别的对象。

我是这样思考的:

这些有区别的字段有两种类型:
1.和具体场景有关的固有属性,比如BOM属性和SKU属性不同。
2.和场景活动产生的结果状态有关。

第一个是否可以使用组合引用原始Product方式实现,重新创建一个ProductBOM的对象?

第二个因为是业务活动的记录,属于事件-状态这种机制,可以专门设置状态对象作为Product的子对象来实现?


2012-11-07 12:02 "@banq"的内容
第一个是否可以使用组合引用原始Product方式实现,重新创建一个ProductBOM的对象?第二个因为是业务活动的记录,属于事件-状态这种机制,可以专门设置状态对象作为Product的子对象来实现? ...

其实ProductVariant就是生产的BOM的规格描述,Product是产品家族
一个Product和一个ProductVariant实例可以对应一个SKU,
销售的商品SKU属性与生产产品规格有着天然的联系,这也就是我前面说的数据有一定的演进关系.

模型是明确指向,BoundedContext可以做为隐含概念,象Eric书里的DDD例子
模型是抽象指向,可对应多个现实模型,BoundedContext应的该显式描述出来

c代码


class EntityARepository
{
public EntityA GetEntityAById(int id) {
EntityA a = Context.Find<EntityA>(id);
a.OnEvent += context.Handle; //这行代码能否自动实现?
return a;
}

在对象重建实例化的时候,有没有程序自动实现对象内的事件与上下文的方法自动装配的机制,不引入annotation或其他领域不相关的技术或架构元素(Ioc容器除外)
--------------------------------------------------------------------------------
文件配置还是把Entity、BoundedContext也扔到Ioc中?
[该贴被clonalman于2012-12-15 06:39修改过]
[该贴被clonalman于2012-12-15 06:41修改过]

2012-12-15 06:28 "@clonalman"的内容
a.OnEvent += context.Handle; //这行代码能否自动实现? ...

axon:


@Override
public T load(Object aggregateIdentifier, Long expectedVersion) {
T aggregate = doLoad(aggregateIdentifier, expectedVersion);
validateOnLoad(aggregate, expectedVersion);
return CurrentUnitOfWork.get().registerAggregate(aggregate, eventBus, saveAggregateCallback);
}

axon是在AggregateRoot和UnitOfWork这里做文章
.net下,只要实现一个Event Broker应该是能自动装配了,
这样对象里就有了Property、Method和Event了,领域对象就丰满了。
[该贴被clonalman于2013-01-29 05:34修改过]
[该贴被clonalman于2013-01-29 05:38修改过]