To automate mobile applications I use the Factory design pattern. The set of methods for iOS and Android is the same, but the elements are declared differently. How to avoid duplicate code?

Here is a simplified example:

public interface FormHelper { void close(); } public class AndroidForm implements FormHelper { private Button btnClose = new Button("//a[text()='Close']"); @Override public void close() { btnClose.click(); } } public class IOSForm implements FormHelper { private Button btnClose = new Button("//div[@id='close']"); @Override public void close() { btnClose.click(); } } public class FormFactory { public static FormHelper getForm(){ if (x > 0) { return new AndroidForm(); } else { return new IOSForm(); } } 
  • Abstract class? - Andrey M

2 answers 2

Your code can be refactored like this:

 public abstract class FormHelper { private final Button button; protected FormHelper(String action) { button = new Button(action); } public void close(){ button.click(); } } public class AndroidForm extends FormHelper { private final static String action="//a[text()='Close']"; protected AndroidForm() { super(action); } } public class IOSForm extends FormHelper { private final static String action = "//div[@id='close']"; protected IOSForm() { super(action); } } public class FormFactory { public static FormHelper getForm(int x) { if (x > 0) { return new AndroidForm(); } else { return new IOSForm(); } } } 
  • Unfortunately, this is not suitable for a real project: there are many methods and many variables of type btnClose. Passing them all in the constructor is not an option - alex
  • @alex would you then bring the code close to the real one in the question. - andreycha
  • @andreycha yes. it was necessary, did not want to pile up large chunks of code - alex
  • @alex so edit the question. - andreycha
  • @andreycha found a solution, thanks for the help - alex

You need to add an abstract class, inherit the android and ios classes from it, and add a non-static initialization block to them.

 public interface FormHelper { void close(); } public abstract class FormAbstract implements FormHelper{ protected Button btnClose; @Override public void close() { btnClose.click(); } } public class AndroidForm extends FormAbstract { { btnClose = new Button("//a[text()='Close']"); } } public class IOSForm extends FormAbstract { { btnClose = new Button("//div[@id='close']"); } } public class FormFactory { public static FormHelper getForm(){ if (x > 0) { return new AndroidForm(); } else { return new IOSForm(); } }