将一个庞大的类重构为许多小类

时间:2010-12-19 19:59:25

标签: refactoring coding-style

我有一个很好的机会来重构旧的和“臭”的代码 进入一个设计得更好的班级家庭。

我已经找到了基本设计框架,并实施了测试

然而,我达到了一个很大的“经理”班级 它管理它应该管理的东西(让我们假设一些棘手的任务队列),
但它也对其他一些东西负责,这不是我本课程的第一本意图。

创建一组新类

class OperationAPerformer
{
    void PerformA(input){...}
}

class OperationBPerformer
{
    void PerformB(input){...}
}

感觉不是正确的解决方案。 保持OperationA,OperationB的逻辑在manager类中 似乎没有很好的设计理由使Manager类膨胀

有什么建议吗? 谢谢!

好的,所以我不能在这里发布我的所有代码 但基本设计(或骨架)

InitEventHandler  
SubmitEventHandler  
CancelEventHandler  
SuccessEventHandler  
FailureEventHandler  
ProgressReportedEventHandler  
TimeOutEventHandler

...
事件处理程序更新一些参数 并做一些管理工作,如故障恢复后, UI参数更新等。

OperationA和OperationB是相关的,但弥补了大量代码 这掩饰了班级的主要骨架

相关行动
SaveProducts()    SaveStepA    SaveStepB ......

ValidateResponses     ValidatePartA     ValidatePartB ......

创建类似

的类
class Validator
{
   public bool Validate(Response resp) {...}
   private bool PartA(...){...}
   private bool PartB(...){...}
}

似乎不合适,因为该类只是一组相关的方法...... 是否有足够的理由创建一个类?

2 个答案:

答案 0 :(得分:4)

尺寸本身并不是一种需要;它只是一种“气味”,是调查是否应该更改代码的理由。

类的目的不是减小文件大小。它应该是代码组织原则的表示。如果不同的操作自然形成类别(理想情况下,因为它们在功能上具有凝聚力,正如Pangea所暗示的那样,但对于任何合理的,可以说明的理由而言),然后将其分解为单独的经理类。

其他想法:

如果决策机制是数据驱动的,请考虑功能映射:

interface Performer { public void perform(InputClass input); };
Map<String,  Performer> choices = new HashMap<String,  Performer>();
choices.put("choiceA", 
            new Performer() { public void perform(InputClass input) {
                // ... do action A
            });
choices.put("choiceB", 
            new Performer() { public void perform(InputClass input) {
                // ... do action B
            });

如果决定是由与执行操作的代码紧密相关的代码做出的,那么您可以重新认为“执行”意味着“如果可以,请执行,告诉我您是否可以”:

interface Performer { public boolean perform(InputClass input); };
List<Performer> pipeline = new LinkedList<Performer>();
pipeline.add(new Performer() { public void perform(InputClass input) {
// ... do action A if you can
});
pipeline.add( new Performer() { public void perform(InputClass input) {
// ... do action B if you can
});

无论哪种方式,您都可以密封管理器内部的配置,将其暴露给主函数,甚至从配置文件中驱动它。

如果上述情况都不属实,并且管理员必须做的事情很简单,那么请考虑咬住子弹并让管理器类通过许多小的静态函数膨胀。

答案 1 :(得分:3)

您可以将GOD manager clas分成多个“用例”管理器类,即每个用例的单独管理器类。这样每个经理类都具有功能上的凝聚力,经理类只有一个原因可以改变(单一责任原则)。

如果你很难把它分成更小的类,那么它可能表明它已经具有凝聚力了。