chain-of-responsibility handler with java generics - java

I'm using the Chain of Responsibility design-pattern in Java. The chain as a whole represents a request for objects of certain types. Each "Handler" in the chain is responsible to handle the requested units of 1 type.
All requests are handled in essentially the same way so I tried making the "Handler"-class generic.
So in the Handle-class I need a method like this (the handling itself is simplified because it would only obfuscate my problem):
public class Handler<T>{
int required;
Handler<?> next;
public void handle(Object O){
if(o instanceof T){
required --;
}else{
next.handle(o);
}
}
}
The problem is that an instanceof like this is impossible. Because the type T isn't explicitly stored during run time (or that's what I understood during my research on the internet). So my question is: what is the best alternative?

Implement handlers using generics by using a constructor parameter to define the class the handler supports:
public class Handler<T> {
private int required;
private Handler<?> next;
private Class<? extends T> c;
public Handler(Class<? extends T> c) {
this.c = c;
}
public void handle(Object o) {
if (c.isInstance(o)) {
required--;
} else {
next.handle(o);
}
}
// ...
}

It looks like you're not actually using a chain at all, unless you have some cases where both base and sub classes kick off events. If that unless part doesn't apply, you could do something like
Map<Class, Handler> handlers = //...initialize however
and in root handler:
public void handle(Object o) {
handlers.get(o.getClass()).handle(o);
}

It doesn't make sense to have a handler using generics if you call handle on every object.
Either you instantiate an handler for type like this:
public class Handler<T>{
int required;
Handler<?> next;
public void handle(T O){
...
}
}
or you define a abstract class handler and let the specific subclass to handle specific type or just pass the event to the chain.
Also using
if( x.isInstance(o)) {...}
is really an antipattern and you can break OOP rules.

It would be ugly, but you could try this:
public abstract class Handler {
int required;
Handler next;
public void handle(Object o){
if(getMyClass().isInstance(o)){
required --;
}else{
next.handle(o);
}
}
protected abstract Class getMyClass();
}

Related

Inherit generic type in nested enum implementing interface

I try to write a generic abstract class for my state machine, that will be utilizing enum implementing some interface defined inside that abstract class. I have an abstract class which contains a field implementing a generic interface and some wrapper functions for state switching logic. I try to extend this abstract class and create nested enum type implementing this generic interface, but there are some places, where I have to define explicitely which types I am using for generics. The code below demostrates this problem
public abstract class FiniteStateMachine<C, I> { // <- generic types declared here
private State<C, I> currentState;
protected FiniteStateMachine(State<C, I> initial){ currentState = initial; }
// some other methods for FSM, that I don't want to include in State<>
// ...
public synchronized void process(C context, I input) {
State<C, I> nextState = currentState.process(context, input)
if(currentState != nextState){
currentState.onExit(nextState, context);
State<C, I> previousState = currentState;
currentState = nextState;
nextState.onEnter(previousState, context);
}
}
public interface State<C, I> { //<- this interface should use the same types as FiniteStateMachine
State<C, I> process(C context, I input);
default void onEnter(State<C, I> s, C context) {}
default void onExit(State<C, I> s, C context) {}
}
}
class FSM extends FiniteStateMachine<Data, String> { // <- here I define types used for FSM
public FSM() { super(FSMStage.START); }
enum FSMState implements State<Data, String> { // <- and here I have to repeat them
START{
#Override
public FSMState process(Data p, String s) {
// ...
return NEXT;
},
#Override
public void onExit(State s, Data d) { /* ... */ }
},
NEXT{
// ...
}
}
}
The main concern is that type information is defined in multiple places in extending class - once in type info of the abstract class and onec in interface the enum implements.
FiniteStateMachine is abstract and not an interface because I need some flags and initial state fields (and I can't make an "abstract field" otherwise than with protected constructor hack). FiniteStateMachine.State is an interface, because it's used in enums which cannot be extended. I also want to keep FiniteStateMachine and FiniteStateMachineState in one file, because separate fiels create lots of bloat content in project. Also inside extending FSM the onExit method has a type of State instead of FSMStage.
I tried something like FiniteStateMachine<C, I, State<C, I>> but errors said that 'State is not accessible in the context'.
Is there any way to declare the types in one place in extending class instead of FSM and FSMState like right now? Or maybe there is a way to declare types only for FSMState and make FSM reuse those types? Or maybe this design is completely flawed?
The point is that inner interfaces (and enums too btw) are implicitely static, so they cannot use generic parameters of outer class, because they have no access to instances of the outer class.
So basically this interface is inside the abstract class only for code convenience, you may aswell extract it to separate file. In this design I don't think there is a way to skip multiple generic type declarations.
I think changing the design just to avoid the re-declaration is not worth it - you could make State an abstract class and remove generic types from declaration so it gets generic types from the outer class, but then the idea with enums doesn't work.
C in FiniteStateMachine is not the same C in State class, If you want to make them dependent, you have to define a third type in your FiniteStateMachine which uses C and I with State. You were almost right with FiniteStateMachine<C, I, State<C, I>>, but here how you can do it :
public abstract class FiniteStateMachine<C, I, T extends FiniteStateMachine.State<C, I>> {
private T currentState;
protected FiniteStateMachine(T initial){ currentState = initial; }
public synchronized void process(C context, I input) {
FiniteStateMachine.State<C, I> nextState = currentState.process(context, input);
if(currentState != nextState){
currentState.onExit(nextState, context);
State<C, I> previousState = currentState;
currentState = (T) nextState;
nextState.onEnter(previousState, context);
}
}
public interface State<CTX, INPT> {
State<CTX, INPT> process(CTX context, INPT input);
default void onEnter(State<CTX, INPT> s, CTX context) {}
default void onExit(State<CTX, INPT> s, CTX context) {}
}
}
Now you force the types of State to be same as those defined in FiniteStateMachine.
You can use it now like :
public class FSM extends FiniteStateMachine<Date, String, FSM.FSMState> {
public FSM() { super(FSMState.START); }
public enum FSMState implements FiniteStateMachine.State<Date, String> {
START{
#Override
public FSMState process(Date p, String s) {
// ...
return NEXT;
}
#Override
public void onExit(FiniteStateMachine.State s, Date d) { /* ... */ }
},
NEXT{
#Override
public FiniteStateMachine.State<Date, String> process(Date context, String input) {
return null;
}
// ...
}
}
}
Otherwise, what about repeating the generic types !? From what i've learned so far, there's no way to simplify the writing of your classes. I think the origin of your question was when the two classes are declared in the same file. What if they were separated in two different files ? Do you continue thinking this way ?

Java - Handling generics with inheritance

I have a class that represents a vendor service and all their services have an authentication and an execute method.
I started thiking of an abstract class that represents this as below.
The thing is each of their services require a different request object, so I thought of using generics.
The problem is that if use it, I can't handle the specifics of each request object. Each children must use some methods from the type.
1) Should I try to make this way I'm trying, or remove this executeRequest method from the abstract class and each subclass implement it with the correct type?
2) I always hear "prefer composition over inheritance". Should I move the executeRequest to an interface?
Thanks in advance!
public abstract class VendorService {
private final VendorInitialization VendorInitialization;
//a bean with some auth params
public VendorService(VendorInitialization VendorInitialization) {
this.VendorInitialization = VendorInitialization;
}
protected abstract <T> boolean validateRequest(T requestObject) throws VendorServiceBadRequest;
protected abstract <T, P> P executeRequest(T requestObject);
}
public class VendorServiceAllocation extends VendorService {
public VendorServiceAllocation(VendorInitialization VendorInitialization) {
super(VendorInitialization);
}
#Override
protected <T> boolean validateRequest(T requestObject) throws VendorServiceBadRequest {
//List<BeanAllocation> requestObject = new Arraylist<>(); //I was using like this before
//TODO: how to handle it as list of on this specific case?
if (requestObject == null || requestObject.size() == 0) {
throw new VendorServiceBadRequest(String.format("The list must have at least one element"));
}
//TODO: requestObject.get(0).getMySpecificFieldFromBeanAllocation will not work
//some checks
return true;
}
#Override
protected <T, P> P executeRequest(T requestObject) {
//executes and return a list of objects specific to this class
return new List<BeanAllocationResponse>();
}
}
Edit, for clarification:
In the child class VendorServiceAllocation, I need to use some methods that are specific of that type.
E.g.: Inside executeRequest, I need to call requestObject.customFunctionFromChild()
I think niceman hit the nail on the head, though I am not quite sure what you are asking. eg.
abstract class Service<T,P>{
abstract public P processRequest(T t);
}
Then you can implement it in one of two ways.
class StringService extends Service<String, String>{
public String processRequest(String t){
return t;
}
}
Or you could leave it to still be Generic and the actual instances would have the different types.
class OtherService<T> extends Service<T, String>{
public String processRequest(T t){
return t.toString();
}
}
Where you could use it as,
OtherService<Integer> is = new OtherService<>();

Calling ungeneric methods from generic method in java

Consider the following:
public class Doer {
public static void doStuff(A a) {
System.out.println("a");
}
public static void doStuff(B b) {
System.out.println("b");
}
}
Where B extends A
And a generic class like this:
public class NewClass<T extends A> {
public void doSomething(T entity) {
Doer.doStuff(entity);
}
}
If I call this method as follows it prints "a"
new NewClass<B>().doSomething(new B());
How do I get it to print "b" ?
Thanks in advance
Edit: A dirty solution is to change
Doer.doStuff(entity);
to
if(entity instanceof B){
Doer.doStuff((B) entity);
}else {
Doer.doStuff(entity);
}
But I'm looking for a solution that does not use instanceof and so that I don't have to add an extra if (C intance of A) ... to NewClass when I make a new Class extending A
See these questions for answers: Java Generic / Type Dispatch Question, How does Java method dispatch work with Generics and abstract classes?
Basically, you have these options:
define doStuff as an abstract method on A
try the Visitor pattern
if possible, use a language (e.g. Xtend) that supports dynamic dispatch
Java doesn't do dynamic binding based on the argument type. The actual method that is invoked is determined at compile time. So in case of a generic type, the method with Object as the parameter type will be invoked.
You could work around this by checking the type with instanceof, but the puristic way of handling this is to leverage polymorphism and using Double Dispatch. But that is not always an option, since it tightly couples your calling class and your argument class together.
I think that in that case you're forced to actually determine entity's type and cast it, as your function doSomething just infers that entity inherits from A.
Basically you could do:
public void doSomething(T entity) {
if (entity instanceof B) {
Doer.doStuff((B) entity);
}
else {
Doer.doStuff(entity);
}
}
NewClass would have to have two methods also, or you could do something like this:
public class NewClass<T extends A> {
public void doSomething(T entity) {
if(entity instanceof B){
Doer.doStuff((B)entity);
}else if(entity instanceof A){
Doer.doStuff((A)entity);
}
}
}

Overloading / generics in Java

I want to run certain tests in Lists. The Lists can contain entirely different classes.
I have one method to check the consistency of the list - not null, not empty, no more than x elements. This is common to all the lists. Then I want to test each of the objects, using overloading.
The idea would be something like:
public static <T> void check(List<T> list) {
//do general checks
for (T element : list) {
check(element);
}
}
and then
public static void check(SomeType element) {...}
public static void check(SomeOtherType element) {...}
But I also had to add a method like this:
public static void check(T element) {...}
And this was called at runtime - not my other methods with the specific classes. Although the class was exactly the same. I'm evidently missing some generics understanding.
Now if I don't use the general method at all and try to solve it this way:
public static void check(List<SomeType> list) {...}
public static void check(List<SomeOtherType> list) {...}
Compiler error - "Method check(List) has the same erasure check(List) as another method..."
So is there any elegant solution for this? I could just use different method names but would like to know how it's possible without that.
Thanks!
This isn't something about generics that you're missing. Java does not have double dispatch. The call to check must be resolved at compile-time, and check(T) is the only match since the compiler can't tell if T is SomeType or SomeOtherType in a given scenario. It needs to choose one method to call that will work for all possible Ts.
This is sometimes solved using the visitor pattern.
The problem should be solved by the caller. When it instanciate your class with a concrete type for T, it should also pass an instance of Checker<T> with the same concrete type:
public class SomeClass<T> {
private List<T> list;
private Checker<T> checker;
public SomeClass(Checker<T> checker) {
this.checker = checker;
}
public void check() {
checker.check(list);
}
}
public interface Checker<T> {
public void check(List<T> list);
}
...
SomeClass<Foo> someClass = new SomeClass<Foo>(new Checker<Foo>() {
#Override
public void check(List<Foo> list) {
// do whatever you want here
}
});
You can use instanceof to dispatch:
public static <T> void check(List<T> list) {
for (T element : list) {
check(element);
}
}
public static void check(T t) {
if (t instanceof SomeType) {
SomeType someType = (SomeType) t;
// code for SomeType ...
} else if (t instanceof OtherType) {
OtherType otherType = (OtherType) t;
// code for OtherType ...
} else {
// we got a type that we don't have a method for
}
}
With generics, the type parameter is actually erased during compilation, and the list object don't know anything about the static type of the object it contains. Since it doesn't know it, it can not use overloading to call methods with different parameters, because Java doesn't support multiple dispatch.
You have then three choices:
Make your objects implement a Checked interface with a check method that does the check logic. Downside is that the check logic is now dispersed in several places and it is not practical if you have objects of classes you don't have control of.
Use instanceof to call explicitly the check methods according to the dynamic type of the object. Downside is you potentially end up with a big if/else block a bit harder to maintain.
Implement the visitor pattern. Downside is that you have to change the object classes too, but the check logic stay in a single place.
Since the type of the variable is lost in check(List<T> list) you have two options:
1. Do different things by checking runtime type
check(T element) {
if (element.getClass().equals(SomeType.class)) {
check((SomeType) element);
} elseif (element.getClass().equals(SomeOtherType.class)) {
check((SomeOtherType) element);
}
This can be made a little more sophisticated, for example by wrapping each check in a Callable and using a Map<Class, Callable>
This is similar to visitor pattern.
2. Calling a virtual method on the element to be checked itself
If the checking logic can be pushed to the object to be checked itself (this is not necessarily a bad thing) then you don't need to check types:
interface Checkable { void check(); }
class SomeType implements Checkable { .... }
class SomeOtherType implements Checkable { .... }
Then:
public static <T extends Checkable> void check(List<T> list) {
for (T element : list) {
element.check();
}
}
These are the only two options, any implementation has to be a variation on one of these

Alternative to instanceof approach in this case

Hello I'm wondering what would be some more elegant alternatives to something like this:
class Base...
class A extends Base...
class B extends Base...
//iterator of colection containing mixed As and Bs i want to remowe Bs and do omething with As
while(iterator.hasNext()) {
Base next = iterator.next();
if(next instanceof A) // do something
if(next instanceof B)
iterator.remove();
}
Sow what are the alternatives...
Thank you for advices.
edit: Base class may have many subclasses not just two and their numbers may grow in time
You can create methods in Base and override them in A and B.
For example:
class Base{
public boolean shouldRemove(){
return false;
}
public void doSomething(){
}
}
class A extends Base{
#Override
public void doSomething() {
}
}
class B extends Base{
#Override
public boolean shouldRemove() {
return true;
}
}
and then you don't need know what class the object is an instance of:
while(iterator.hasNext()) {
Base next = iterator.next();
if(next.shouldRemove()){
iterator.remove();
}
else{
next.doSomething();
}
}
Do you really need to remove them from the list? Why don't you just have the method to do something in the Base class (doing nothing) and then just override it do to what you want on class A.
class Base{
public void doSomething(){
}
}
class A extends Base{
#Override
public void doSomething(){
// do something
}
}
Then you could just iterate over the list and calling the method doSomething on all objects.
for(Base base : list) {
base.doSomething();
}
This way only the classes that have overridden the doSomething() method will actually do something. All the other classes will just execute the dummy implementation in the Base class.
If Base was an abstract class you could declare the doSomething() as abstract and have the extending classes implement it. With this approach all classes would have to implement the method and classes for which you don't want any computation to be performed you would just provide a dummy implementation of that method. Alternatively you could even create an interface with the doSomething() method and have (which could even be a better decision) and have the Base class implement it, given that only the extending classes would actually implement the method.
instanceof is a good way to filter objects by type - and that's what you want to do. You have a mixed collection and so you need some kind of filter, either filter the input (store nothing but As) or filter the output (process nothing but As).
If you just don't like "instanceof", you could use an enum to specify the type and add a final method to get the type at Base:
enum Type { ATYPE, BTYPE };
public Base {
final private Type type;
public Base(Type type) { this.type = type; }
public Type getType() { return type; }
// ...
}
public A {
public A() { super(Type.ATYPE); }
}
while(iterator.hasNext()) {
Base next = iterator.next();
switch (next.getType) {
case ATYPE: // do something and break
case BTYPE: iterator.remove(next); break;
}
}
i think is very short and clear solution and has no alternatives (without code growing),
just add else if instead of if in second case
Also you can split code on function calls, and if statement will not be huge
Another solution is to create Map of delegates that will be called. Like this:
interface ISimpleDelegate{ void doSomeLogic(Base b) }
`Map delegates = new HashMap();
After this add your logic as anonymous classes that realizes ISimpleDelegate.
delegates.put(A.class, new ISimpleDelegate() { //write your logic here });
I hope that the idea is clear
And in your loop you just call delegates:
while(iterator.hasNext()) {
Base next = iterator.next();
delegates.get(next.getClass()).doSomeLogic(next);
}
In general, a nice solution to avoid instanceof is to use the so-called visitor pattern.
For this pattern, you need an additional interface (the Visitor), an implementation of it that contains the code you want to execute and an additional method in all classes of your hierarchy, so this might be overkill in small cases (but it is very handy if there is not only A and B, but more types).
In your case it would look like this:
interface Visitor {
void visit(A a);
void visit(B b);
}
class Base {
abstract accept(Visitor v);
}
class A extends Base {
accept(Visitor v) {
v.visit(this);
}
}
class B extends Base {
accept(Visitor v) {
v.visit(this);
}
}
class MyVisitor implements Visitor {
visit(A a) {
doSomethingWithA(a);
}
visit(B b) {
doSomethingWithB(b);
}
}
It is used like this:
MyVisitor v = new MyVisitor();
while(iterator.hasNext()) {
Base next = iterator.next();
next.accept(v);
}
An advantage is that you have to write most of the code only once. If you want to do other things with A and B in another place of your program, just write another implementation of Visitor. You don't need to modify Base, A and B as you would if you'd add doSomething() to these classes.
Edit:
If the number of sub-classes increases, you need to change all your existing implementations of Visitor. However, at least the compiler tells you about that. With instanceof you might end up forgetting a place where you need to add a handling clause. This can at most be detected at runtime, whereas the visitor pattern gives you compile-time safety.

Categories