Factory to instantiate and configure Selenium WebDriver
Quick Simplifications


The 0-args constructor is not used. Remove it.
close() can not be called in a meaningful way. Nobody can obtain an instance of DriverFactory, so making that an instance method is not useful in any way.
You're misusing fields as variables. Everything you're doing can be put into the factory method itself. There's no need for any instance data, you're not accessing it anywhere.


Let's consider instead:

static WebDriver getWebDriver(Properties properties) throws MalformedURLException {
    LOG.fine(properties.toString);
    final URL url = new URL(properties.getProperty("url"));
    final String driver = properties.getProperty("driver");
    final String gecko = properties.getProperty("gecko");
    final List&lt;String&gt; commandLineOptions = new ArrayList&lt;&gt;();
    commandLineOptions.add(properties.getProperty("option01"));

    final FirefoxBinary ffBinary = new FirefoxBinary();
    commandLineOptions.forEach((commandLineOption) -&gt; {
        LOG.fine(commandLineOption);
        ffBinary.addCommandLineOptions(commandLineOption);
    });
    System.setProperty(driver, gecko);

    final FirefoxOptions ffOptions = new FirefoxOptions();
    ffOptions.setBinary(ffBinary);

    WebDriver result = new FirefoxDriver(ffOptions);
    result.get(url.toString()); 
    LOG.fine(webDriver.getTitle());
    LOG.fine(webDriver.getCurrentUrl().toLowerCase());
    return result;
}


This does mostly the same as the code you presented. We can see here that opening yourself up to MalformedURLException is not necessary. You're reading the String from properties into a URL and then call .toString() on it.

What we can see pretty easily now is that you're reading the contents of the passed Properties into variables to just use them once. It might be easier to reimagine the code as something like the following:

public static WebDriver getWebDriver(Properties properties) {
    final FirefoxBinary ffBinary = discoverBinary(properties);
    setSystemProperties(properties);
    final FirefoxOptions ffOptions = buildOptions(ffBinary);
    return createWebDriver(ffOptions, properties);
}


This makes the code comparatively abstract and easy to follow. You can grasp what happens without needing a deeper understanding of Selenium itself (not that the original code required a lot of it).

This abstraction just makes it easier to understand what's going on. The methods themselves are pretty trivial :)