repetition is bad, repetition is bad
Post on 12-Apr-2017
21 Views
Preview:
TRANSCRIPT
title
subtitle
Repetition is bad, repetition is bad
Michele Giacobazzi – WellD SaglVoxxed days Ticino 18 april 2015www.welld.ch
article
title
A «harder» case of repetition Repeated code is above and below the «Dynamic» part Use of variables and resources makes refactoring harder In our example there are 6 main actions:
1. User retrieval2. Connection to remote system3. Dynamic call4. Exception handling5. Closing the connection6. Action auditing (log)
REPETITION
CODE
REPETITION
public Squid findSquids(String token, Map<String,Object> criteria) {BEConnector connector = null;Squid result = null;//1 Get the operatorVoxxedOperator operator = login.getOperator(token);if (operator == null) {
logger.warn("invalid operator token " + token); return null;
}try {
//2 estabilish connection and get remote service facadeconnector = ConnUtility.getBEConnector();VoxxedFacade service = ConnUtility.getVoxxedFacade(connector);//3 The real action!result = service.findSquidByCriteria(operator, criteria);
} catch (Exception e) { //4 log and handle exceptionlogger.error("Error in findSquids", e);result = null;
} finally {//5 release the connectionConnUtility.releaseBEConnector(connector);
}// 6 audit the action (log)logger.info("findSquids executed with params " + criteria + " and result " + result);return result;
}
article
title
Java reflection - Method java.lang.reflect.Method Obtained with class.getMethod(String name, Class<?>... parameterTypes) Executed with method.invoke(Object context, Object... parameters)
public class BeMethodCall{
//Token. To be provided.private String token;
private Method method;
private Object[] params;
public BeMethodCall(Method method, String token, Object[] params) {
super();this.token = token;
}
//[getters and setters]
}
article
title
Java reflection - Method Standard Java Only single method call Returns Object Needs wrapper object Verbose syntax
article
title
Callable Task java.util.concurrent.Callable Interface Callable<V> A simple method call() that returns V.
public abstract class BeTask<T> implements Callable<T> {
//Token. To be provided.private String token;//Facade. Injected by BetaskExecutor.private VoxxedFacade service;//Operator. Injected by BetaskExecutor.private VoxxedOperator operator;
public BeTask(String token) {
super();this.token = token;
}
//[..] Getters and setters}
public Squid getSquidsWithTask(String token, final Map<String,Object> criteria) {
Squid result= beTaskExecutor.executeBeCall(new BeTask<Squid>(token) {
@Overridepublic Squid call() throws Exception {
return this.getService().findSquidByCriteria(this.getOperator(),criteria);
}
});
// 6 audit the action (log)logger.info("getSquidsWithTask executed with params " + criteria
+ " and result " + result);return result;
}
article
title
Callable Task Standard Java Simple code in DAO Allows the use of generic Parameters must be final Resources must be injected Does not allow auditing (log)
article
title
Java 8 function java.lang.FunctionalInterface Must have a single method Can be used with lambdas Common function types in java.util.function Create your own
@FunctionalInterfacepublic interface BeFunctionInterface<T> {
T execute(VoxxedOperator operator, VoxxedFacade service);
}
public abstract class BeFunction<T> implements BeFunctionInterface<T>{
private String token;
public BeFunction(String myToken) {super();this.token = myToken;}
public String getToken(){return token;}
public abstract T execute(VoxxedOperator operator, VoxxedFacade service);
}
public Squid getSquidsWithFunction(String token, final Map<String,Object> criteria) {
Squid result= beFunctionExecutor.executeFunction(new BeFunction<Squid>(token) {
@Overridepublic Squid execute(VoxxedOperator operator, VoxxedFacade service) {
return service.findSquidByCriteria(operator, criteria);}
});
// 6 audit the action (log)logger.info("getSquidWithFunction executed with params " + criteria
+ " and result " + result);return result;
}
article
title
Java 8 function Needs Java 8 Better syntax and parameter handling Does not allow auditing (log) Parameters must be final
article
title
Interceptor javax.interceptor.Interceptor Annotate a method with AroundInvoke Access to InvocationContext Returns a result
@LogMethod@BeConnectionpublic Squid findSquids(@BeFacade VoxxedFacade service, String token, Map<String,Object> criteria) {
Squid result = null;//1 Get the operatorVoxxedOperator operator = loginManager.getOperator(token);if (operator == null) {
logger.warn("invalid operator token " + token); return null;
}
//3 The real action!result = service.findSquidByCriteria(operator, criteria);
//Exception and Connection close handling in interceptor.
//Log handled in interceptor.return result;
}
article
title
Interceptor Needs container support Wraps the method execution Has access to method data Can manipulate parameter Relies on method signature
article
title
A small comparison
Support Syntax Completeness
Method Standard Java Mah.. Full
Task Standard Java Acceptable Partial (no log)
Function Java 8 Good! Partial (no log)
Interceptor Container library Depends Partial
article
title
Our solution: function + interceptor
article
title
Discussion! Questions and suggestions Find me around or at WellD stand Other approaches: dependency injection, decorator, filters… Contacts: Michele.Giacobazzi@Welld.ch Twitter: @Smirne WellD: www.welld.ch
top related