Java 包装器枚举开关多态性

Java Wrapper enum switch polymorphism

我从原始界面获得了使用 Wrapper 的代码。基于枚举a会调用链表的方法,如putFirst(T data), putCurrent(T data), putLast(), removeFirst(), ...

...

@Override
public void put(T data, EnumPosition position) {

    switch (position) {
        case FIRST:
            abstrList.putFirst();
            break;

        case LAST:
            abstrList.putLast();
            break;

        ...

        default:
           throw new NoSuchElementException("something exception...");
    }

@Override
public void remove(T data, EnumPosition position) {

    switch (position) {
        case FIRST:
            abstrList.removeFirst(data);
            break;

        case LAST:
            abstrList.removeLast(data);
            break;

        ...

        default:
           throw new NoSuchElementException("something exception...");
    }

我的 EnumPosition 现在看起来很简单。 (可能会改变它实现一些接口)

public enum EnumPosition {
     FIRST, LAST, CURRENT ...

}

A 想问一下,是否可以删除此开关并用 java 8 或其他...中的 lambda 替换一些多态性消费者...更有效的东西。

感谢您的帮助

是的。然而,答案取决于您如何使用枚举。

您是否总是一遍又一遍地传递相同的枚举值,或者它们是否混淆了?

如果你总是使用相同的枚举

您可以制作多个采用 List 的包装器实现,并制作一个采用枚举来确定实现的工厂(或使其成为枚举本身的工厂方法)。

MyList<T> list = EnumPosition.LAST.newMyListWrapper(abstrList);

list.put(data);
list.remove(data);

如果您在调用中混淆了枚举

如果您同时使用不同的枚举来对同一个 abstrList 进行操作,那么您将必须向您的枚举添加 put(List<T> list, T data)remove(List<T> list, data) 方法:

EnumPosition.LAST.put(abstrList, data);

EnumPosition.CURRENT.remove(abstrList, data);

或者,如果您需要支持这两种用例,则可以同时执行这两种操作...

由于不能扩展枚举,所以不能直接对枚举使用多态性。

但是您可以在某种类型的枚举中定义一个实例变量。然后你可以使用多态性,例如

public enum EnumPosition {

    FIRST(new FirstElementModification()), 
    LAST(new LastElementModification())
    ...;

    private ListModification listModification;

    private EnumPosition(ListModification listModification) {
        this.listModification = listModification;
    }

    public <T> void put(List<T> list, T element) {
        listModification.put(list, element);
    }

    public void remove(List<?> list) {
        listModification.remove(list);
    }

}

interface ListModification {
    public <T> void put(List<T> list, T element);
    public <T> void remove(List<T> list);
}

并像这样实施不同的列表修改策略

class FirstElementModification implements ListModification {

    public <T> void put(List<T> list, T element) {
        ...
    }

    public <T> void remove(List<T> list) {
        ...
    }

}

从客户的角度来看,您可以省略开关并只使用

EnumPosition.FIRST.put(someList, someElement);
EnumPosition.LAST.remove(someList);

枚举状态机呢?我不确定它是否能解决您的问题,但您可以尝试像这样编辑您的界面:

    public enum EnumPosition {
    FIRST {
      @Override
      public void doPut(){
         abstrList.putFirst();
      }
      @Override
      public void doGet(){
         abstrList.getFirst();
      }
    },
    LAST {
      ... // Override methods for LAST
    },
    CURRENT {
      ...
    },

    ...

    public abstract void doPut();
    public abstract void doGet();
    }

进行这些更改后,您可以避免使用此开关:

...

@Override
public void put(T data, EnumPosition position) {
       position.doPut();
    }

您可以在这里找到更多信息:https://schneide.wordpress.com/2010/12/13/avoid-switch-use-enum/