WebDriver factory без IF-ELSE
В этой заметке покажу, как можно написать WebDriver factory без применения IF-ELSE. Зачастую во фреймворках в случае кросс-браузерного тестирования приходится писать драйвер фэктори. Большинство реализаций, которые мне приходилось видеть, выглядели так:
BrowserFactory.class
class BrowserFactory{
public static final WebDriver DEFAULT_FF = new FirefoxDriver();
public static WebDriver getDriver(String name){
WebDriver driver = null;
if("FIREFOX".equalsIgnoreCase(name)){
driver= new FirefoxDriver();
}else if("CHROME".equalsIgnoreCase(name)){
driver = new ChromeDriver();
}else if("IE".equalsIgnoreCase(name)){
driver = new InternetExplorerDriver();
}else {
driver = DEFAULT_FF;
}
return driver;
}
Но такая реализация, скажем так, не самая хорошая: читабельность кода страдает, человеку приходится гадать, как же правильно задать имя браузера, ну и самое неприятное - куча if-else. Давайте посмотрим, как можно улучшить ситуацию. Объектно-ориентированные языки программирования обладают мощнейщим принципом - полиморфизмом. Его мы и будем использовать, чтобы удалить if-else в коде. В результате читабельность кода значительно повысится.
Рефлексия
Первое "топорное" решение (я назвал бы его "решением для реальных пацанов"):
public class Browsers{
public static WebDriver newBrowser(String name){
return Class.forName(name).newInstance();
}
}
Смотрится очень просто, НО сложность заключается в том, что человек должен помнить полное имя класса. К тому же, использование рефлексии повышает степень брутальности в пару раз. Поэтому таких решений следует избегать.
Map
Второе решение более приемлемое - использование Map.
public class Browsers{
private static Map<String,WebDriver> drivers = new HashMap<>(){
put("CHROME",new ChromeDriver());
put("FIREFOX",new FirefoxDriver());
put("IE",new InternetExplorerDriver());
}
public static WebDriver newDriver(String name){
return drivers.get(name);
}
}
Это решение обладает недостатком: нужно знать правильное имя драйвера, которое задано в Map.
Switch
switch (name) {
case "FIREFOX": return new FirefoxDriver();
case "CHROME": return new ChromeDriver();
case "IE": return new InternetExplorerDriver();
default: return DEFAULT_FF;
}
Enum
Самое элегантное решение:
public enum Browsers {
CHROME {
public WebDriver create(){
return new ChromeDriver();
}
},
IE {
public WebDriver create(){
return new InternetExplorerDriver();
}
},
FIREFOX {
public WebDriver create() {
return new FirefoxDriver();
}
};
public WebDriver create(){
return null;
}
}
class Test {
public static void main(String[] args) {
WebDriver driver = Browsers.FIREFOX.create();
}
}
Классно, не правда ли? Нету надоедливых if-else, нету строк, которые нужно помнить - просто вызываем нужный нам тип драйвера и все. Лично я предпочитаю этот метод.
P.S. Конструкция if-else делает код сложным для чтения, поэтому нужно стараться избегать их использования.