如果枚举不可扩展,则重构此代码的最佳方法



考虑以下类,它们表示一个实体,并具有返回类型为EnumA的数据的方法

实体A类:

public class EntityA
{   
public Set<EnumA> getProcessedFlags() { ... }
}

EnumA

public enum EnumA {
READ_ONLY,
READ_WRITE,
PERMISSION_DENIED,
COMMENT_ENABLED
}

现在,我需要再添加一个EntityB,它与EntityA相似,但在逻辑上不同。(相同的方法签名但不同的实现:

还有一件事,返回值是EntityA中的EnumAntityB的**EnumB。

EnumAEnumB是两个不同的集合,它们表示逻辑上相同的标志的集合,但每个标志中都有一些互斥值:

EnumB

public enum EnumB {
READ_ONLY,
READ_WRITE,
LIKE_ENABLED
}

因此,为了重构它,我创建了一个抽象基类-EntityBase,并将EntityAEntityB都作为该基类的子级。

问题是枚举不可扩展,有没有一个好的方法来重构它?

我想创建如下的类结构:

public enum EnumBase {}
public enum EnumA extends EnumBase {}
public enum EnumB extends EnumBase {}
public abstract class EntityBase
{
public Set<? extends EnumBase> getProcessedFlags();
}
public class EntityA extends EntityBase
{   
public Set<EnumA> getProcessedFlags() { ... }
}
public class EntityB extends EntityBase
{   
public Set<EnumB> getProcessedFlags() { ... }
}

由于java中的枚举是不可扩展的,我们能有一些更好的设计来维护这个EntityBase类吗?

如果没有更多的上下文,很难提供具体的建议,但值得注意的是,枚举可以共享接口,所以你可以尝试这样的方法:

interface Base {
String name();
}
interface A extends Base {}
interface B extends Base {}
public enum EnumBase implements A, B {
READ_ONLY,
READ_WRITE
}
public enum EnumA implements A {
PERMISSION_DENIED,
COMMENT_ENABLED
}
public enum EnumB implements B {
LIKE_ENABLED
}
public abstract class EntityBase<F extends Base> {
public abstract Set<F> getProcessedFlags();
}
public class EntityA extends EntityBase<A> {
@Override
public Set<A> getProcessedFlags() { ... }
}
public class EntityB extends EntityBase<B> {
@Override
public Set<B> getProcessedFlags() { ... }
}

另一种解决方案是对所有PermissionsFlags使用一个枚举,然后添加一个属性,允许您检查PermissionFlag是否可以与此类一起使用。

public enum PermissionFlag {
READ_ONLY,
READ_WRITE,
PERMISSION_DENIED(EntityA.class),
COMMENT_ENABLED(EntityA.class),
LIKE_ENABLED(EntityB.class);
private final Class<?> useForClass;
PermissionFlag() {
this(null);
}
PermissionFlag(Class<?> useForClass) {
this.useForClass = useForClass;
}
/**
* Check if given class can be used for this PermissionFlag.
*/
public boolean useForClass(Class<?> clazz) {
return useForClass == null || useForClass.equals(clazz);
}
/**
* Returns a Stream consisting of all the PermissionFlags that can be used with the given class.
*/
public static Stream<PermissionFlag> getPermissionsFlags(Class<?> clazz){
return Stream.of(values()).filter(flag -> flag.useForClass(clazz));
}
}

然后,您可以使用getPermissionFlags(EntityA.class).collect(Collectors.toList())来获取EntityA的所有权限标志的列表。

相关内容

  • 没有找到相关文章

最新更新