使用基本枚举作为从属枚举

时间:2016-10-09 01:04:14

标签: java enums

我正在使用标准化Web服务的客户端,但其中一个供应商的行为略有不同,因此我们必须考虑这些行为。要做到这一点,我们一直在使用枚举:

public enum ServiceProviderType {
    FOO, BAR;

    public ServiceProviderType checkService(String url) {
        if (url.equals("http://www.example.com")) {
            return ServiceProviderType.FOO;
        } else {
            return ServiceProviderType.BAR;
        }
    }
}

这些行为的差异也根据我们对服务的要求而有所不同,例如我们可能会请求一个图层并希望该图层为红色,但要知道BAR和FOO服务以不同方式表示RGB值。为此,我们创建了另一个枚举,用于存储服务中每个层所需的属性。

public enum LayerServiceProviderType {
    FOO("#ff0000"),
    BAR("#ff5555");

    private String colour;

    public ServiceProviderType(String colour) {
        this.colour = colour;
    }

    public String getColour() {
        return colour;
    }

    public ServiceProviderType checkService(String url) {
        if (url.equals("http://www.example.com")) {
            return ServiceProviderType.FOO
        } else {
            return ServiceProviderType.BAR;
        }
    }
}

这种方法很好,除非我们想要处理多个图层并将它们视为同一个基本枚举的衍生物。基本上我们希望将Layer1ServiceProviderType.BAR作为等价于Layer2ServiceProviderType.BAR。但是我们不能对枚举进行子类化,甚至试图这样做也似乎打破了各种声音设计原则。

我的第一个想法是拥有一个包含枚举的界面:

interface ServiceProvider {
    ServiceProviderType {FOO, BAR};

    ServiceProviderType getServiceProviderType();

    ServiceProvider checkService(String url);
}

public enum LayerServiceProvider implements ServiceProvider {
    FOO (ServiceProviderType.FOO, "#ff0000"),
    BAR (ServiceProviderType.BAR, "#ff0000");

    public LayerServiceProvider(ServiceProviderType serviceProviderType, String colour) {
        this.serviceProviderType = serviceProviderType;
        this.colour = colour;
    }

    @Override
    public ServiceProviderType getServiceProviderType() {
        return this.serviceProviderType;
    }

    @Override
    public ServiceProvider checkService(String url) {
        if (url.equals("http://www.example.com")) {
            return LayerServiceProviderType.FOO
        } else {
            return LayerServiceProviderType.BAR;
        }
    }
}

但是,对于我来说,在枚举中使用枚举,每个都具有相同的值范围,这似乎很难过。有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

也许Visitor Pattern是您正在寻找的。

与enum一起使用时,它基本上允许在不使用switch语句的情况下添加依赖于枚举的逻辑。

示例:

public enum ServiceProviderType {
    FOO {
        @Override public <T> T apply(Action<T> action) { return action.doFoo(); }
    },
    BAR {
        @Override public <T> T apply(Action<T> action) { return action.doBar(); }
    };

    public interface Action<T> {
        T doFoo();
        T doBar();
    }

    public abstract <T> T apply(Action<T> action);

    public static ServiceProviderType checkService(String url) {
        if (url.equals("http://www.example.com"))
            return FOO;
        return BAR;
    }
}

public class LayerServiceProviderType implements ServiceProviderType.Action<String> {
    @Override
    public String doFoo() {
        return "#ff0000";
    }
    @Override
    public String doBar() {
        return "#ff0000";
    }
}

public class Main {
    public static void main(String[] args) {
        ServiceProviderType type = ServiceProviderType.checkService("");

        String colour = type.apply(new LayerServiceProviderType());
    }
}