我正在使用标准化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;
}
}
}
但是,对于我来说,在枚举中使用枚举,每个都具有相同的值范围,这似乎很难过。有更好的方法吗?
答案 0 :(得分:0)
也许Visitor Pattern是您正在寻找的。 p>
与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());
}
}