替换一大堆只返回false的if语句的干净方法是什么?



我正在编写一个简单的电子邮件验证器。我有一个可行的解决方案,但它使用了一堆if语句,它们都返回false。对于这类问题是否有更清晰的方法或设计模式?(我只包含了我想简化的代码)

if (prefix.length() == 0 || domain.length() == 0 || topLevelDomain.length() < 2) {  // if prefix or domain length == 0, or topLevelDomain < 2
return false;
} else if (!isBuiltFrom(prefix, alpha + digit + special)) {  // if any char in prefix is not (a-z), (0-9), '_', '.' or '-' return false
return false;
} else if (!isBuiltFrom(domain, alpha + digit + "-")) {  // if any char in domain is not (a-z), (0-9), or '-' return false
return false;
} else if (!isBuiltFrom(topLevelDomain, alpha)) {  // if any char in topLevelDomain is not (a-z) return false
return false;
} else if (special.contains("" + prefix.charAt(0))) {  // if prefix leading special char return false
return false;
} else if (special.contains("" + email.charAt(prefixIndex - 1))) {  // if prefix trailing special char return false
return false;
} else if (special.contains("" + domain.charAt(0))) {  // if domain leading special char return false
return false;
} else if (special.contains("" + email.charAt(domainIndex - 1))) {  // if domain trailing special char return false
return false;
}

返回true;

if (A) {
return false;
} else if (B) {
return false;
} else if (C) {
return false;
} else if (D) {
return false;
} else {
return true;
}

转换为:

return !A && !B && !C && !D;

有多种方法可以使您的代码更易于阅读或维护。

您可以定义一个接口Validator,例如使用一个简单的方法isValid()。然后每个检查变成它自己的小类。然后将每个类的一个实例放入一个列表中,检查意味着遍历该列表以调用检查方法。这意味着更多的代码和大量的样板文件,但它允许非常简单地添加新的检查:只是另一个类,并向该列表添加另一个对象。你再也不用碰循环部分了

另一个想法是:简单地将每个检查放入一个不同的助手方法中,该方法有一个明确的名称。这将允许你完全放弃所有这些评论。你看,不用写

// if condition X return false 
if whatever X... return false 

你去

if isX(.....) return false

这不会对整体结构造成太大的改变,但是生成的代码应该更容易阅读和理解。

在我看来,我认为你可以根据你检查的函数来简化你的if-else。这样的:

if (prefix.length() == 0 || domain.length() == 0 || topLevelDomain.length() < 2) {  
return false;
}else if(!isBuiltFrom((prefix, alpha + digit + special) || (domain, alpha + digit + "-") || (topLevelDomain, alpha)){
return false;
}else if(special.contains(("" + prefix.charAt(0)) || ("" + email.charAt(prefixIndex - 1)) || ("" + domain.charAt(0)) || ("" + email.charAt(domainIndex - 1))){
return false;
}

在这种情况下,我不认为重写会提高可读性。除了通过修改注释来解释测试的含义,可能会提高可读性。

(示例中的许多注释或多或少是测试表达式的字面翻译。那种评论是多余的。假设检查代码的人可以阅读Java。)

现在,如果单个测试更复杂,或者它们在代码库的其他地方使用,那么将测试重构为谓词方法将有所帮助。如果这些测试中的在其他地方使用,并且您将普通组排除在外,则更是如此。


但归根结底是这样的。哪一个>> <<认为更容易阅读?

if (prefix.length() == 0) return false;

if (isPrefixEmpty(prefix)) return false;

声明

boolean isEmptyPrefix(String prefix) {
return prefix.length() == 0;
}

可以在50行之外,或者在另一个文件中。

考虑到要阅读第二个,您需要或者知道isPrefixEmpty正在进行适当的测试(因为您之前阅读了它并记住了它的功能)您需要查看方法定义。如果你必须(找到并)查看定义,那就打断了"流程"。你对密码的解读。如果您只是假设isPrefixEmpty做了您认为它做的事情,那么您可能会误读代码。


底线:重构可以是好的…这可能很糟糕。你必须考虑结果会是什么样子。这同样适用于设计模式。

A"if试验壁";可能在美学上令人不满意,但美学并不是判断代码的最佳标准。其他事情更重要……

相关内容

最新更新