锁定老帖子 主题:如何减少子类对超类的依赖——一个设计问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-04-01
如果以后还会新增B3、B4、D、E,那么重构为Decorator是最好的选择,如果以后不会新增这么多类,那么现在的你在担心什么?
|
|
返回顶楼 | |
发表时间:2008-04-01
聚合优于继承,对复杂的结构来说
|
|
返回顶楼 | |
发表时间:2008-04-01
总觉得此帖的作者是没有理解什么设计模式、继承,既然是继承了,又怎么不依赖父类,那你继承干什么,不知所谓。好莱坞原则不是你这个意思吧
|
|
返回顶楼 | |
发表时间:2008-04-01
LZ代码的耦合性太高了。借用C3PO的说法
引用 1. 父类的"go"方法粒度太大。可以把“go”分解成一系列互相独立的protected小方法,让子类调用,“组装”各自所需要的逻辑。
这种方法类似于Spring调用Hibernate的HibernateDaoSupport 引用 2. 如果第一步做不了,说明你的类太monolith,表达的逻辑太多,建议拆分父类并重新考虑继承结构。
LZ你看设计模式的时候一定看过一个叫“单一职能原则”的吧。一个类只做一件事情。 不能为了设计模式而设计模式,所谓的模式是在有大量编码经验基础上总结出来的经验。属于经验之谈,每个都有自己特定的使用环境。 其实我觉得让你的代码保存简约精致就是最好的模式。就是说明明一个System.out.println("Hello, world.");就能解决的问题,不用非要去用什么工厂模式、单例模式、……模式什么的吧。 |
|
返回顶楼 | |
发表时间:2008-04-01
还是少用继承为妙,如果是大系统的话
建议多用用组合的方式把 |
|
返回顶楼 | |
发表时间:2008-04-01
先不说技术,我感觉讨论的氛围太差了吧....
|
|
返回顶楼 | |
发表时间: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绝不会比你现在这种方式更“重”。另外所谓的好莱坞原则是该用到父子类上的吗? |
|
返回顶楼 | |
发表时间:2008-04-03
为什么有的人 要把 楼主 要表达的东西和 这个那个的设计模式 来对比,要说谁优谁劣。
这样没有必要。 设计模式无非是代码的优美有效的组织形式。 楼主 提出了一个 模式(或者说一个模式片断),并对这个模式片段进行了阐述。这对以后真实的设计有很好的参考意义。 一定要和那个设计模式模式比的话,我觉得范了个错误,因为模式是设计有效参考,但不是来套设计的(当然有些模式的确有很好的可套用性)。 可能大家的疑虑是 这样的一个设计模式片段,在实际设计中有什么应用,应用的方式是什么? 那是另一个问题,不见得要楼主一起给出。 (模式的提出和模式的应用,就好像 电脑 和 电脑的应用 一样,造电脑的人 不见得要知道 电脑应用在什么方面效益最好) 支持楼主的独立见解!支持楼主!!! |
|
返回顶楼 | |
发表时间:2008-04-03
LZ的设计企图在每个子类中对父类方法调用进行拦截处理,AOP是最合适的,其次就是运用decorator模式来实现。现在的设计不具备可扩展性,每加一个子类,都会造成不小修改,系统变大后,可读性也急剧变差。
|
|
返回顶楼 | |
发表时间: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的初始化等问题,这里只是简单起见介绍一个思路 |
|
返回顶楼 | |