Java 如何用许多相似的方法重构两个复杂的类?
每个类包含大约30个方法,其中几乎一半是相同或非常相似的。很快我将添加第三个类,它与这两个类处于相同的情况。我觉得维护或更改它们是一团糟。如何重构以避免重复代码 以下是一个简化版本:Java 如何用许多相似的方法重构两个复杂的类?,java,design-patterns,refactoring,Java,Design Patterns,Refactoring,每个类包含大约30个方法,其中几乎一半是相同或非常相似的。很快我将添加第三个类,它与这两个类处于相同的情况。我觉得维护或更改它们是一团糟。如何重构以避免重复代码 以下是一个简化版本: public class A extends ContentPanel{ private AMenuProvider menuProvider; private ADefinitionTree tree; public void sameMethod1(){ ..
public class A extends ContentPanel{
private AMenuProvider menuProvider;
private ADefinitionTree tree;
public void sameMethod1(){
...
menuProvider.do();
tree.doSomething();
...
}
public void sameMethod2(){
...
menuProvider.do();
tree.doSomething();
...
}
public void differentMethodFromA(){
... // uses menuProvider and tree
}
...
// 10 similar methods and 20 different methods
}
public class B extends ContentPanel{
private BMenuProvider menuProvider;
private BDefinitionTree tree;
public void sameMethod1(){
...
menuProvider.do();
tree.doSomething();
...
}
public void sameMethod2(){
...
menuProvider.do();
tree.doSomething();
...
}
public void differentMethodFromB(){
... // uses menuProvider and tree
}
...
// 10 similar methods and 20 different methods
}
注意:BMenuProvider与AMenuProvider、ADefinitionTree与BDefinitionTree可能是非常不同的实现,但它们提供了许多相同的方法。它们中的每一个都有一些独特的方法,而另一个则没有
我曾想过创建一个抽象类并对其进行扩展,但无论我将menuProvider和tree属性放在哪里,它看起来都很难看。我不确定是否有任何设计模式或解决方案。请帮助我重构这些类,以便删除重复的代码。中:
单一责任原则规定每个模块或类
应负责功能的单个部分
由软件提供,并且该责任应完全由
由类封装。它的所有服务应该紧密结合在一起
我有这个责任
:
接口隔离原则(ISP)规定,任何客户端都不应
被迫依赖于它不使用的方法。[1]ISP拆分
将非常大的接口划分为更小和更具体的接口,因此
客户只需要知道所使用的方法
他们很感兴趣。这种缩小的接口也称为角色
接口。[2]ISP旨在保持系统解耦,从而
更易于重构、更改和重新部署
:
A.高级模块不应依赖于低级模块。二者都
应该依赖于抽象。B.抽象不应依赖于
细节。细节应该取决于抽象
你(至少)违反了OO的这三条神圣规则<代码>A和
B
应该依赖于抽象(接口)。相同的方法应该抽象为一个接口,不同的方法应该抽象为不同的接口。S.O.L.I.D比设计模式更基本。设计模式基于实体。首先学习它,你就不会再有这样的问题了。重用代码基本上有两种方法(当代码在两个或多个类之间重复时)
- 继承:如果所有参与的类(共享重复的代码)在逻辑上都被放入一个层次结构中,在这个层次结构中遵循“is-a”关系,而不是创建一个基类,那么在基类中拉取公共方法,并自定义子类方法。(如果方法实现在子类之间存在差异,请考虑使用模板方法模式。)
- 组合:如果参与的类不遵循“is-a”关系,因此无法放置在层次结构中,则创建一个类并将所有可重用方法放置在该类中。只要您想通过组合重用方法,就可以使用该类
MenuProvider
功能。@Alex为什么需要强制转换?您可以在基类上使用泛型。@JnRouvignac我的意思是,从子类中调用getMenuProvider()方法后,我必须将其强制转换为AmenuUpVider或BMenuProvider