gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 05:30:15 24 4
gpt4 key购买 nike

您好,重构 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/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com