Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何用许多相似的方法重构两个复杂的类?_Java_Design Patterns_Refactoring - Fatal编程技术网

Java 如何用许多相似的方法重构两个复杂的类?

Java 如何用许多相似的方法重构两个复杂的类?,java,design-patterns,refactoring,Java,Design Patterns,Refactoring,每个类包含大约30个方法,其中几乎一半是相同或非常相似的。很快我将添加第三个类,它与这两个类处于相同的情况。我觉得维护或更改它们是一团糟。如何重构以避免重复代码 以下是一个简化版本: public class A extends ContentPanel{ private AMenuProvider menuProvider; private ADefinitionTree tree; public void sameMethod1(){ ..

每个类包含大约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与AMenuProvider、ADefinitionTree与BDefinitionTree可能是非常不同的实现,但它们提供了许多相同的方法。它们中的每一个都有一些独特的方法,而另一个则没有

我曾想过创建一个抽象类并对其进行扩展,但无论我将menuProvider和tree属性放在哪里,它看起来都很难看。我不确定是否有任何设计模式或解决方案。请帮助我重构这些类,以便删除重复的代码。

中:

单一责任原则规定每个模块或类 应负责功能的单个部分 由软件提供,并且该责任应完全由 由类封装。它的所有服务应该紧密结合在一起 我有这个责任

:

接口隔离原则(ISP)规定,任何客户端都不应 被迫依赖于它不使用的方法。[1]ISP拆分 将非常大的接口划分为更小和更具体的接口,因此 客户只需要知道所使用的方法 他们很感兴趣。这种缩小的接口也称为角色 接口。[2]ISP旨在保持系统解耦,从而 更易于重构、更改和重新部署

:

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


你(至少)违反了OO的这三条神圣规则<代码>A和
B
应该依赖于抽象(接口)。相同的方法应该抽象为一个接口,不同的方法应该抽象为不同的接口。S.O.L.I.D比设计模式更基本。设计模式基于实体。首先学习它,你就不会再有这样的问题了。

重用代码基本上有两种方法(当代码在两个或多个类之间重复时)

  • 继承:如果所有参与的类(共享重复的代码)在逻辑上都被放入一个层次结构中,在这个层次结构中遵循“is-a”关系,而不是创建一个基类,那么在基类中拉取公共方法,并自定义子类方法。(如果方法实现在子类之间存在差异,请考虑使用模板方法模式。)

  • 组合:如果参与的类不遵循“is-a”关系,因此无法放置在层次结构中,则创建一个类并将所有可重用方法放置在该类中。只要您想通过组合重用方法,就可以使用该类


如果功能相同,为什么基类不是一个合理的解决方案?@DaveNewton因为其他20种不同的方法,如differentMethodFromA和differentMethodFromB,也需要使用menuProvider和tree字段,我必须提供基类的getter方法。此外,每次从基类调用getter后,我都必须进行强制转换,在我看来,基类看起来很难看。然后应该有一个接口规范化
MenuProvider
功能。@Alex为什么需要强制转换?您可以在基类上使用泛型。@JnRouvignac我的意思是,从子类中调用getMenuProvider()方法后,我必须将其强制转换为AmenuUpVider或BMenuProvider