这个反模式是否有名称(带模式的函数)?

时间:2016-03-05 00:43:16

标签: anti-patterns

程序员经常注意到他在一些地方有一些非常相似的代码。可以说这里有类似代码的实例。 (这是一个明确的玩具示例。在野外,这种反模式通常不会在代码上发生这么简单)

function showLoginError(){
    let msg = "Login Error";
    logAtLevel(WARNING, msg);
    displayInPopup(msg);
}

function showDbError(){
    let msg = "Could not access DB";
    logAtLevel(ERROR, msg);
    displayInPopup(msg);
    notify("db-admin@foo.com");
}

function showUnknownError(){
    let msg = "Something has gone wrong";
    logAtLevel(ERROR, msg);
    displayInPopup(msg);
    notify("general-admin@foo.com");
}

一位经验丰富的程序员可能会重构这样的事情,现在这可以被普遍重用并且非常简单地理解。

function showError(logLevel, msg, notifyEmail){
    logAtLevel(logLevel, msg);
    displayInPopup(msg);
    if(notifyEmail){
        notify(notifyEmail);
    }
}

function showLoginError(){
    showError(WARNING, "Login Error");
}

function showDbError(){
    showError(ERROR, "Could not access DB", "db-admin@foo.com");
}

function showUnknownError(){
    showError(ERROR, "Something has gone wrong", "general-admin@foo.com");
}

但是由于经验不足的程序员,我经常会看到像

这样的东西
function showError(errorType){
    let msg;
    let logLevel = ERROR;
    if(errorType == "LOGIN"){
        msg = "Could not access DB";
        level = WARNING;
    }else if(errorType == "DB"){
        msg = "Could not access DB";
    }else if(errorType == "UNKNOWN"){
        msg = "Something has gone wrong";
    }
    logAtLevel(logLevel, msg);
    displayInPopup(msg);
    if(errorType != "LOGIN"){
        notify(errorType == "DB" ? "db-admin@foo.com" : "general-admin@foo.com")
    }
}

function showLoginError(){
    showError("LOGIN");
}

function showDbError(){
    showError("DB");
}

function showUnknownError(){
    showError("UNKNOWN");
}

它们应该具有隔离的部件功能,可以改变它们并将它们从功能中提取出来,但相反,它们使用"模式" (或者有时是布尔标志)。

通常在整个函数的几个位置检查函数模式以隐式设置变量和/或确定函数的哪些部分执行。虽然他们已经摆脱了复制粘贴的代码,但他们已经添加了一种特殊的意大利面条代码。

我已经看够了这么多次,因为我认为必须有一个名字。

P.S。如果一个人不存在,我会思考" Rotini Code"因为它像意大利面,但它有3种不同的颜色混合在一起。

1 个答案:

答案 0 :(得分:0)

是的,这是RTTI =运行时类型信息。通常是代码味道,有时不是。

通常它是代码味道,应该用多态性替换,参见例如Do polymorphism or conditionals promote better design?

另外,Java枚举功能更像是枚举类的子类,因此您可以避免编写许多打开枚举的函数。但它并不总是可以避免的(例如,当一个不能向枚举添加方法的类必须将自己的方法添加到枚举时)。