Java包装枚举开关多态性

4

我有一段使用Wrapper的代码,从原始接口继承而来。基于枚举类型,我将调用链表的方法,如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 ...

我想问一下,是否可以使用Java 8中的lambda或其他方法,通过多态性来替换这个开关以使其更加有效?谢谢您的帮助。

3个回答

1
关于枚举状态机怎么样?我不确定它是否能解决你的问题,但你可以尝试编辑你的接口像这样:
    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();
    }

在这些更改之后,您可以避免使用 switch,方法如下:
...

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

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


0

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

你总是一遍又一遍地传递相同的枚举值,还是它们会混合在一起?

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

你可以创建多个包装器实现来接收 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);

如果您需要支持这两种用例,您也可以同时进行...


太好了。感谢你的回答。 - Petr Tomášek

0

由于您无法扩展枚举,因此无法直接使用枚举进行多态。

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

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);

很棒的解决方案。感谢您的回答。 - Petr Tomášek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接