这个问题经常出现在我的项目中。举例来说,假设我有两个接口,一个接口从API检索信息,另一个接口分析该信息。
public interface APIClient {...}
public interface APIParser {...}
现在,我可能需要使用不同的API,因此我将为APICLient
提供许多实现,但是每个实现都需要自己的APIParser
。
这将导致这种类型的结构
public class APIClientA implements APIClient {...}
public class APIParserA implements APIParser {...}
public class APIClientB implements APIClient {...}
public class APIParserB implements APIParser {...}
...
...
因此,通常来说,这意味着每次我想添加一种新类型的API时,都必须为同一类型创建多个类,并确保它们仅相互通信而不与其他类型的API的实现。
这看起来与Bridge设计模式所建议的非常相似,但是该模式将允许任何APIClient使用任何APIParser(是吗?)
那么,有没有更好的解决方案?也许这很好,不需要重构。
此外,也许 parse 不是正确的词,对不起我的英语,但是我的意思是分析JSON / XML响应以便从中获取具体信息。我分析每个响应的方式取决于每个API提供的结构,因此这就是为什么我需要不同的“解析器”的原因
编辑:
我会稍微扩展一下这个想法。有一个使用APIClient发出给定类型参数的客户端类。 JSON响应满足请求后,客户端将使用相应的APIParser来获取有关响应的特定信息。
public class ClientClass {
...
json = APIClientTypeA.makeRequest(city, day, ...);
temperature = APIParserTypeA.getTemperature(json);
...
}
这里的问题是客户端需要确保使用正确的APIClient和APIParser实现(它们必须匹配)
答案 0 :(得分:2)
您的要求似乎非常适合Abstract Factory GoF模式,因为一旦创建了具体工厂并且您的代码仅实例化了该工厂的客户端和解析器,它将不会可能会错误地获得一组不匹配的客户端/解析器实例。
AbstractFactory
是客户端用于实例化客户端/解析器对的对象:
interface AbstractFactory {
APIParser createAPIParser();
APIClient createAPIClient();
}
interface APIParser {}
interface APIClient {}
具体工厂可以提供匹配对(您可以重用产品实例,但我保持简单):
class ConcreteFactoryA implements AbstractFactory {
public APIParser createAPIParser() { return new APIParserA(); }
public APIClient createAPIClient() { return new APIClientA(); }
}
class ConcreteFactoryB implements AbstractFactory {
public APIParser createAPIParser() { return new APIParserB(); }
public APIClient createAPIClient() { return new APIClientB(); }
}
为完整起见,以下是具体产品的声明:
class APIParserA implements APIParser {}
class APIParserB implements APIParser {}
class APIClientA implements APIClient {}
class APIClientB implements APIClient {}
示例客户端代码:
AbstractFactory factory = new ConcreteFactoryA();
APIClient client = factory.createAPIClient();
APIParser parser = factory.createAPIParser();
答案 1 :(得分:1)
您可以做的是在类中添加类型参数。
// wrapper for your json
public class APIResult<T extends APIClient<T>> {
private final String json;
public APIResult(String json) {
this.json = json;
}
public String getJson() {
return this.json;
}
}
// client always returns a result with itself as a type
public interface APIClient<T extends APIClient<T>> {
APIResult<T> makeRequest();
}
// parser only handles the implementation specific results of one client
public interface APIParser<T extends APIClient<T>> {
String getTemperature(APIResult<T> result);
}
public class APIClientA implements APIClient<APIClientA> {
public APIResult<APIClientA> makeRequest() {
// must return a result with this type
}
}
public class APIParserA implements APIParser<APIClientA> {
public String getTemperature(APIResult<APIClientA> result) {
// only accepts results from one specific client
}
}