我正在处理一个使用标准化 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;
}
}
}
但在我看来,在一个枚举中包含一个枚举,每个枚举都具有相同的值范围,这似乎有点过分了。有更好的方法吗?
最佳答案
也许是 Visitor Pattern这就是您正在寻找的。p>
与枚举一起使用,它基本上允许添加依赖于枚举的逻辑,而无需使用 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());
}
}
关于java - 使用基本枚举作为依赖枚举的默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39938952/