这个类有三个方法可以做同样的事情,它们等待三秒钟加载页面,如果页面已加载则返回true。
我的问题是,我如何确定哪一段代码最好?
我知道Lambda is preferred above Anon classes,但为什么静态嵌套类(pageLoaded3)不好?根据{{3}},它也应该适合。
public final class ExpectedConditions {
private ExpectedConditions() {
}
public static ExpectedCondition<Boolean> pageLoaded1() {
return (driver) -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return !((JavascriptExecutor) driver).executeScript("return performance.timing.loadEventEnd", new Object[0])
.equals("0");
};
}
public static ExpectedCondition<Boolean> pageLoaded2() {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return !((JavascriptExecutor) driver)
.executeScript("return performance.timing.loadEventEnd", new Object[0]).equals("0");
}
};
}
public static ExpectedCondition<Boolean> pageLoaded3() {
return new PageLoaded();
}
private static class PageLoaded implements ExpectedCondition<Boolean> {
@Override
public Boolean apply(WebDriver driver) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return !((JavascriptExecutor) driver).executeScript("return performance.timing.loadEventEnd", new Object[0])
.equals("0");
}
}
}
这是三种方法的返回类型的接口:
public interface ExpectedCondition<T> extends Function<WebDriver, T> {}
答案 0 :(得分:1)
正如评论中已经提到的:功能是等效的。所以技术上,差别很小。所有方法都编译为类似的字节码。所以关于哪一个是最好的&#34;只能根据代码本身来回答。在那里,可以应用不同的标准。
首先,正如Peter Lawrey在评论中所说的那样:你可以将Thread.sleep
召唤变成帮助方法:
private static void pause(long ms)
{
try
{
Thread.sleep(ms);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
此外,您可以将在那里实现的核心功能转换为辅助方法:
private static Boolean execute(WebDriver driver)
{
pause(3000);
return !((JavascriptExecutor) driver)
.executeScript("return performance.timing.loadEventEnd", new Object[0])
.equals("0");
}
使用这种方法,给定方法之间的相似性变得更加明显:它们只是调用此方法的不同方式!我认为引入这种方法将具有额外的优势。该方法是一个清晰的构建块&#34;,具有清晰的接口(并且希望具有清晰的JavaDoc)。
此外,此方法将为第四次实现打开大门 - 即使用方法引用的方法:
public static ExpectedCondition<Boolean> pageLoaded4()
{
return ExpectedConditions::execute;
}
因此,您现在有四种方法可以实现所需的功能:
方法3,使用静态内含类:这不是必需的。如果静态内部类仅是方法调用的包装器,则它不能用于实际目的。它引入了一个新的名称(在您的情况下为PageLoaded
),并在源代码中引入了一个新的间接 - 这意味着程序员必须查找PageLoaded
类来查看它确实。在其他情况下,这可能是一个不同的故事。例如。如果PageLoaded
类有其他方法或字段,但这不是这种情况。
方法2,有一个匿名的内部类:有人可能会认为功能界面的匿名类只是老式的#34;或者#Java; pre-Java8-way&#34;写它。如果必须实现的类型是功能接口(即具有单个抽象方法),则使用lambda或方法引用只是更短且更方便,并且没有任何明显的缺点。 (当然,如果必须实现的类型具有多个抽象方法,那么这是不可能的。但同样,这不是这种情况)
方法1,使用lambda:这是在Java 8中实现这种功能接口的标准方法。我个人更喜欢拥有短 lambda体。像你问题中那样的lambda
return (driver) -> {
// "Many" lines of code, maybe even nested, with try-catch blocks
};
是恕我直言,不那么可读和简洁,我通常尽量保持这些身体尽可能短。在最好的情况下,可以省略{
括号}
- 通过引入包含lambda主体的方法来确定。在这种情况下,人们通常可以将其归结为最后一种方法:
方法4,方法参考。这可能有点主观,但我认为这个是最具可读性的。该方法的优点是成为&#34;构建块&#34;具有明确的功能,可以在JavaDocs中明确指定。此外,您甚至可以考虑省略包装方法(上面称为pageLoaded4
),并简单地将该方法作为public
提供。用户,以前称为
ExpectedCondition<Boolean> condition =
ExpectedConditions::pageLoaded4();
然后可以直接使用该方法
ExpectedCondition<Boolean> condition =
ExpectedConditions::execute;
但是这个取决于确切的应用程序模式和这个类的预期接口。可能不希望直接公开此方法。