Перечисление в перечислении - PullRequest
29 голосов
/ 04 января 2012

Дело не в том, что я застрял, а скорее в поиске аккуратного способа написания своего кода.

По сути, я пишу приложение, управляемое событиями.Пользователь инициирует событие, событие отправляется соответствующим объектам, и объекты обрабатывают события.Сейчас я работаю над написанием методов четного обработчика, и я надеялся использовать операторы switch, чтобы определить, как обрабатывать событие.Прямо сейчас, пока я работаю над общей структурой, класс событий действительно прост:

public class Event {

    public static enum Action {
        MOVE, FOO, BAR
    }

    private Action action;
    private int duration;

    public Event(Action action, int duration) {
        this.action = action;
        this.duration = duration;
    }

    public Action getAction() {
        return action;
    }

    public int getDuration() {
        return duration;
    }

Затем в другом классе у меня будет что-то вроде:

public void handleEvent(Event evt) {    
    switch(Event.getAction()) {
        case MOVE: doSomething(); break;
        case FOO:  doSomething(); break;
        case BAR:  doSomething(); break;
        default: break; 
    }
}

хотелось бы сделать что-то вроде этого (хотя я бы, конечно, вставил операторы switch в их собственные функции, чтобы избежать превращения в неприятный комок из переключателей и кейсов):

public void handleEvent(Event evt) {    
    switch(Event.getAction()) {
        case MOVE: switch(Event.getAction()) {
                       case UP:    break;
                       case DOWN:  break;
                       case LEFT:  break;
                       case RIGHT: break;
                   }
        case FOO:  break;
        case BAR:  break;
        default:   break; 
    }
}

Итак, я бы хотел создать вложенные перечисления ... вот так:

public static enum Action {
    public enum MOVE {UP, DOWN, LEFT, RIGHT}, FOO, BAR
}

Не то, чтобы я не мог избежать сценария, это было бы просто ... удобно.Итак, хотя вышесказанное на самом деле не работает, есть ли подобный метод для достижения этой цели?Было бы неплохо, если бы я мог отправить событие с действием «MOVE.UP», и метод сначала идентифицировал бы его как действие типа MOVE, а затем дополнительно определил, что оно конкретно в направлении UP.Это просто простой пример, было бы здорово, если бы я мог также создавать более длинные цепочки, что-то вроде «DELETE.PAGE1.PARAGRAPH2.SENTENCE2.WORD11.LETTER3».На мой взгляд, мне просто нужно использовать строки и множество операторов if / else.Надеюсь, есть лучший способ!(Да, и производительность имеет значение в моем случае, если это поможет)

Ответы [ 3 ]

32 голосов
/ 04 января 2012

Я считаю, что в Java вы можете просто вкладывать перечисления, если ваши первичные не-константы стоят первыми.

enum Action
{
    FOO,
    BAR;
    enum MOVE
    {
         UP,
         DOWN,
         LEFT,
         RIGHT 
    }
}

Это компилирует для меня и дает мне поведение, которое вы искали.

7 голосов
/ 04 января 2012

Возможно использовать иерархию наследования для событий?

Итак, у вас есть:

- abstract Event
-- MoveEvent(Direction)
-- FooEvent()
-- BarEvent()

Может иметь смысл иметь:

- abstract Event
-- abstract MoveEvent
--- MoveUpEvent
--- MoveDownEvent
--- MoveRightEvent
--- MoveLeftEvent
-- FooEvent
-- BarEvent

Если все события Move имеют расстояние, то передайте его в конструктор MoveEvent (который будет смещаться вниз).

3 голосов
/ 20 января 2012

вы можете вкладывать их в произвольном порядке, например:

вложенный пакет;

import java.util.*;
import nested.Citrus.Orange;
interface HasChildren {
    Set<Enum<?>> children();
}
enum Citrus implements HasChildren {
    lemon, lime, orange;
    Set<Enum<?>> children;
    enum Orange implements HasChildren {
        navel, valencia, blood;
        Set<Enum<?>> children;
        enum Navel implements HasChildren {
            washinton, lateLane, caraCaraPink;
            public Set<Enum<?>> children() {
                return null;
            }
        }
        static {
            navel.children = new LinkedHashSet<Enum<?>>();
            navel.children.addAll(EnumSet.allOf(Navel.class));
        }
        enum Blood implements HasChildren {
            moro, taroco;
            public Set<Enum<?>> children() {
                return null;
            }
        }
        static {
            blood.children = new LinkedHashSet<Enum<?>>();
            blood.children.addAll(EnumSet.allOf(Blood.class));
        }
        public Set<Enum<?>> children() {
            return children != null ? Collections.unmodifiableSet(children) : null;
        }
    }
    static {
        orange.children = new LinkedHashSet<Enum<?>>();
        orange.children.addAll(EnumSet.allOf(Orange.class));
    }
    public Set<Enum<?>> children() {
        return children != null ? Collections.unmodifiableSet(children) : null;
    }
}
public class EnumTreeNested {
    static void visit(Class<?> clazz) {
        Object[] enumConstants = clazz.getEnumConstants();
        if (enumConstants[0] instanceof HasChildren) for (Object o : enumConstants)
            visit((HasChildren) o, clazz.getName());
    }
    static void visit(HasChildren hasChildren, String prefix) {
        if (hasChildren instanceof Enum) {
            System.out.println(prefix + ' ' + hasChildren);
            if (hasChildren.children() != null) for (Object o : hasChildren.children())
                visit((HasChildren) o, prefix + ' ' + hasChildren);
        } else
            System.out.println("other " + hasChildren.getClass());
    }
    static <E extends Enum<E> & HasChildren> Set<E> foo() {
        return null;
    }
    public static void main(String[] args) {
        System.out.println(Citrus.Orange.Navel.washinton);
        visit(Citrus.lemon, "");
        System.out.println("----------------------");
        visit(Citrus.orange, "");
        System.out.println("----------------------");
        visit(Citrus.class);
        System.out.println("----------------------");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...