实践中如何处理这种业务方法?

12-06-21 xxooxx

需求描述是这样的:crm系统中。“潜在客户”归档后变为“客户”。这个“归档”需要创建一个“客户”,并删除对应的“潜在客户”。新的“客户”对象的属性值多数是来源于原来的“潜在客户对象”。

这个Archive是一个业务方法,那么它应该写在domain层中还是service(应用)层中?

如果是在domain层中,伪代码如下:

public class PreCustomer

{

public void Archive()

{

Customer customer = new Customer();

customer.xx = xx;

customer.yy = this.yy;

// 其他操作。。。

CustomerDao.Add(cutomer);

PreCustomerDao.Delete(this);

}

}

如果是在service层中,伪代码如下:

public class CustomerService

{

public void Archive(int preCustomerId)

{

PreCustomer preCustomer = ProCustomer.GetById(preCustomerId);

Customer customer = Customer.Create(preCustomer);

// 其他操作。。。

CustomerDao.Add(cutomer);

PreCustomerDao.Delete(preCustomer );

}

}

这两种方式,都能完成任务,看似也差不多。但重要的是Archive是一个业务方法,所以我倾向于放到domain中,既第一种方式。但是放到domain中问题是domain模型被dao污染了,而且这时执行Archive后PreCustomer成了一个悬浮对象了。第二种看似没什么问题,但是这种业务方法到底service层,将导致类似情况对service层不断添加代码,导致service过于厚重,从而退化成事务脚本模式了

想看看大家是怎么理解这个问题了。谢谢

                   

8
banq
2012-06-21 21:37
我的建议当然应该是domain,我是通过领域事件来驱动悬浮对象持久化。

或者可以通过dci或mixin将持久化注入给领域对象,而且不会污染领域。

chanball
2012-06-21 22:27
2012-06-21 21:37 "@banq"的内容
或者可以通过DCI或mixin将持久化注入给领域对象,而且不会污染领域。 ...

这种方式的话,需要多出额外的接口,而且只能通过接口去调用,感觉不像是在用领域对象

banq
2012-06-22 07:19
不好意思,我想到这是对将客户实体转为另外客户实体的过程,类似银行转帐,从一个账户转账到另外一个账户。

这个过程应该是一种服务。

xxooxx
2012-06-22 12:03
和银行转账不一样吧?转账涉及的是两个对象的金额属性的变化。而这个需求是对象本身的转换。

而且,我觉得转账这个所谓的领域服务设计也是代码重构的结果,转账本身也是账户对象的职责,试想如果转账规则依赖于账户的私有属性时,放在转账服务中的转账实现如何去访问账户的私有属性?所以我任务转账服务(或者说领域服务)应该是代码重构的结果,应该是被领域实体调用的,供领域实体完成职责所需的。是领域实体依赖领域服务,而不是领域服务依赖领域实体,因此,领域服务被上层(应用层)调用是不应该的,不然成了一种更细粒度的应用层代码了。而应用层代码主要是领域模型的外观层。

您是怎么理解的呢?

猜你喜欢
4Go 1 2 3 4 下一页