我有一个看起来像这样的大方法
List<Hotel> findAvailHotels(Provider provider, Method method, List<String> codes) {
switch (provider) {
case PROVIDER_1:
//TODO Do common things to provider 1
switch (method) {
case HOTEL_CODE:
break;
case DESTINATION_CODE:
break;
case GEO:
break;
}
break;
case PROVIDER_2:
switch (method) {
case HOTEL_CODE:
break;
case DESTINATION_CODE:
break;
case GEO:
break;
}
break;
}
因此,每次我需要添加提供程序时,我都需要向该提供程序添加一个案例,然后为此新提供程序重复method
开关。
我得到了一位研究员的建议,应该将其分成每个method
的方法,例如,而不是上述内容,它将是
List<Hotel> findAvailHotelsByHotelCode(Provider provider, List<String> codes) {
switch (provider) {
case PROVIDER_1:
//TODO Do common things to provider 1
break;
case PROVIDER_2:
break;
}
List<Hotel> findAvailHotelsByDestinationCode(Provider provider, List<String> codes) {
switch (provider) {
case PROVIDER_1:
//TODO Do common things to provider 1
break;
case PROVIDER_2:
break;
}
List<Hotel> findAvailHotelsByGeo(Provider provider, List<String> codes) {
switch (provider) {
case PROVIDER_1:
//TODO Do common things to provider 1
break;
case PROVIDER_2:
break;
}
个人想法:也许分成多种方法会让它更清晰,但如果我需要对PROVIDER_1
做一些常见的事情(尽管有method
)那么这个常见的东西会需要在每个方法中重复/重复(如上面代码中的//TODO
所示),这意味着更多的代码行,但这可能有点无关紧要。
我想听听一些关于此问题的想法,您认为哪个更具可读性和更干净?还有更好的选择吗?
编辑:为了提供更多背景信息,我与酒店提供商合作..大多数提供商都有3种常见的搜索方法(hotel_code,destination_code,geo)..从这个方法之外我可以做{ {1}}搜索所有提供者(通过循环提供者枚举并使用hotel_code
枚举参数调用每个提供者的方法)..或者我可以将其用于特定提供者。
答案 0 :(得分:2)
你的问题仍然有点过于抽象,无法提出“最佳”解决方案,但提摩太到目前为止是正确的 - 在任何一种情况下你都可以使用polimorphism。
我建议使用策略模式,因为您通过使用接口定义了广泛的结构,并为每个算法(在您的情况下为提供者)创建一个专用类。
这至少有两个好处:
嗯 - 既然你要求它 - 这里有一些示例代码(虽然有点大......)
import java.util.ArrayList;
import java.util.List;
public class HotelStuff {
private static class Hotel{/* does whatever ...*/}
private enum SearchMethod{
HOTELCODE,
DESTINATIONCODE,
GEOCODE
}
private interface Providable{
List<Hotel> findAvailHotels(SearchMethod method, List<String> codes);
}
private static class Provider1 implements Providable{
@Override
public List<Hotel> findAvailHotels(SearchMethod method, List<String> codes) {
// TODO create the list ...
return null;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Providable> providers = new ArrayList<Providable>();
providers.add(new Provider1());
// providers.add(new Provider2 .. and so on
List<String> codes = Arrays.asList("123","456");
SearchMethod method = SearchMethod.GEOCODE;
List<Hotel> availableHotels = findAvailHotels(providers, method, codes);
}
public static List<Hotel> findAvailHotels(List<Providable> providers, SearchMethod method, List<String> codes) {
List<Hotel> result = new ArrayList<Hotel>();
List<Hotel> partResult;
for(Providable provider: providers) {
partResult = provider.findAvailHotels(method, codes);
result.addAll(partResult);
}
return result;
}
}
当然你应该在单独的文件中实现这些类 - 我只是把它们放在一个文件中来缩短它。
答案 1 :(得分:1)
除非您的switch
声明位于工厂中,否则最好使用多态。
答案 2 :(得分:0)
您应该同时查看访客模式和双重调度。
四人帮将访客定义为:
表示要对对象结构的元素执行的操作。访问者允许您定义新操作,而无需更改其操作的元素的类。
在您的情况下, Provider 是对象,而 Method 就是操作。
在计算选择取决于其参数的运行时类型的情况下,双重调度很有用。在您的情况下:您希望根据提供程序和方法的类型执行某些操作。