St.Antario
St.Antario

Reputation: 27455

Using FactoryMethod pattern

I have two separate entities:

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 having a number of subclasses I would not like users to access directly. How should I handle those things better?

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 shown earlier.

Couldn't someone explain how can I make a right decision? What potentiall circumstances requires implementing FactoryMethod a bad decision and when it would be really good?

UPD:

public interface Validator{
    public ErrorCode validate();
}

public abstract class GenericValidator implements Validator{
   //...
}

The ErrorCode class encapsulates the result of the validation (null if valiadtion's completed succsfully).

Upvotes: 5

Views: 130

Answers (3)

Vikas
Vikas

Reputation: 4301

Validator interface can look like this:

public interface Validator {
   public int validate();
}

Filter interface can look like this:

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

Rule interface:

public interface Rule {
  public String getRule();
}

FilterValidator can 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 client will invoke this factoy like this:

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 interfaces Rule, Filter you can enforce the behavior you desire from client. Then client can get instances from the factory and pass the rule/filter instances to it for validation.

Upvotes: 3

makasprzak
makasprzak

Reputation: 5220

The Single Responsibility Principle

Construction of Validator is one responsibility, Filter or Rule probably carries another one. This means we should split it and usually we do so encapsulating instantiation logic in a Factory pattern.

Also note that implementing Validatable means being a ValidatorFactory. My answer would be - 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 Dependency Injection.

Upvotes: 3

jakub.petr
jakub.petr

Reputation: 3031

I use this pattern in two major cases:

A) Construction of the object isn't trivial - I don't trust the users of the API to do it correctly

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

In both these cases I want to hide implementations simply because the user won't know which one to use and/or doesn't know how to construct it properly.

Always aim for simplicity and ease-of-use for your user. Ask yourself these questions:

  1. Is the API easy to understand?
  2. Is the API easy/fun to use?
  3. Is it foolproof? (I have to try quite hard to misuse it)

Upvotes: 3

Related Questions