论坛首页 Java企业应用论坛

[TSS discussion] Spring 2.0 vs. the Anemic Domain Model

浏览 12511 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-12-14  
最开始是Craig Walls (Spring In Action作者之一) 在自己的BLOG上写了这篇文章,当时就有人在他的BLOG上直接讨论他的例子是不恰当的。结果到了第二天有人把这个BLOG放到了TSS上,引出了不少有趣而有价值的讨论。

http://www.theserverside.com/news/thread.tss?thread_id=38047
   发表时间:2005-12-14  
貌似 Craig Walls 的原意是讲解一下spring 2.0 的 post-instantiation注入,可惜一不小心把anemic domain model牵扯进来了,结果自然又少不了一番争论。。。。
0 请登录后投票
   发表时间:2005-12-15  
好, 又有一个机会兜售我的Nuts。这个热闹一定要掺和一下。

针对这个讨论,我写了一个wiki:
http://docs.codehaus.org/display/YAN/Simple+Rich+Domain+Injection

看看比起spring的rocket science如何。
0 请登录后投票
   发表时间:2005-12-15  
很多时候,优秀的框架往往束缚住速度和简单的原则。
现在的J2ee开发,远远达不到高质量,高速度开发的效果。
我觉得其中很重要的一个原因就是广泛采用框架带来了一个负面效果:那就是越来越深的依赖于某种框架的某种构架体系。
而框架出于兼容,可扩展的目的,提供越来越多的插入点和配置点,因为要吸取广而泛之得各种各样的复杂需求,导致在软件开发易用性上没有得到太多深入的发展。
另外一方面,依赖框架导致很多活跃的思想得实现遇到了框架所提供的基础构架方面的阻碍。 正如Spring给贫血模型提供了充分的依据,很多人很多时候往往越来越臣服于可爱而又广泛的领域模型。
0 请登录后投票
   发表时间:2005-12-15  
ajoo 写道
好, 又有一个机会兜售我的Nuts。这个热闹一定要掺和一下。

针对这个讨论,我写了一个wiki:
http://docs.codehaus.org/display/YAN/Simple+Rich+Domain+Injection

看看比起spring的rocket science如何。


ajoo,你的解决方案简单来说,就是不要new XXX,而是XXXFactory。不过blog作者在一开始就点明了很多情况下我们需要对new出来的对象进行DI。举例来说,以我们常用的Hibernate/Spring/Webwork的架构,实体类基本上不是在我们的应用程序中显式的通过new得到的,而是通过Hibernate,Webwork这样的框架在底层运行的时候隐式的得到的,你总不能去改Hibernate/Webwork的代码来适配你的XXXFactory吧?

例如从数据库得到对象  User user = (User) session.load(id);
Hibernate有一个隐式的new UserProxy()操作,返回给你一个UserProxy的对象,这时候你怎么织入XXXFactory?

再例如一个增加用户的页面提交,request paramters 是 user.name=robbin,Webwork使用ognl表达式调用,隐含了:
User user = new User(); user.setName("robbin");
这样的操作,你又如何织入UserFactory?
0 请登录后投票
   发表时间:2005-12-15  
引用

Anemic is about domain logic
Posted by: Martin Fowler on December 13, 2005 in response to Message #193682 3 replies in this thread
Just to clarify (and I've added a para to the bliki entry too) my definition of an Anemic Domain Model is about the domain objects lacking domain logic. Persistence and/or Presentation logic are an entirely separate issue. I've seen (and helped build) good, rich domain models that have no connections to presentation or data sources and they worked well.

On the real issue of the article, there is value in injecting service objects into domain objects. Better examples would involve gateways to external systems that would be invoked due to the flow of the business logic.

老马就贫血的DomainModel作了些澄清。原来的bliki也作了update http://www.martinfowler.com/bliki/AnemicDomainModel.html

等俺研究好了EclipseRCP,再杀回来。赫赫
0 请登录后投票
   发表时间:2005-12-15  
robbin 写道
ajoo 写道
好, 又有一个机会兜售我的Nuts。这个热闹一定要掺和一下。

针对这个讨论,我写了一个wiki:
http://docs.codehaus.org/display/YAN/Simple+Rich+Domain+Injection

看看比起spring的rocket science如何。


ajoo,你的解决方案简单来说,就是不要new XXX,而是XXXFactory。不过blog作者在一开始就点明了很多情况下我们需要对new出来的对象进行DI。举例来说,以我们常用的Hibernate/Spring/Webwork的架构,实体类基本上不是在我们的应用程序中显式的通过new得到的,而是通过Hibernate,Webwork这样的框架在底层运行的时候隐式的得到的,你总不能去改Hibernate/Webwork的代码来适配你的XXXFactory吧?

例如从数据库得到对象  User user = (User) session.load(id);
Hibernate有一个隐式的new UserProxy()操作,返回给你一个UserProxy的对象,这时候你怎么织入XXXFactory?

再例如一个增加用户的页面提交,request paramters 是 user.name=robbin,Webwork使用ognl表达式调用,隐含了:
User user = new User(); user.setName("robbin");
这样的操作,你又如何织入UserFactory?

你没看明白。我是说用factory来代替直接new。而从hibernate返回出来的对象是用proxy来注入。也就是说,原始的CustomerDao直接返回Hibernate生成的那个对象,然后有一个CustomerDao的dynamic proxy负责注射依赖。
那个<inject>就是干这个用的。

总的来说,从第三方库出来的对象都用dynamic proxy来注射,同时程序自己要生成对象就用factory。只要保证service使用的都是接口,容器就可以把依赖注射好。

你看这个CustomerService,它用了CustomerDao和CustomerFactory,CustomerDao封装了Hibernate,CustomerFactory代替"new"。从这两个接口返回的Customer对象都是已经把依赖注射好的。
public class CustomerServiceImpl implements CustomerService {
  public CustomerServiceImpl(); {}  
  public void loadAndDoBusiness(Integer id); {
    Customer original = dao.load(id);;    
    Customer duplicate = factory.createCustomer();;
    duplicate.setId(original.getId(); + 1);;
    duplicate.setName(original.getName(););;
    
    original.setName("Michael Walls");;
    
    original.doBusiness();;
    duplicate.doBusiness();;
  }
  
  private final CustomerDao dao;
  private final CustomerFactory factory;
  public CustomerServiceImpl(CustomerDao dao, CustomerFactory factory);{
    this.dao = dao;
    this.factory = factory;
  }
}
0 请登录后投票
   发表时间:2005-12-15  
ajoo 写道
robbin 写道
ajoo 写道
好, 又有一个机会兜售我的Nuts。这个热闹一定要掺和一下。

针对这个讨论,我写了一个wiki:
http://docs.codehaus.org/display/YAN/Simple+Rich+Domain+Injection

看看比起spring的rocket science如何。


ajoo,你的解决方案简单来说,就是不要new XXX,而是XXXFactory。不过blog作者在一开始就点明了很多情况下我们需要对new出来的对象进行DI。举例来说,以我们常用的Hibernate/Spring/Webwork的架构,实体类基本上不是在我们的应用程序中显式的通过new得到的,而是通过Hibernate,Webwork这样的框架在底层运行的时候隐式的得到的,你总不能去改Hibernate/Webwork的代码来适配你的XXXFactory吧?

例如从数据库得到对象  User user = (User) session.load(id);
Hibernate有一个隐式的new UserProxy()操作,返回给你一个UserProxy的对象,这时候你怎么织入XXXFactory?

再例如一个增加用户的页面提交,request paramters 是 user.name=robbin,Webwork使用ognl表达式调用,隐含了:
User user = new User(); user.setName("robbin");
这样的操作,你又如何织入UserFactory?

你没看明白。我是说用factory来代替直接new。而从hibernate返回出来的对象是用proxy来注入。也就是说,原始的CustomerDao直接返回Hibernate生成的那个对象,然后有一个CustomerDao的dynamic proxy负责注射依赖。
那个<inject>就是干这个用的。

总的来说,从第三方库出来的对象都用dynamic proxy来注射,同时程序自己要生成对象就用factory。只要保证service使用的都是接口,容器就可以把依赖注射好。

你看这个CustomerService,它用了CustomerDao和CustomerFactory,CustomerDao封装了Hibernate,CustomerFactory代替"new"。从这两个接口返回的Customer对象都是已经把依赖注射好的。
public class CustomerServiceImpl implements CustomerService {
  public CustomerServiceImpl(); {}  
  public void loadAndDoBusiness(Integer id); {
    Customer original = dao.load(id);;    
    Customer duplicate = factory.createCustomer();;
    duplicate.setId(original.getId(); + 1);;
    duplicate.setName(original.getName(););;
    
    original.setName("Michael Walls");;
    
    original.doBusiness();;
    duplicate.doBusiness();;
  }
  
  private final CustomerDao dao;
  private final CustomerFactory factory;
  public CustomerServiceImpl(CustomerDao dao, CustomerFactory factory);{
    this.dao = dao;
    this.factory = factory;
  }
}

nothing ......
这么多言语,我实在看不出有什么新的东西,也没有什么可以鼓舞人心的东西。
还是套用一句话:老瓶装旧酒,外加一个新标签。
除了IOC ,IOC,Factory ,Factory还是IOC....Factory ....

如果仅仅是IOC,Factory,通过Factory获取Proxy对象,OK,please stop .
Spring已经够可爱的啦,够cool了,再来这么多围绕这个体系的框架,负面效果要高于正面效果。
0 请登录后投票
   发表时间:2005-12-15  
不知道火尸同学在说些什么。

spring那个根本就不是ioc/factory。它是aop+annotation+对框架的依赖。

我那个自然是旧酒(我认为oo, ioc就足够了,没必要不要喝什么新酒),spring倒不是。你可以不喜欢,但是连区别都看不出来就糗了一点。
0 请登录后投票
   发表时间:2005-12-15  
firebody 写道

nothing ......
这么多言语,我实在看不出有什么新的东西,也没有什么可以鼓舞人心的东西。
还是套用一句话:老瓶装旧酒,外加一个新标签。
除了IOC ,IOC,Factory ,Factory还是IOC....Factory ....

如果仅仅是IOC,Factory,通过Factory获取Proxy对象,OK,please stop .
Spring已经够可爱的啦,够cool了,再来这么多围绕这个体系的框架,负面效果要高于正面效果。


Nod, 从 ajoo 的帖子里, 没看出换掉 spring 能得到什么好处
0 请登录后投票
论坛首页 Java企业应用版

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