论坛首页 Java企业应用论坛

如何减少子类对超类的依赖——一个设计问题

浏览 11713 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-04-01  
如果以后还会新增B3、B4、D、E,那么重构为Decorator是最好的选择,如果以后不会新增这么多类,那么现在的你在担心什么?
0 请登录后投票
   发表时间:2008-04-01  
聚合优于继承,对复杂的结构来说
0 请登录后投票
   发表时间:2008-04-01  
总觉得此帖的作者是没有理解什么设计模式、继承,既然是继承了,又怎么不依赖父类,那你继承干什么,不知所谓。好莱坞原则不是你这个意思吧
0 请登录后投票
   发表时间:2008-04-01  
LZ代码的耦合性太高了。借用C3PO的说法
引用
1. 父类的"go"方法粒度太大。可以把“go”分解成一系列互相独立的protected小方法,让子类调用,“组装”各自所需要的逻辑。

这种方法类似于Spring调用Hibernate的HibernateDaoSupport
引用
2. 如果第一步做不了,说明你的类太monolith,表达的逻辑太多,建议拆分父类并重新考虑继承结构。

LZ你看设计模式的时候一定看过一个叫“单一职能原则”的吧。一个类只做一件事情。

不能为了设计模式而设计模式,所谓的模式是在有大量编码经验基础上总结出来的经验。属于经验之谈,每个都有自己特定的使用环境。
其实我觉得让你的代码保存简约精致就是最好的模式。就是说明明一个System.out.println("Hello, world.");就能解决的问题,不用非要去用什么工厂模式、单例模式、……模式什么的吧。
0 请登录后投票
   发表时间:2008-04-01  
还是少用继承为妙,如果是大系统的话
建议多用用组合的方式把
0 请登录后投票
   发表时间:2008-04-01  
先不说技术,我感觉讨论的氛围太差了吧....
0 请登录后投票
   发表时间:2008-04-02  
撇开模式什么不要谈,我觉得lz那个代码里面子类B根本没法避免调用父类A的方法。按照lz的意图,执行B.go,是不是在call父类A的方法呢? 另外关于子类调用父类方法会照成循环依赖的说法如何而来? 依赖是对的,不知道怎么是循环了依赖了。

就算lz这样的做法是避免所谓的循环依赖,但是lz真的是觉得这种继承真的“清晰和简洁”吗? A的go前后是prepare()和cleanup(),B中又增减了run,假如你又需要新的动作,那么子类里最后到底有多少这种差异性的方法? lz也说假如有D,E。So,清晰性和简洁性都是无从谈起。不仅仅是类爆炸了,方法也在爆炸。

当然在没有知道lz所面对的到底是一种什么样的应用场景下,说decorator可以搞定也有些不太合适。所以建议lz重新考虑下自己的应用需求和设计。你的这些BCDE到底和A应不应是种继承关系?lz到底需要的一种树形结构还是别的什么? 因为我看lz的继承只是为了从父类那里继承个方法。

如果真的是继承关系,那么到底是不是该有对象自己决定该怎么做,还是把那些go啊run转交给别的对象。

其实lz拒绝decorator的理由并不充分,使用decorator绝不会比你现在这种方式更“重”。另外所谓的好莱坞原则是该用到父子类上的吗?



0 请登录后投票
   发表时间:2008-04-03  
为什么有的人 要把 楼主 要表达的东西和 这个那个的设计模式 来对比,要说谁优谁劣。
这样没有必要。 设计模式无非是代码的优美有效的组织形式。

楼主 提出了一个 模式(或者说一个模式片断),并对这个模式片段进行了阐述。这对以后真实的设计有很好的参考意义。

一定要和那个设计模式模式比的话,我觉得范了个错误,因为模式是设计有效参考,但不是来套设计的(当然有些模式的确有很好的可套用性)。

可能大家的疑虑是 这样的一个设计模式片段,在实际设计中有什么应用,应用的方式是什么?

那是另一个问题,不见得要楼主一起给出。
(模式的提出和模式的应用,就好像 电脑 和 电脑的应用 一样,造电脑的人 不见得要知道 电脑应用在什么方面效益最好)

支持楼主的独立见解!支持楼主!!!
0 请登录后投票
   发表时间:2008-04-03  
LZ的设计企图在每个子类中对父类方法调用进行拦截处理,AOP是最合适的,其次就是运用decorator模式来实现。现在的设计不具备可扩展性,每加一个子类,都会造成不小修改,系统变大后,可读性也急剧变差。
0 请登录后投票
   发表时间:2008-04-04  
就事论事,这个需求可以这样做,直接在文本编辑器写的,简单意思到就行
首先有接口
IGoAroundInterceptor
before();
after();

AGoAroundInterceptor implements IGoAroundInterceptor

A类

go() {
	IGoAroundInterceptor interceptorget = getGoAroundInterceptor()
	interceptorget.before()
	run()
	interceptorget.after()
}
abstract run();
IGoAroundInterceptor getGoAroundInterceptor() {
	return AGoAroundInterceptor.INSTANCE;//简单起见
}

要增加A的子类B,可先增加
BGoAroundInterceptor extends AGoAroundInterceptor

before() {
	super.before();
	.....//special before
}
after() {
	.....//special after
	super.after();
}


B类
run() {

}
IGoAroundInterceptor getGoAroundInterceptor() {
	return BGoAroundInterceptor.INSTANCE;
}

对B的子类C类似,而且CGoAroundInterceptor可以决定before/after的策略,可以继承AGoAroundInterceptor也可以继承BGoAroundInterceptor,非常自由

实际应用中可能还要考虑IGoAroundInterceptor的初始化等问题,这里只是简单起见介绍一个思路
0 请登录后投票
论坛首页 Java企业应用版

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