Using the FactoryMethod Template

I have two separate objects:

public enum Rule implements Validatable, StringRepresentable{ //... } 

and

 public inteface Filter extends Validatable, StringRepresentable{ //... } 

Where

 public inteface Validatable{ public GenericValidator getValidator(); } 

and

 public interface StringRepresentable{ public String getStringRepresentation(); } 

GenericValidator is an abstract class that has several subclasses that I would not want users to access directly. How should I deal with these things?

I don’t understand when it’s better to create a class like

 public class ValidatorFactory{ public Validator getRuleValidator(Rule r){ ... } public Validator getFilterValidator(Filter f){ ... } } 

instead of implementing the Validatable interface, as I showed earlier.

Can anyone explain how I can make the right decision? What potential circumstances require FactoryMethod bad decision and when will it be really good?

UPD:

 public interface Validator{ public ErrorCode validate(); } public abstract class GenericValidator implements Validator{ //... } 

The ErrorCode class encapsulates the result of the test ( null if valiadtion is successful).

+5
source share
3 answers

Principle of shared responsibility

Building a Validator is one responsibility; a Filter or Rule probably carries another. This means that we must separate it, and usually we do this by encapsulating the logic of creating an instance in a Factory template.

Also note that the implementation of Validatable means ValidatorFactory. My answer would be to combine both solutions:

 public class FilterImpl implements Filter { private final Validator validator; public FilterImpl(Validator validator) { this.validator = validator; } @Override public getValidator() { return this.validator; } //... } public class FilterFactory { private final ValidatorFactory validatorFactory = new ValidatorFactory(); public Filter createFilter() { return new FilterImpl(valdatorFactory.createFilterValidator()); } } 

This is called Injection Dependency.

+3
source

I use this template in two main cases:

A) Building an object is not trivial - I don't trust API users to do it right

B) There are more implementations, and I want to choose the right one myself.

In both cases, I want to hide the implementations simply because the user will not know which one to use and / or does not know how to build it correctly.

Always strive for simplicity and ease of use for your user. Ask yourself the following questions:

  • Is the API easy to understand?
  • Is the API easy / useful?
  • It is safe? (I need to use it very hard)
+3
source

The verification interface may look like this:

 public interface Validator { public int validate(); } 

The filter interface may look like this:

 public interface Filter { public String getParameters(); // some related methods.. public int currentLength(); .... } 

Rules Interface:

 public interface Rule { public String getRule(); } 

FilterValidator might look like this:

 public class FilterValidator implements Validator{ private Filter f; public FilterValidator(Filter f){ this.f = f; } @Override public int validate() { // validate f and return errorcode String params = f.getParameters(); int strLength = f.currentLength(); ..... return 0; } } 

Creating a factory is better to hide the internal logic of validators.

 public class ValidatorFactory { public Validator getRuleValidator(Rule r){ return null; } public Validator getFilterValidator(Filter f){ FilterValidator fv = new FilterValidator(f); return fv; } } 

Now the client will refer to this fact as follows:

 public class ClientDemo { private class MyFilter implements Filter{ private String filterInput; public MyFilter(String input){ this.filterInput = input; } @Override public String getParameters() { return null; } @Override public int currentLength() { return this.filterInput.length(); } } public void testValidators(){ ValidatorFactory factory = new ValidatorFactory(); Validator v = factory.getFilterValidator(new MyFilter("filter string goes here...")); v.validate(); } } } 

Through the Rule, Filter interfaces, you can force the behavior you want from the client. Then the client can get instances from the factory and pass him the instances of the rules / filters for verification.

+3
source

All Articles