Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do too many generic types in class mean bad design?

Tags:

java

generics

I have a class that takes three generic type arguments. I was wondering if that is good to do. I mean is this considered as design smell? Suppose some class has even more then what is an approximate limit to the number of generic arguments?

class InnerStateMachine<ST extends Enum<?>,EV extends Enum<?>,PEV extends Enum<?>>{

}

Where

ST - are the states of inner state machine

EV - are events of inner state machine

PEV - are the events of parent state machine that I use for communication between state machines

UPDATE: The inner state machine is contained with another state machine which is the parent. So if inner state machine wants to fire some event on parent then it does so using one of PEV events which then parent uses to do some transition and change its state and perform some action.

like image 979
Narendra Pathai Avatar asked Nov 13 '22 08:11

Narendra Pathai


1 Answers

You can do something like the code below. It's a little ugly to initialize the inner state machines though.

edit: add generic parent event.

import java.util.*;
interface Event {}
enum AEvent implements Event {
    e1
}
enum BEvent implements Event {
    e1
}
interface State {
    State processEvent(Event event);
}
enum AState implements State {
    s1,s2;
    public State processEvent(Event event) {
        return eventToState.get(event);
    }
    final Map<Event,State> eventToState=new TreeMap<Event,State>();
}
enum BState implements State {
    s1,s2;
    public State processEvent(Event event) {
        return eventToState.get(event);
    }
    final Map<Event,State> eventToState=new TreeMap<Event,State>();
}
interface ParentEvent {}
enum ParentEvents implements ParentEvent {
    e1;
}
class InnerStateMachine<St extends Enum<?> &State,Ev extends Enum<?> &Event,PEV extends Enum<?> &ParentEvent> {
    public InnerStateMachine(St state) {
        this.state=state;
    }
    St state() {
        return state;
    }
    St processEvent(Ev event) {
        State s=state.processEvent(event);
        if(s instanceof Enum<?>) {
            PEV pev=stateToParentEvent.get(s);
            if(pev!=null)
                System.out.println("fire parent event "+pev);
            return state=(St)s; // unsafe cast
        } else throw new RuntimeException("oops");
    }
    St state;
    Map<St,PEV> stateToParentEvent=new TreeMap<St,PEV>();
}
public class So15804185 {
    public static void main(String[] args) {
        AState.s1.eventToState.put(AEvent.e1,AState.s2);
        BState.s1.eventToState.put(BEvent.e1,BState.s2);
        InnerStateMachine<AState,AEvent,ParentEvents> innerStateMachineA=new InnerStateMachine<AState,AEvent,ParentEvents>(AState.s1);
        innerStateMachineA.stateToParentEvent.put(AState.s2,ParentEvents.e1);
        innerStateMachineA.processEvent(AEvent.e1);
        System.out.println(innerStateMachineA.state());
        InnerStateMachine<BState,BEvent,ParentEvents> innerStateMachineB=new InnerStateMachine<BState,BEvent,ParentEvents>(BState.s1);
        innerStateMachineB.processEvent(BEvent.e1);
        System.out.println(innerStateMachineA.state());
    }
}
like image 175
Ray Tayek Avatar answered Nov 14 '22 22:11

Ray Tayek