您好,重构 50k 多行代码,继承和组合哪个更好。
我的方法如下:
- 创建将扩展父类的子类(需要重构)。
- 为子类创建接口(interface)
- 将内部公共(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/