java - 重构超过 50k 行代码的类?

标签 java

您好,重构 50k 多行代码,继承和组合哪个更好。

我的方法如下:

  1. 创建将扩展父类的子类(需要重构)。
  2. 为子类创建接口(interface)
  3. 将内部公共(public)方法传递给子类,这些方法也在子类的接口(interface)中声明。

现在为什么要采用这种方法: 1.要重构的父类是@ManagedBean和spring @Component。

@Component
public class MBean extends ManagedBean{

@Autowired
transient SomeService someService;

private void calltoPriavateMethod(){
//100loc
}

public void calltoPublicMethod(){
//200loc
}

public void getExportJson(){

//100 loc

   try{
     calltoPrivateMethod()
   }catch(Exception e){
   //catch exception
   } 

   try{
     calltoPublicMethod()
   }catch(Exception e){
  //catch exception
  }
}
}

  • 我尝试过的解决方案
  • public Interface ChildMBeanInterface{
    
    calltoPublicMethod();
    
    }
    
    @Component
    public class ChildMbean extend MBean implements ChildMBeanInterface{
    
    calltoPublicMethod(){
    
    //200 loc copied here
    }
    
    }
    
    @Component
    public class MBean extends ManagedBean{
    
    @Autowired
    transient SomeService someService;
    
    @Autowired
    ChildMBeanInterface childMBeanInterface;
    
    
    public void getExportJson(){
    
    //100 loc
    
       try{
         calltoPrivateMethod()
       }catch(Exception e){
       //catch exception
       } 
    
       try{
         childMBeanInterface.calltoPublicMethod()
       }catch(Exception e){
      //catch exception
      }
    }
    
    }
    
    
    

    JSF 代码:直接调用 getExportJson()

    <p:commandLink id="exportCaseWithJsonId"
                                                value="Export Data" partialSubmit="true"
                                                onclick="PF('statusDialog').show();"
    
                                                action="#{MBean.getExportCaseJSON}" process="@this"
                                                immediate="true">
    
    

    所以我的问题是我的类结构看起来像这样?我的方法好还是可以改进。请大家给点建议。

    MBean 是 JSF 管理的 Bean,它包含许多用于不同服务的其他函数。从 jsf 调用的函数是公共(public)的,但是一些内部方法调用是私有(private)的和公共(public)的。

    最佳答案

    总的来说,赞成Composition over Inheritance 。继承有许多不适用于组合的限制,并且它会使事情变得过于复杂。

    开始之前,您需要知道哪些部分可以分离。拿一张纸,列出你的字段的用法和方法的关系。尝试确定哪些部分是隔离的。然后将该部分移至不同的类。 (显然,您无法隔离调用方法或使用父类(super class)字段的代码部分)。

    下面是一段代码的示例,其中包含大量有关监听器的代码。

    class Foo {
      List<Listener> listeners;
      // and 101 other fields
    
      public void addListener(...) { }
      public boolean removeListener(...) { }
      private void notifyListeners(...) { }
      // and 101 other mthods
    
      private void somethingHappens() {
        notifyListeners();
      } 
    }
    

    在这种情况下,您可以将监听器部分视为该类的一个独立功能。 这部分代码使用的字段和方法不被其他方法使用,这意味着您可以将它们隔离。

    因此,您可以将它们移动到名为 Listeners 的新“要素类”。

    class Listeners() {
      List<Listener> listeners;
    
      public void add(...) { ... }
      public boolean remove(...) { ... }
      public void notifyListeners(...) { ... }
    }
    

    现在,在原始类中,大多数代码都消失了。

    class Foo {
      Listeners listeners = new Listeners();
    
      public Listeners getListeners() { ... }
    
      private void somethingHappens() {
        listeners.notifyListeners();
      } 
    }
    

    (注意:new Listeners() 也可以进入 protected createListeners() 方法,该方法仍然允许子类覆盖您刚刚创建的行为隔离。)

    你的类(class)变得越来越薄弱。但这确实意味着用法和签名发生了一些变化。即 addListener(...)getListeners().add(...)。这可能是一个问题。

    因此,在开始之前,您应该确定这是否是一个问题。对于内部使用来说这不是问题。但如果你实现了一个接口(interface),它肯定会是这样。

    您可以只添加转发请求的瘦包装方法。但通常这不会是一个很大的进步。您移动了一些代码,并添加了一些新代码。您最终可能会想知道这是否值得。如果有很多私有(private)方法而只有有限数量的公共(public)方法,那么这是一个值得考虑的权衡。

    或者,有时对于遗留代码,您可能只是选择将类划分为可折叠部分。这本身就是一个进步。

    关于java - 重构超过 50k 行代码的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57708771/

    相关文章:

    java - 找不到类型扫描仪的符号变量键盘

    Java递归1234到4321为例

    java - 在文档中显示方法体的一部分

    java - 如何在Spring Gradle项目中将Lombok与JPA元模型一起使用?

    java - FX TabPane 中的 Swing 内容中断

    java - 令人费解的 map 行为

    java - 解析 XML 时出错 : junk after document element - The markup in the document following the root element must be well-formed

    java - 如何使用java客户端请求tensorflow为wide&deep模型提供服务或者如何使用java加载wide&deep模型并预测?

    java - 谷歌分析报告 API v4 : get data from date range between two dates accurate to hours

    java - 获取太多子节点无法获取属性