锁定老帖子 主题:贫血就贫血,咂地?
精华帖 (1) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2005-11-02
ajoo 写道 充血对象的依赖注入是一个值得关心的问题。因为它的实例化本身不是由容器负责,而它的一些依赖则最好能由容器注射。
spring和pico对此都没有好的解决办法。 所有现行的方案,无一例外都被迫采用了service locator这种不利于单元测试的主动请求组件的方式,同时还增加了对某个具体容器api的绑定。请看: http://forum.iteye.com/viewtopic.php?t=15665&highlight=injection+AOP 大致看了一下你的文章,有几点不同意见: 1。你认为Domain层应该依赖Data Access层,因为Domain层需要调用DA层返回持久化的对象,为了避免双向依赖,你建议DA层最好只返回Domain层的数据,然后由业务对象来负责处理。 hostler同学在前面已经给你指出了,通过Separated Interface完全不存在双向依赖的问题。 因此后面你的很多论述就站不住脚。认为DA不应该依赖业务层的论断也就不成立了。 2。另外,对于BankAccount职责的问题,BankAccount需要知道SMTPService吗?这不是一个好的设计,因为SMTPService怎么看都是一个可选的内容,让BankAccount依赖于它,哪怕是接口也好,都是不好的。因为正如你预测的还可能有WebService等等。 3。即使DomainObject需要依赖于外界服务,也完全不必要那么复杂的玩。 因为这些服务本身不是DomainObject,所以使用简单的IOC就可以注入了。 |
|
返回顶楼 | |
发表时间:2005-11-02
partech 写道 大致看了一下你的文章,有几点不同意见: 1。你认为Domain层应该依赖Data Access层,因为Domain层需要调用DA层返回持久化的对象,为了避免双向依赖,你建议DA层最好只返回Domain层的数据,然后由业务对象来负责处理。 hostler同学在前面已经给你指出了,通过Separated Interface完全不存在双向依赖的问题。 因此后面你的很多论述就站不住脚。认为DA不应该依赖业务层的论断也就不成立了。 谁说我说domain object要依赖da?我明明说是不要。老大, 你读的也太“大致”了吧? 而且hostler说的好像是直接把dao挪到domain层吧?这似乎不是说不存在双向依赖,而是耍赖。你说呢? 也许我没有理解hostler的真正意思。 要不你举个这个separated inerface的例子。要说一个观点最好是“说明”,而不是轻描淡写的“指出”。多少的误解甚至无知都来自于不负责任的“指出”。 partech 写道 2。另外,对于BankAccount职责的问题,BankAccount需要知道SMTPService吗?这不是一个好的设计,因为SMTPService怎么看都是一个可选的内容,让BankAccount依赖于它,哪怕是接口也好,都是不好的。因为正如你预测的还可能有WebService等等。 rich domain如何设计更合理本身不在这个话题之内。smtp只是一个例子,无所谓好不好。我的意思只是说domain object可能需要一个外界的依赖。至于具体什么依赖在你看来是好的例子,就留个填空,你自己填吧。 partech 写道 3。即使DomainObject需要依赖于外界服务,也完全不必要那么复杂的玩。 因为这些服务本身不是DomainObject,所以使用简单的IOC就可以注入了。 麻烦解释(不要“指出”)一下这个简单的IOC如何玩。让我们看看你怎么简单注入。其实,不幸的是,至少有一部分人认为这个注入不简单,想用ioc容器来处理,只不过,他们的方法,比如xiecc的那个方法,在我看来都是违背了依赖注入的原则,因为他们都用了service locator。并且依赖spring的api。 |
|
返回顶楼 | |
发表时间:2005-11-02
ajoo 写道 下面,分析持久层。 肯定是有一个ItemDao了: java代码: interface ItemDao{ Item findById(int id); void update(Item item); } 这里面有一个疑问。这个findById()返回的Item是不是上面业务层的那个Item呢?理想情况应该不是。为什么? 1。业务层的实现肯定会依赖持久层,你这里再弄个反方向依赖,坏味道。 这是啥? |
|
返回顶楼 | |
发表时间:2005-11-02
service代码要依赖dao,但是domain最好不要。
|
|
返回顶楼 | |
发表时间:2005-11-02
ajoo 写道 partech 写道 3。即使DomainObject需要依赖于外界服务,也完全不必要那么复杂的玩。 因为这些服务本身不是DomainObject,所以使用简单的IOC就可以注入了。 麻烦解释(不要“指出”)一下这个简单的IOC如何玩。让我们看看你怎么简单注入。其实,不幸的是,至少有一部分人认为这个注入不简单,想用ioc容器来处理,只不过,他们的方法,比如xiecc的那个方法,在我看来都是违背了依赖注入的原则,因为他们都用了service locator。并且依赖spring的api。 ajoo 写道 public interface Injector{ void inject(Object obj);; } class BankAccountService{ private final Injector injector; private final BankAccountDao dao; BankAccountService(Injector injector, BankAccountDao dao);{ this.injector = injector; this.dao = dao; } BankAccount findAccountById(String id);{ BankAccount acc = dao.getById(id);; injector.inject(acc);; return acc; } } public interface SmtpService{ void send(Object obj);; } class BankAccountService{ private final SmtpService smtpService; private final BankAccountDao dao; BankAccountService(SmtpService smtpService, BankAccountDao dao);{ this.smtpService= smtpService; this.dao = dao; } BankAccount findAccountById(String id);{ BankAccount acc = dao.getById(id);; acc.setSmtpService(smtpService);; return acc; } } 有多大区别? 况且,仅凭你上面的代码,我也实在看不出什么时候调的smtpService。 |
|
返回顶楼 | |
发表时间:2005-11-02
总体上倾向于支持ajoo的观点,Partech好象有点过于纠缠在ajoo谴辞造句的细节上了,不过ajoo一向自诩严谨,为何总是会语焉不详落下把柄呢?
|
|
返回顶楼 | |
发表时间:2005-11-02
ajoo 写道 下面,分析持久层。 肯定是有一个ItemDao了: java代码: interface ItemDao{ Item findById(int id); void update(Item item); } 这里面有一个疑问。这个findById()返回的Item是不是上面业务层的那个Item呢?理想情况应该不是。为什么? 1。业务层的实现肯定会依赖持久层,你这里再弄个反方向依赖,坏味道。 service代码要依赖dao,但是domain最好不要。 业务层依赖于持久层, Item属于业务层,为了避免反向依赖,所以持久层不该返回Item? 还是 Service层依赖于持久层,Service层依赖Domain层,持久层依赖Domain层,Item属于Domain层,Service层,使用持久层返回Item? |
|
返回顶楼 | |
发表时间:2005-11-02
多大的区别?简单的情况当然没啥区别。但是如果依赖很多呢?你看看我那个文章的第二章,可以完全避免这些setXXX, setYYY, setZZZ,你说有区别么?
另外可以问问xiecc,问问hostler,问问这位同学:http://forum.springframework.org/showthread.php?t=19098 为啥他们都不直接注射,而是非要捣那个麻烦? 说实话,我本来就对这种rich domain的设计不感冒。这种被迫setXXX, setYYY本来就很别扭。要照我说,干脆就不这么设计,也就无所谓如何注射的问题了。 但是,我不喜欢,我却不能否认有人喜欢这么做。我给出的方案就是在暂且承认这种设计的合法性,并且认可这个想要统一管理依赖注射的前提下的一个我认为比现有的方法好的方案。 至于你根本不认可这个前提,也无不可。你就直接说你反正根本不会这么设计就成了。对你没用,也许对想要这么做的人有用? |
|
返回顶楼 | |
发表时间:2005-11-02
age0 写道 总体上倾向于支持ajoo的观点,Partech好象有点过于纠缠在ajoo谴辞造句的细节上了,不过ajoo一向自诩严谨,为何总是会语焉不详落下把柄呢?
他啥观点?你支持他啥观点? |
|
返回顶楼 | |
发表时间:2005-11-02
partech 写道 ajoo 写道 下面,分析持久层。 肯定是有一个ItemDao了: java代码: interface ItemDao{ Item findById(int id); void update(Item item); } 这里面有一个疑问。这个findById()返回的Item是不是上面业务层的那个Item呢?理想情况应该不是。为什么? 1。业务层的实现肯定会依赖持久层,你这里再弄个反方向依赖,坏味道。 service代码要依赖dao,但是domain最好不要。 业务层依赖于持久层, Item属于业务层,为了避免反向依赖,所以持久层不该返回Item? 还是 Service层依赖于持久层,Service层依赖Domain层,持久层依赖Domain层,Item属于Domain层,Service层,使用持久层返回Item? 讨论来,讨论去。 接口而已。 不存在谁一定不能依赖谁的说法。 DAO也仅仅一个接口而已,现在问题的焦点似乎在于怎么IOC. 我的观点就是这个问题不是很大的问题,随你怎么玩。 |
|
返回顶楼 | |