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/
我从原始界面获得了使用 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/