我继承了一个需要重构的应用程序。以下是让我头疼的问题。原始源代码包含太多开关案例,如下所示:
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();
这是正确的方法吗?如果我的交换机中没有20多个案例,策略模式就可以了。
此外,我不愿意添加20多个课程以适应策略设计模式。还有另一种重构方法吗?
答案 0 :(得分:2)
根据属性Girl
的{{1}}应用程序中存在的其他操作/开关,确实会在此处调用继承。
如果那是唯一的开关,你可以这样做,
type
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();
的来电Utility.koreanMakeUP()
。
答案 1 :(得分:1)
有多种方法可以重构这种情况。
继承肯定是这里考虑的另一种选择。但是,根据层次结构的深度,以及您是否需要在层次结构中创建辅助类或中间类来共享公共代码,我会考虑组合。
虽然#makeUp
的确根据女孩的类型而有所不同,但也许存在语义上的相似之处,你可以构建小单位的代码(组件),然后你可以以类似组件的方式拼凑起来。
答案 2 :(得分:0)
我宁愿为这里的女孩做作文,也要为化妆继承。根据您的域名,法国女孩可能会穿非洲化妆品。让女孩包含MakeUp类型的对象。
然后我会做类似的事情:
public class FrenchMakeUp extends MakeUp
{
@Override
public void apply(){...}
}
public class Girl
{
public void makeUp(MakeUp makeUp)
{
makeUp.apply();
}
}
在客户端代码中:
girl.makeUp(new FrenchMakeUp());
这是更接近您尝试的重构,但它不能解决决策问题。也许您可以使用地图来帮助您选择正确的化妆类型。