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).
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.
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:
Is the API easy to understand?
Is the API easy/fun to use?
Is it foolproof? (I have to try quite hard to misuse it)
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.
Related
I have these classes:
#Data
#AllArgsConstructor
#NoArgsConstructor
public class User {
private String name;
private int age;
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Admin {
private String name;
private int age;
}
And I have some operations with template method pattern implementation. Base class with algorithm:
public abstract class Operation<T> {
public void process(T t) {
System.out.println(t);
updateName(t);
System.out.println(t);
}
protected abstract void updateName(T t);
}
Two children with implementation template method:
#Component
public class UserOperation extends Operation<User> {
#Override
protected void updateName(User user) {
String newName = user.getName().toUpperCase();
user.setName(newName);
}
}
#Component
public class AdminOperation extends Operation<Admin> {
#Override
protected void updateName(Admin admin) {
String name = admin.getName();
StringBuilder builder = new StringBuilder();
builder.append(name);
StringBuilder reverse = builder.reverse();
admin.setName(reverse.toString());
}
}
My questions:
How do I rewrite this code to use composition?
Do I understand correctly that when using the template method, I attach to inheritance?
The template method is a great way to avoid duplication. But if it binds me to inheritance, what other ways are there to avoid code duplication? In my example, how can I use composition? (replace the template method with something else?)
1) How do I rewrite this code to use the composition?
The Strategy Pattern is one way. Essentially, you would reverse the relationship between data and operations by passing the operations into the data rather than passing the data into the operations. This is a fundamental change, because "real" objects (with state and behavior) are used instead of data classes.
2) Do I understand correctly that when using the template method, I attach to inheritance?
Yes, the Template Method Pattern is fundamentally based on inheritance.
Instead of template pattern you could have a proxy:
public abstract class Operation<T> {
public abstract void updateName(T t);
}
public class OperationProxy<T> extends Operation<T> {
private final Operation<T> delegate;
public OperationProxy(Operation<T> delegate) {
this.delegate = delegate;
}
#Override
public void updateName(T t){
System.out.println(t);
delegate.updateName(t);
System.out.println(t);
}
}
Note that this would allow you to make class Operation and interface.
UPDATE
Another possibility is defining sequences of operations, and a print operation (even more code):
public interface Operation<T> {
void updateName(T t);
}
public class OperationSequence<T> implements Operation<T> {
private final Operation<T>[] steps;
public OperationSequence(Operation<T>... steps) {
this.steps = steps;
}
#Override
public void updateName(T t){
for (Operation<T> step: steps) {
step.updateName(t);
}
}
}
public class PrintOperation<T> implements Operation<T> {
#Override
public void updateName(T t){
System.out.println(t);
}
}
You can now use the following code:
Operation<MyClass> print = new PrintOperation<>();
Operation<MyClass> seq = new OperationSequence<>(
print, (t) -> {doSomethingWith(t);}, print);
Suppose there is a third party library containing base class Transformer and concrete implementations TransformerA and TransformerB.
I need to write parallel classes for TransformerA and TransformerB outputting class say TransformerNew
public class TransformerAConverter {
public TransformerNew convert(TransformerA transformerA) {
// conversion logic
}
}
public class TransformerBConverter {
public TransformerNew convert(TransformerB transformerB) {
// conversion logic
}
}
I need to write following function:
public TransformerNew[] process(Transformer[] transformers) {
}
How can I achieve this without instanceof or explicit type casting. I have tried using visitor pattern but unable to express it.
I would suggest you using Strategy pattern here. The two transformers would be the Transformer strategy here. You may organize the code like this. Visitor won't fit in here, since it is used to decouple the traversal logic from the underneath data structure or representation.
public class TransformerConverter {
private final Transformer transformerStrategy,
public TransformerConverter(Transformer strategy) {
this.transformerStrategy = strategy;
}
public TransformerNew convert() {
// use the strategy to achieve the conversion.
}
}
From the comments - that sounds like the Facade pattern might be useful. For example, given this interface:
public interface TransformerNew {
public int getInterestingValue();
}
Then have a few implementations:
public class TransformerNewA implements TransformerNew {
private final TransformerA a;
public TransformerNewA(TransformerA a) {
this.a = a;
}
public int getInterestingValue() {
return a.getSomeValue() + a.getSomeOtherValue();
}
}
and
public class TransformerNewB implements TransformerNew {
private final TransformerB b;
public TransformerNewB(TransformerB b) {
this.b = b;
}
public int getInterestingValue() {
return b.getFirstPart() + b.getSecondPart();
}
}
So there's really no conversion here - just wrapping the 3rd party type, and providing a common (hopefully simpler) interface for downstream use.
I use a common interface which doesn't provide a method from an implementation class. I don't want to instantiate the concrete implementation, but still need to use this method.
Concrete question: How to make the specialMethod() available?
Interface:
public interface Filter {
void commonMethod();
}
Implementation:
public class IpFilter implements Filter {
#Override
public void commonMethod() {
}
public void specialMethod() {
}
}
Container class:
public class Manager {
private final Filter filter = new IpFilter();
public Filter getFilter() {
return this.filter;
}
}
Caller class:
public static void main(final String[] args) {
final Manager manager = new Manager();
manager.getFilter().commonMethod();
manager.getFilter().specialMethod(); // METHOD NOT AVAILABLE
}
There has to be a concrete class instance in existence at the point where you want to call specialMethod(). If you can prove (i.e. with instanceof) it's the right class then you can downcast to IpFilter and call the method.
public static void main(final String[] args) {
final Manager manager = new Manager();
Filter f = manager.getFilter();
f.commonMethod();
if (f instanceof IpFilter)
{
((IpFilter) f).specialMethod();
}
...
}
HOWEVER, this is code smell and should be avoided.
DOUBLE-HOWEVER sometimes the sausage-making is not pretty and this is the only way to accomplish something if you have to work within a legacy system that cannot be redesigned to not smell so much.
Change
public class Manager {
private final Filter filter = new IpFilter();
public Filter getFilter() {
return this.filter;
}
}
to
public class Manager {
private final IpFilter filter = new IpFilter();
public IpFilter getFilter() {
return this.filter;
}
}
The specialMethod() doesn't show up because the object your trying to invoke the method on is a "Filter", and Filter does not define specialMethod. Only IpFilter does.
I would like to use the builder pattern in some upcoming work that I have which has several classes in a hierarchy. The base class will have at least 9 fields to start, and the various sub-classes may add between 2-4 more fields each. This would get out of hand very quickly and the builder pattern is appealing to me for this exact reason. I got some initial exposure to the builder pattern in books and articles. They were helpful, but had nothing on how to extend this pattern. I tried to implement this by myself, but I ran into trouble with the constructors of each of the sub-classes because I didn't get how to pass the collected data in the builder to super class. I looked on SO for some answers, and here's what I found.
This one is from SO 24243240 where an example of how to extend an abstract class with an abstract builder is given. It is also based on this blog post.
public abstract class AbstractA {
protected String s;
protected int i;
protected AbstractA() {
}
protected abstract static class ABuilder<T extends AbstractA, B extends ABuilder<T,B>> {
protected T object;
protected B thisObject;
protected abstract T getObject(); //Each concrete implementing subclass overrides this so that T becomes an object of the concrete subclass
protected abstract B thisObject(); //Each concrete implementing subclass builder overrides this for the same reason, but for B for the builder
protected ABuilder() {
object = getObject();
thisObject = thisObject();
}
public B withS(String s) {
object.s = s;
return thisObject;
}
public B withI(int i) {
object.i = i;
return thisObject;
}
public T build() {
return object;
}
}
}
public final class ConcreteA extends AbstractA {
private String foo;
protected ConcreteA() {
}
public static final class Builder extends AbstractA.ABuilder<ConcreteA,Builder> {
#Override protected ConcreteA getObject() {
return new ConcreteA();
}
#Override protected Builder thisObject() {
return this;
}
public Builder() {
}
public Builder withFoo(String foo) {
object.foo = foo;
return this;
}
}
}
And then in client code, it would look like...
ConcreteA baz = new ConcreteA.Builder().withFoo("foo").withS("bar").withI(0).build();
I like this example because it allows you to easily extend these classes, but it also seems to me that this defeats the purpose of using the builder pattern because the methods withS(String s) and withI(int i) act alot like setter methods. Also, this method leaves the fields of the base class and the builder class as protected rather than private.
Here's one from SO 17164375
public class NutritionFacts {
private final int calories;
public static class Builder<T extends Builder> {
private int calories = 0;
public Builder() {}
public T calories(int val) {
calories = val;
return (T) this;
}
public NutritionFacts build() { return new NutritionFacts(this); }
}
protected NutritionFacts(Builder builder) {
calories = builder.calories;
}
}
public class GMOFacts extends NutritionFacts {
private final boolean hasGMO;
public static class Builder extends NutritionFacts.Builder<Builder> {
private boolean hasGMO = false;
public Builder() {}
public Builder GMO(boolean val) {
hasGMO = val;
return this;
}
public GMOFacts build() { return new GMOFacts(this); }
}
protected GMOFacts(Builder builder) {
super(builder);
hasGMO = builder.hasGMO;
}
}
I like that this one seemingly adheres more closely to the builder pattern described by Josh Bloch and it also allows you to simply pass the builder into the constructor for the class you want to instantiate. This would be a nice way to do some validation inside the builder before instantiating the object in the call to build(). At the same time though, this example shows how you can extend the builder pattern with concrete classes, and when you do that the potential for all the nastiness that comes with extending concrete classes (e.g. inconsistent interfaces, inheriting methods which can corrupt the state of your object, etc.)
So my question is there a way to implement an abstract class with an abstract builder that also allows you to pass in a reference to a builder in the constructor for the base class? Something like:
public abstract BaseClass {
// various fields go here
...
public abstract Builder<T extends BaseClass, B extends Builder<T,B>> {
// add chaining methods here
...
public T build() {
if (isValid()) return new T(this);
else Throw new IllegalArgumentException("Invalid data passed to builder.");
}
}
public BaseClass(Builder builder) {
// set fields of baseclass here
}
}
I realize that you can't instantiate an object the way that I've shown here, but is there some other way to do it I mean? Is this possibly where a factory would go? Maybe I just have the wrong assumptions about the builder pattern in general. :) If that's the case, is there a better direction to take?
Your first example is not bad, but I don't think it is what you are looking for.
I am still a little unsure of exactly what you want, but seeing your examples do not work for you, I thought I'd give you one or two of my own. :)
class ParentBuilder{
public ConcreteParent build(){
ConcreteParent parent = new ConcreteParent();
parent.setFirst(1);
parent.setSecond(2);
parent.setThird(3);
return parent;
}
}
class ChildBuilder{
public ConcreteChild build(ParentBuilder parentBuilder){
ConcreteParent parent = parentBuilder.build();
ConcreteChild child = new ConcreteChild();
child.setFirst(parent.getFirst());
child.setSecond(parent.getSecond());
child.setThird(parent.getThird());
child.setFourth(4); //Child specific value
child.setFifth(5); //Child specific value
return child;
}
}
Any new type, would have its own builder, taking in its parent's builder.
As you can see this is similar to:
public NutritionFacts build() { return new NutritionFacts(this); }
}
protected NutritionFacts(Builder builder) {
calories = builder.calories;
}
In your example.
This however, quickly gets out of hand as well, increasingly for the number of variables and subclasses.
An alternativ, would be to use dynanic variables, have a look at this: http://martinfowler.com/apsupp/properties.pdf
Martin Fowler writes a great article specifying all the pros and cons.
Anyways, here's my second example:
public class Demo {
public static void main(String[] args) {
ConcreteBuilder builder = new ConcreteBuilder();
Concrete concrete = builder.with("fourth", "valueOfFourth").build();
for(String value : concrete.getAttributes().values())
System.out.println(value);
}
}
class ConcreteBuilder{
private Concrete concrete;
public ConcreteBuilder(){
concrete = new Concrete();
}
public ConcreteBuilder with(String key, String value){
concrete.getAttributes().put(key, value);
return this;
}
public Concrete build(){
return concrete;
}
}
class Concrete{
private HashMap<String, String> attributes;
public Concrete(){
attributes = new HashMap<>();
}
public HashMap<String, String> getAttributes(){
attributes.put("first", "valueOfFirst");
attributes.put("second", "valueOfSecond");
attributes.put("third", "valueOfThird");
return attributes;
}
}
The magic here is, you (might) no longer need all these subclasses.
If these subclasses' behavior does not change, but only their variables, you should be fine using a system like this.
I strongly advise that you read Martin Fowler article on the subject though, there are good places and bad places to do this, but I think this is a good one.
I hope this brings you closer to an answer, good luck. :)
I can't seem to figure out the best approach to tackle the following problem. Let's say there is an abstract base class with several concrete subclasses:
public abstract class AbstractType { /* common properties */ }
public class TypeA { /* properties of type A */ }
public class TypeB { /* properties of type A */ }`
These are domain classes (JPA entities). The properties of the types are (amongst other things) used to validate user data. I'm under the assumption that adding logic to the domain model itself is considered bad practice. Therefore, I want to avoid adding a validate method to the concrete subclasses. Like so:
UserInput userInput = ...;
AbstractType data = ...;
data.validate(userInput);
I don't see an option without having to cast the domain model,
if I want to move the logic to a logic layer. With the limited knowledge I have, I can only come up with following two similar "solutions", using some kind of handler interface.
Keep some explicit reference to the handler in the type
public interface TypeHandler {
public validate(AbstractType data, UserInput userInput);
}
/* TypeAHandler & TypeBHandler implementations */
public enum Type {
TYPE_A(new TypeAHandler()),
TYPE_B(new TypeBHandler());
private TypeHandler handler;
public Handler(TypeHandler handler){
this.handler = handler;
}
public TypeHandler getHandler(){ return handler; }
}
public class TypeA {
private Type type = TYPE_A;
/* ... */
}
The handler would than be called in the following manner:
UserInput userInput = ...;
AbstractType data = ...;
data.getType.getHandler().validate(data, userInput);
The reference to the handler could also be added immediately (without the enum in between) as property to the AbstractType class, but that would mean there is a reference to a class inside the logic layer from the domain model (which kind of defeats the purpose of moving the logic to a logic layer?)
The problem here too is that the validate method inside the TypeXHandler needs to cast the data argument to its subclass first before it can start validating.
Or I could implement some method which has a large if-then structure to get the right subclass, cast it and call the appropriate handler which implements an interface similar to the following.
public interface TypeHandler<T extends AbstractType> {
public validate(T data, UserInput userInput);
}
So in both cases there is casting. In the first case there is no huge if-then structure, but the logic and domain are not separated. In the second case there is a very inflexible if-then structure.
To conclude, here is my question. Should I really avoid implementing the logic directly inside the domain? If so, is there any way to avoid the casting, the if-else structure and/or adding additional properties to the domain model (like the enum in the first "solution").
At the end of the day, you're branching based on the subtype (concrete classes) since the logic to validate user input is based on those specific details contained in the subclasses.
Generics don't really help you much here since generics are based primarily on applying logic that is uniform across different types, operating on universal logic applied to a common interface that all applicable types share. Here your logic and interface varies for each subtype.
So your main choices are an inextensible solution where you're modifying central source code (like a big bunch of ifs/elses, a map, etc) and manually branching based on subtype, or using abstraction/dynamic polymorphism as an extensible solution which doesn't require modifying any central source code and automatically branches based on subtype.
Reflection might also be a possible route if you can afford it (it's a bit expensive at runtime) and provided it can fit to give you that universal logic you can implement centrally.
If you don't want to add this validate method to AbstractType and all of its subtypes, then you can always add another level of abstraction on top which does contain a validate method like ValidatorB which implements the IValidator interface and stores an object of TypeB as a member and applies the logic used to validate user input using TypeB's properties.
I studied design patterns last week and I would like to propose my solution (it works but I'm not sure that is the smartest way to resolve your problem).
The idea of my solution is to use a factory: you give a model (in your case a JPA entity) to the factory and it gives you the correct validator for that model.
At the beginning of the program, you have to tell to the factory which is the validator class for each model class of your program through a register method.
Let's start with the implementation...
AbstractModel.java
public abstract class AbstractModel
{
private final int commonProperty;
protected AbstractModel(int commonProperty)
{
this.commonProperty = commonProperty;
}
public int getCommonProperty() { return commonProperty; };
}
In the AbstractModel we put all the common properties of the models.
ModelA.java
public class ModelA extends AbstractModel
{
private final int specificProperty1;
private final int specificProperty2;
public ModelA(int commonProperty, int specificProperty1, int specificProperty2)
{
super(commonProperty);
this.specificProperty1 = specificProperty1;
this.specificProperty2 = specificProperty2;
}
public int getSpecificProperty1() { return specificProperty1; }
public int getSpecificProperty2() { return specificProperty2; }
}
ModelA has got two specific properties.
ModelB.java
public class ModelB extends AbstractModel
{
private final int specificProperty1;
private final int specificProperty2;
public ModelB(int commonProperty, int specificProperty1, int specificProperty2)
{
super(commonProperty);
this.specificProperty1 = specificProperty1;
this.specificProperty2 = specificProperty2;
}
public int getSpecificProperty1() { return specificProperty1; }
public int getSpecificProperty2() { return specificProperty2; }
}
ModelB has got two specific properties too.
Let's say that an instance a of ModelA is valid iff
a.commonProperties == a.specificProperty1 + a.specificProperty2
and an instance b of ModelB is valid iff
b.commonProperties == b.specificProperty1 * b.specificProperty2
Validator.java
public interface Validator
{
public boolean validate();
}
A really simple interface for the validators.
AbstractValidator.java
public abstract class AbstractValidator implements Validator
{
private final AbstractModel toBeValidated;
protected AbstractValidator(AbstractModel toBeValidated)
{
this.toBeValidated = toBeValidated;
}
protected AbstractModel getModel()
{
return toBeValidated;
}
}
This is the superclass of the concrete validators that wraps the model to be validated.
ValidatorA.java
public class ValidatorA extends AbstractValidator
{
protected ValidatorA(AbstractModel toBeValidated)
{
super(toBeValidated);
}
public boolean validate()
{
ModelA modelA = (ModelA) getModel();
return modelA.getCommonProperty() == modelA.getSpecificProperty1() + modelA.getSpecificProperty2();
}
}
The validator for the instances of ModelA.
ValidatorB
public class ValidatorB extends AbstractValidator
{
protected ValidatorB(AbstractModel toBeValidated)
{
super(toBeValidated);
}
public boolean validate()
{
ModelB modelB = (ModelB) getModel();
return modelB.getCommonProperty() == modelB.getSpecificProperty1() * modelB.getSpecificProperty2();
}
}
And this is the validator for the instances of ModelB.
And finally it comes the factory!
ValidatorFactory.java
public class ValidatorsFactory
{
private static ValidatorsFactory instance;
private final HashMap<Class<? extends AbstractModel>, Class<? extends Validator>> registeredValidators;
private ValidatorsFactory()
{
registeredValidators =
new HashMap<Class<? extends AbstractModel>, Class<? extends Validator>>();
}
public static ValidatorsFactory getInstance()
{
if (instance == null)
instance = new ValidatorsFactory();
return instance;
}
public void registerValidator(
Class<? extends AbstractModel> model,
Class<? extends Validator> modelValidator)
{
registeredValidators.put(model, modelValidator);
}
public Validator createValidator(AbstractModel model)
{
Class<? extends Validator> validatorClass = registeredValidators.get(model.getClass());
Constructor<? extends Validator> validatorConstructor = null;
Validator validator = null;
try
{
validatorConstructor = validatorClass.getDeclaredConstructor(new Class<?>[] { AbstractModel.class });
validator = (Validator) validatorConstructor.newInstance(new Object[] { model });
}
catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
System.err.println(e.getMessage());
// handle exception
}
return validator;
}
}
The factory is a singleton with two significant method:
registerValidator to add a new pair (modelClass, validatorClass) in the HashMap.
createValidator to obtain the correct validator for the specified model.
This is how to use this pattern:
public class Main
{
public static void main(String args[])
{
ValidatorsFactory factory = ValidatorsFactory.getInstance();
factory.registerValidator(ModelA.class, ValidatorA.class);
factory.registerValidator(ModelB.class, ValidatorB.class);
ModelA modelA = new ModelA(10, 4, 6);
if (factory.createValidator(modelA).validate())
System.out.println("modelA is valid");
else
System.out.println("modelA is not valid");
ModelB modelB = new ModelB(10, 8, 2);
if (factory.createValidator(modelB).validate())
System.out.println("modelB is valid");
else
System.out.println("modelB is not valid");
}
}
output:
modelA is valid [because 10 = 4 + 6]
modelB is not valid [because 10 != 8 * 2]
Note that the model is completely separeted from the controller and it uses only one cast from AbstractModel to a concrete model.
Hope it helps!