【问题标题】:Refactoring code with too many switch cases使用过多的 switch case 重构代码
【发布时间】:2017-02-16 03:17:59
【问题描述】:

我继承了一个需要重构的应用程序。以下让我有些头疼。原始源代码中有太多类似如下的 switch case:

class Girl {
    //...
    void traditionalMakeUp() {
        switch (type) {
            case FRENCH:
                frenchMakeUp();
                break;
            case AFRICAN:
                africanMakeUp;
                break;
            case NORWEGIAN:
                norwegianMakeUp();
                .....

            case KOREAN:
                koreanMakeUp();
                .....
        }
    }
}

我正在尝试像这样重构它:

abstract class Girl {
    //...
    abstract void makeUp();
}

class French extends Girl {
    void makeUp() {
        // makeUP
    }
}
class African extends Girl {
    void makeUp() {
        // makeUP
    }
}
class Norwegian extends Girl {
    void makeUp() {
        // makeUP
    }
}

// Somewhere in client code
girl.makeUp();

这是正确的方法吗?如果我的 switch 中没有 20 多个案例,那么策略模式就可以了。

此外,我不愿意为了适应策略设计模式而添加 20 多个类。还有其他重构的好方法吗?

【问题讨论】:

  • 每个变体makeUp() 方法的作用是什么?
  • @Naros makeUp() 因国籍而异。挪威语中的 makeUp() 逻辑与法语中的 makeUp() 逻辑等完全不同......
  • switch 中的病例数或多或少是固定的还是有可能增加? makeUp() 方法的平均代码行是多少? makeUp() 方法也依赖于其他类还是完全独立的代码?
  • 另外,Girl 中除了makeUp() 之外总共有多少方法?
  • @SabirKhan switch 中的病例数将继续增长。这就是我想重构它的原因。一个 makeUp() 方法平均有大约 20 行代码。除了 makeUp() 之外,还有大约 26 种其他方法。一团糟!

标签: java android design-patterns refactoring


【解决方案1】:

根据属性type,您的应用程序中存在的Girl 的其他操作/开关看起来确实在这里调用了继承。

如果这是唯一的开关,你可以像下面这样,

用一个抽象方法定义一个枚举 Girl - makeUp(),然后为该枚举类型实现该方法。

public enum Girl {

    FRENCH {
        public void makeUp() {
            Utility.frenchMakeUP();
        }
    },

    AFRICAN {
        public void makeUp() {
            Utility.africanMakeUP();
        }
    },

    NORWEGIAN {
        public void makeUp() {
            Utility.norwegianMakeUP();
        }
    },

    KOREAN {
        public void makeUp() {
            Utility.koreanMakeUP();
        }
    };

    public abstract void makeUp();

}

您的实用程序类如下所示。

public class Utility {

    public static void frenchMakeUP() {

    }

    public static void africanMakeUP() {

    }

    public static void norwegianMakeUP() {

    }

    public static void koreanMakeUP() {

    }

}

客户端代码

Girl girl = Girl.FRENCH;
girl.makeUp();

您可以组织多个实用程序类,具体取决于存在多少功能以及如何组合常用功能,即 call ,Utility.koreanMakeUP() from with in makeUp() 可以进一步组织。

【讨论】:

    【解决方案2】:

    有多种方法可以重构这样的场景。

    继承当然是这里要考虑的一种选择。但是根据层次结构的深度以及您是否发现自己需要在层次结构中创建辅助类或中间类来共享公共代码,我会考虑组合。

    虽然 #makeUp 所做的工作因女孩的类型而异,但在语义上可能存在相似之处,您可以构建小的代码单元(组件),然后您可以以类似组件的方式将它们拼凑在一起。

    【讨论】:

    • 谢谢!我会尝试研究构图。
    【解决方案3】:

    我宁愿在这里为Girl作曲,为妆容传承。根据您的领域,法国女孩可能可以穿非洲妆。让一个女孩包含一个 MakeUp 类型的对象。

    然后我会做这样的事情:

    public class FrenchMakeUp extends MakeUp
    {
        @Override
        public void apply(){...}
    }
    
    public class Girl
    {
        public void makeUp(MakeUp makeUp)
        {
            makeUp.apply();
        }
    }
    

    在客户端代码中:

    girl.makeUp(new FrenchMakeUp());
    

    这是为了更接近您尝试的重构,但它并不能解决决策问题。也许您可以拥有一张地图来帮助您选择正确的化妆类型。

    【讨论】:

      猜你喜欢
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      相关资源
      最近更新 更多