5

3 つのジェネリック型引数を取るクラスがあります。それでいいのかな?と思いました。これはデザイン臭ということでしょうか。一部のクラスで、ジェネリック引数の数のおおよその制限を超えるものがあるとします。

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

}

どこ

ST- 内部ステートマシンの状態です

EV- 内部ステートマシンのイベントです

PEV- ステート マシン間の通信に使用する親ステート マシンのイベントです。

UPDATE :内部ステート マシンは、親である別のステート マシンに含まれています。したがって、内部ステート マシンが親で何らかのイベントを発生させたい場合はPEV、親が何らかの遷移を行い、その状態を変更し、何らかのアクションを実行するために使用するイベントの 1 つを使用してそうします。

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

列挙型をインターフェイスにラップし(列挙型を受け入れる実装を使用)、その型をジェネリックパラメーターとして使用することをお勧めします-あなたの説明から、列挙型の外観はまとまりのあるユニットに属します。

また、ST と PEV は独自のインターフェイスに属しているように見えます。その多くは、質問のコンテキストに基づく憶測です。

于 2013-04-04T08:38:34.667 に答える