论坛首页 Java企业应用论坛

Domain Object贫血vs富血(DDD)和spring roo到ruby的扯淡

浏览 42317 次
该帖已经被评为良好帖
作者 正文
   发表时间:2011-04-18  
很喜欢这类文章 LZ威武

不过不大明白的是。LZ已经说了。 富血模型对复杂事务的支持不大好, 但是LZ又说贫血模型适合做简单的业务。 这是不是冲突了?

我觉得“复杂的业务”很多时候都是多个领域对像之间的交互,这之间肯定会涉及事务。所以应该是贫血模型适合做复杂原业务。
0 请登录后投票
   发表时间:2011-04-18   最后修改:2011-04-18
fireflyc 写道
哎,看了楼主的介绍我觉得,楼主对领域驱动设计认识似乎是有问题的,而且我感觉基本上很多人都是存在这样的一个误区。

认为service和entity和DAO合并在一起,就是领域驱动了,比如之前是
Student,StudentDAO(或者泛型DAO),StudentService现在只有一个Student来干所有的事情。

我觉得持有这种观点的人是对DDD的理解有问题的,DDD中最为突出的5辆马车,Entity,Value Object,Factory,Service,Repository,这里可是也有entity也有vo,也有service的。只此一例来证明楼主对DDD的理解有偏差。


很同意你的观点,貌似现在很多人认为  service和entity和DAO合并在一起,就是领域驱动了


downpour 写道


任何的开发方法和模式,都不能和程序开发中最基本的最佳实践相违背。在Java中,让Domain Object和Service Layer过度膨胀都是错误做法。只有两者结合,才能写出可维护的代码来。程序员在这里需要权衡的,是哪些逻辑应该放在Domain Object里面,哪些逻辑应该放在Service Layer中。


老大说的很到位,非常同意。DDD更加关注职责划分。Domain Object有什么,Service Layer有什么,只有职责都划分清楚了,才能弄的清楚。当然DDD还有其他方面。
0 请登录后投票
   发表时间:2011-04-18  
IcyFenix 写道
downpour 写道
一个没写过超过1000w行代码的人,我认为连说OO的资格都没有。


你是不是多打了一两个零?
这个世界上有多少人能写过超过1000w行代码?

作为一个深度的OO粉丝,我一般用写过多少个类来计算代码量。
而那些用过程化程序员则依然用行数来计算。
一定会有很多过程化程序员来告诉我类的长度是多变的。正如行的长度也是多变的,你是否曾觉得计算字符个数更合理?
一个完美主义者写出来的类的大小一般是体型不大不小的,如果一开始不是,重构以后就是了。
0 请登录后投票
   发表时间:2011-04-18  
下面是一些示例代码,
//以下是UI层代码
@Component
public class SomeAction {
    private SomeApp someApp;
    
    private String id;
    
    public String execute() {
        try {
            this.someApp.someBusinessMethod(this.id);
            return "success";
        } catch (SomeBusinessException e) {
            ...
            return "fail";
        }
        
    }
    
    @Autowired
    public void setSomeApp(SomeApp someApp) {
        this.someApp = someApp;
    }
    
    ...
}

//以下是应用层代码
@Component
public class SomeApp {
    private SomeRepository someRepository;
    
    public void someBusinessMethod(String id) {
        SomeEntity someEntity = this.someRepository.findById(id)
        someEntity.executeSomeBusiness();
    }

    @Autowired
    public void setSomeRepository(SomeRepository someRepository) {
        this.someRepository = someRepository;
    }
}

//以下是领域层代码
public interface SomeEntity {
    public void executeSomeBusiness();
}

public class SomeEntityImpl implements SomeEntity {
    private SomeTable someTable;
    
    private SomeRepository someRepository;
    
    public SomeEntityImpl(SomeTable someTable) {
        this.someTable = someTable;
    }
    
    public void executeSomeBusiness() {
        this.someTable.setSomeAttribute("someValue");
        ...
        
        this.someRepository.update(this);
    }
    
    @Autowired
    public void setSomeRepository(SomeRepository someRepository) {
        this.someRepository = someRepository;
    }
    
    public SomeTable getSomeTable() {
        return this.someTable;
    }
    
}

@Component
public class SomeRepository implements ApplicationContextAware {
    private SomeDao someDao;
    
    private ApplicationContext applicationContext;
    
    public SomeEntity findById(String id) {
        SomeTable someTable = this.someDao.findById(id);
        SomeEntityImpl someEntityImpl = new SomeEntityImpl(someTable);
        this.applicationContext.getAutowireCapableBeanFactory().autowireBean(someEntityImpl);
        return someEntityImpl;
    }
    
    public void update(SomeEntity someEntity) {
        SomeEntityImpl someEntityImpl = (SomeEntityImpl) someEntity;
        this.someDao.update(someEntityImpl.getSomeTable()));
    }
    
    @Autowired
    public void setSomeDao(SomeDao someDao) {
        this.someDao = someDao;
    }
    
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

//以下是基础设施层代码
@Entity
@Table(name = "some_table")
public class SomeTable {
    @Id
    private String id;
    
    ...
}

@Component
public class SomeDao extends HibernateDaoSupport{
    ...
}



分层必然会使某些代码变得麻烦,但是,我觉得当领域足够复杂的时候,是有必要牺牲的。
0 请登录后投票
   发表时间:2011-04-18  
idle_sun 写道
很喜欢这类文章 LZ威武

不过不大明白的是。LZ已经说了。 富血模型对复杂事务的支持不大好, 但是LZ又说贫血模型适合做简单的业务。 这是不是冲突了?

我觉得“复杂的业务”很多时候都是多个领域对像之间的交互,这之间肯定会涉及事务。所以应该是贫血模型适合做复杂原业务。


DDD并不会导致对事务支持不好。事务边界的划分本来就不适合于放在领域层,而应该放在上面的应用层。我听着“富血模型”这四个字就觉得很别扭,就好像富血模型和贫血模型就是两种不同的设计风格,都是正确的一样。其实要做DDD就无所谓富血,贫血,因为贫血根本就违背了面向对象和DDD,DDD从来都不贫血。我也写过好多贫血的代码,但是我现在省悟了,我要DDD,寻找领域模型,用模型驱动代码,抛弃贫血模型!
0 请登录后投票
   发表时间:2011-04-18  
itstarting 写道
引用

3.对于简单的软件,使用领域模型,显得有些杀鸡用牛刀了。


我到觉得简单的软件用领域模型更方便点。

+1
0 请登录后投票
   发表时间:2011-04-18  
peterwei 写道
fireflyc 写道
哎,看了楼主的介绍我觉得,楼主对领域驱动设计认识似乎是有问题的,而且我感觉基本上很多人都是存在这样的一个误区。

认为service和entity和DAO合并在一起,就是领域驱动了,比如之前是
Student,StudentDAO(或者泛型DAO),StudentService现在只有一个Student来干所有的事情。

我觉得持有这种观点的人是对DDD的理解有问题的,DDD中最为突出的5辆马车,Entity,Value Object,Factory,Service,Repository,这里可是也有entity也有vo,也有service的。只此一例来证明楼主对DDD的理解有偏差。

我承认我对DDD了解不深。那么,DDD应该是吧数据和逻辑放在一起吧?service层应该不管逻辑的事吧,应该只是浅浅的一层。那么dao,service是可有可无吧,从spring roo可以看到一斑。如果你有DDD实践经验,那么你认为DDD在国内是否已经成熟,是否可以在实际的项目中推广了?推广的难度是什么?为什么大家还在用贫血的模式?



可以先这样理解DDD,它是一种设计方法,与传统的面向数据库设计对立的方法。当面对一个系统的时候不应该想到的是有哪些表,先折腾数据库结构;这种设计方法只能让所有的业务逻辑更加凌乱系统模块各个都紧密的耦合在一起。DDD的做法是先进行系统的分析,识别出一些对象,Entity VO Service Repository之类的,其实就是一个为对象分配职责的过程,注意这个中间不涉及到任何数据库相关的东西,没有表结构的概念。所以重要的问题不在于用的是什么roo还是ruby之类的,重要的是你的设计是否真正的做到了不是以数据库为中心的设计,这个才是DDD真正的意义所在。
0 请登录后投票
   发表时间:2011-04-18  
我只说一句:面向真实业务的对象...
其他的神马都是浮云
0 请登录后投票
   发表时间:2011-04-18  
fireflyc 写道
peterwei 写道
fireflyc 写道
哎,看了楼主的介绍我觉得,楼主对领域驱动设计认识似乎是有问题的,而且我感觉基本上很多人都是存在这样的一个误区。

认为service和entity和DAO合并在一起,就是领域驱动了,比如之前是
Student,StudentDAO(或者泛型DAO),StudentService现在只有一个Student来干所有的事情。

我觉得持有这种观点的人是对DDD的理解有问题的,DDD中最为突出的5辆马车,Entity,Value Object,Factory,Service,Repository,这里可是也有entity也有vo,也有service的。只此一例来证明楼主对DDD的理解有偏差。

我承认我对DDD了解不深。那么,DDD应该是吧数据和逻辑放在一起吧?service层应该不管逻辑的事吧,应该只是浅浅的一层。那么dao,service是可有可无吧,从spring roo可以看到一斑。如果你有DDD实践经验,那么你认为DDD在国内是否已经成熟,是否可以在实际的项目中推广了?推广的难度是什么?为什么大家还在用贫血的模式?



可以先这样理解DDD,它是一种设计方法,与传统的面向数据库设计对立的方法。当面对一个系统的时候不应该想到的是有哪些表,先折腾数据库结构;这种设计方法只能让所有的业务逻辑更加凌乱系统模块各个都紧密的耦合在一起。DDD的做法是先进行系统的分析,识别出一些对象,Entity VO Service Repository之类的,其实就是一个为对象分配职责的过程,注意这个中间不涉及到任何数据库相关的东西,没有表结构的概念。所以重要的问题不在于用的是什么roo还是ruby之类的,重要的是你的设计是否真正的做到了不是以数据库为中心的设计,这个才是DDD真正的意义所在。

赞同,就是这个意思!
0 请登录后投票
   发表时间:2011-04-18  
IcyFenix 写道
peterwei 写道
IcyFenix 写道
downpour 写道
一个没写过超过1000w行代码的人,我认为连说OO的资格都没有。


你是不是多打了一两个零?
这个世界上有多少人能写过超过1000w行代码?

1000w,确实是一个很大的概念。我承认我没有达到。


这不是很大的概念,是一个基本不可能完成的任务。

即使你非常勤奋,每天写300行代码,一年365天不休息,从刚刚出生0岁就开始敲键盘,也要敲到100岁才能写完1000w行代码。

哈哈
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics