2016-03-08 29 views
0

每个类包含约30个方法,其中几乎一半是相同或非常相似。很快我要添加一个与这两个班级处于相同状况的第三班。我觉得维护或改变它是一团糟。我如何重构以避免重复的代码?如何用许多类似的方法重构两个复杂的类?

下面是一个简化版本:

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 VS AMenuProvider和ADefinitionTree VS BDefinitionTree可能是非常不同的实现,但它们提供了许多相同的方法。他们每个人都有一些独特的方法,而另一个没有。

我想过创建一个抽象类并对其进行扩展,但无论在哪里放置menuProvider和树属性,它都显得很丑陋。我不确定是否有任何设计模式或解决方案。请帮助我重构类,以便我可以删除重复的代码。

+1

如果功能相同为什么*不会*基类是一个合理的解决方案? –

+0

@DaveNewton因为剩下的20个不同的方法,如不同的MethodFromA和differentMethodFromB也需要使用字段menuProvider和树,我必须从基类中提供getter方法。每次我召唤一个来自基地的吸气者时,我也必须施展一次,这在我看来很丑陋。 – Alex

+0

然后应该有一个接口来规范'MenuProvider'的功能。 –

回答

0

S.O.L.I.D"S"

的单一职责原则规定,每个模块或 类应该有过的由软件提供的功能 单个部分的责任,这个责任应该由完全 封装班上。所有的服务应该与这个责任范围很窄地对齐 。

"I"

界面偏析原理(ISP)规定,任何客户端应 被迫依赖于它不使用方法[1] ISP将 接口分成更小更具体的接口,因此客户只需知道 对其感兴趣的方法。这种缩小的接口也被称为角色 接口。[2] ISP旨在保持系统解耦,因此更容易重构,更改和重新部署。

"D"

A.高层模块不应该依赖于低级别的模块。 都应该依赖于抽象。 B.抽象不应取决于 的细节。细节应该取决于抽象。

您违反了(至少)OO的这三条神圣规则。 AB应取决于抽象(接口)。同样的方法应该抽象为一个接口,不同的接口方法。 S.O.L.I.D比设计模式更重要。设计模式基于SOLID。先学习一下,你就不会再有像这样的问题了。

0

基本上有两种重用代码的方法(当代码跨两个或多个类复制时)。

  • 继承:如果所有参与类(共享重复的代码)在逻辑上被放入其中,“被”的关系之后不是创建一个基类层次结构,拉在基类中的常用方法,并自定义子类方法。 (如果跨子类的方法实现有变化,请考虑使用模板方法模式。)

  • 组成:如果参与类不遵循“is-a”关系,因此不能放入层次结构中,请创建类并把所有可重用的方法放在那里。在任何想要通过构图重用方法的地方使用该类。

相关问题