DRYing out some Java code and tests I am writing some tests that all follow the same pattern, I feel like repeating myself over and over again, how can I reduce the repetition? The (almost) repeating part is in constructor and the class level variables:

VariablesPage

public class VariablesPage extends LoadableComponent&lt;VariablesPage&gt; {

    private final TestHelpers helpers;
    private WebDriver driver;

    @FindBy(xpath = "//a[@title=\"Define new variable\"]") 
    private WebElement btnAddNewVariable;

    public VariablesPage() throws Exception {
        helpers = new TestHelpers();
        driver = helpers.getWebDriver();
        helpers.setHar(VariablesPage.class.getSimpleName());
        PageFactory.initElements(driver, this);
        isLoaded();
        helpers.getHar();
    }

    @Override
    protected void load() {

    }

    @Override
    protected void isLoaded() throws Error {
        helpers.waitUntil(btnAddNewVariable);
    }
}


addStepsPage

public class AddStepsPage extends LoadableComponent&lt;AddStepsPage&gt; {

    private final TestHelpers helpers;
    private WebDriver driver;
    @FindBy(xpath = "//div[@class=\"body sequential\"]")
    private WebElement divStepsBody;

    public AddStepsPage() throws Exception {
        helpers = new TestHelpers();
        driver = helpers.getWebDriver();
        helpers.setHar(AddStepsPage.class.getSimpleName());
        PageFactory.initElements(driver, this);
        isLoaded();
        helpers.getHar();
    }


    @Override
    protected void load() {

    }

    @Override
    protected void isLoaded() throws Error {
        helpers.waitUntil(divStepsBody);
    }
}
First, let us collect the code pieces which are repeated   

Fields


private final TestHelpers helpers;
private WebDriver driver;



Constructor related  


helpers = new TestHelpers();  
driver = helpers.getWebDriver();



Now, let's start refactoring by extending LoadableComponent&lt;T&gt;  

public abstract class ExtendedLoadableComponent&lt;T&gt; extends LoadableComponent&lt;T&gt; {

    protected final TestHelpers helpers
    protected WebDriver driver;

    public ExtendedLoadableComponent() throws Exception {
        helpers = new TestHelpers();
        driver = helpers.getWebDriver();
    }
}


which reduces the first class to  

public class VariablesPage extends ExtendedLoadableComponent&lt;VariablesPage&gt; {

    @FindBy(xpath = "//a[@title=\"Define new variable\"]") 
    private WebElement btnAddNewVariable;

    public VariablesPage() throws Exception {
        super();
        helpers.setHar(VariablesPage.class.getSimpleName());
        PageFactory.initElements(driver, this);
        isLoaded();
        helpers.getHar();
    }

    @Override
    protected void load() {}

    @Override
    protected void isLoaded() throws Error {
        helpers.waitUntil(btnAddNewVariable);
    }
}


But wait, we can do better! So, let us also call helpers.setHar(String) and thus we need to refactor the constructor of ExtendedLoadableComponent&lt;T&gt;   

public abstract class ExtendedLoadableComponent&lt;T&gt; extends LoadableComponent&lt;T&gt; {

    protected final TestHelpers helpers
    protected WebDriver driver;

    public ExtendedLoadableComponent(Class&lt;T&gt; pageClassToProxy) throws Exception {
        helpers = new TestHelpers();
        driver = helpers.getWebDriver();
        helpers.setHar(pageClassToProxy.getSimpleName());
        PageFactory.initElements(driver, pageClassToProxy);
    }
}


which reduces the first class to  

public class VariablesPage extends ExtendedLoadableComponent&lt;VariablesPage&gt; {

    @FindBy(xpath = "//a[@title=\"Define new variable\"]") 
    private WebElement btnAddNewVariable;

    public VariablesPage() throws Exception {
        super(VariablesPage.class);
        isLoaded();
        helpers.getHar();
    }

    @Override
    protected void load() {}

    @Override
    protected void isLoaded() throws Error {
        helpers.waitUntil(btnAddNewVariable);
    }
}


Naming

I don't know if the TestHelpers class is your own. If yes, you should think about changing the names for setHar() and getHar() so Mr. Maintainer can evaluate what they do by looking at the names.