5

我有一个接受三个泛型类型参数的类。我想知道这样做是否好。我的意思是这被认为是设计气味吗?假设某个类的泛型参数数量的近似限制更多?

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

}

在哪里

ST- 是内部状态机的状态

EV- 是内部状态机的事件

PEV- 是我用于状态机之间通信的父状态机的事件

更新内部状态机包含在另一个作为父状态机的状态机中。因此,如果内部状态机想要在父级上触发某个事件,那么它会使用其中一个PEV事件来执行此操作,然后父级使用该事件来进行某些转换并更改其状态并执行某些操作。

4

3 回答 3

1

您可以执行以下代码。不过,初始化内部状态机有点难看。

编辑:添加通用父事件。

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());
    }
}
于 2013-04-04T19:42:37.577 回答
0

根据您的描述,在我看来,您的 3 个通用类类型更像是您的类的属性。如果对于例如您的 ST 类类型,您想要使用任何一个,泛型将是正确的

Enum StateEnum1 { idle, busy }

有时你想使用

Enum StateEnum2 { Idle, QuiteBusy, VeryBusy }.

但是,如果您的 3 种泛型类类型中的每一种都只考虑一个 Enum,那么泛型就不合适了。

于 2013-04-04T06:53:04.520 回答
0

我建议将您的枚举包装到一个接口中(实现接受枚举),然后将该类型用作通用参数 - 从您的描述来看,枚举的外观属于一个内聚单元。

看起来 ST 和 PEV 也属于自己的界面——其中大部分是基于问题上下文的推测。

于 2013-04-04T08:38:34.667 回答