Java 嵌套开关或多个函数,什么是更好的设计?
我有一个类似这样的大方法Java 嵌套开关或多个函数,什么是更好的设计?,java,oop,design-patterns,switch-statement,Java,Oop,Design Patterns,Switch Statement,我有一个类似这样的大方法 List<Hotel> findAvailHotels(Provider provider, Method method, List<String> codes) { switch (provider) { case PROVIDER_1: //TODO Do common things to provider 1 switch (method) {
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;
}
个人想法:可能拆分成多个方法会使它更干净,但是如果我需要对
提供者1
做一些普通的事情(尽管方法
),那么这个普通的事情需要在每个方法中重复/复制(如上面代码中的//TODO
所示)这意味着更多的代码行,但这可能有点无关
我想听听一些关于这方面的想法,你认为它更可读,更干净吗?还有更好的选择吗
编辑:为了提供更多上下文,我与酒店提供商合作。。大多数供应商有3种常见的搜索方法(酒店代码、目的地代码、地理位置)。。从该方法之外,我可以执行
hotel\u code
搜索所有提供者(通过循环访问提供者枚举并使用hotel\u code
enum param调用每个提供者的方法)。。或者我可以对特定的提供者这样做。除非您的开关语句在工厂中,否则您最好使用多态性除非您的开关语句在工厂中,否则您最好使用多态性您的问题仍然有点过于抽象,无法提出“最佳”的建议解决方案,但到目前为止Timothy是正确的-在这两种情况下,您都可以使用polimorphism
我建议使用策略模式,因为您可以通过使用接口来定义广泛的结构,并为每个算法创建一个专用的类(在您的例子中是提供者)
这至少有两个优点:
您有一个易于监督的类形式的算法列表
您可以通过策略对象的循环替换外部开关
嗯-既然你要求它-这里是一些示例代码(虽然有点大…)
import java.util.ArrayList;
导入java.util.List;
公共级塔夫酒店{
私人静态级酒店{/*做任何事…*/}
私有枚举搜索方法{
酒店代码,
目的代码,
地理编码
}
可提供的专用接口{
列出findAvailHotels(搜索方法、列表代码);
}
私有静态类Provider1实现可提供{
@凌驾
公共列表findAvailHotels(搜索方法,列表代码){
//要创建列表,请执行以下操作。。。
返回null;
}
}
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
列表提供程序=新的ArrayList();
添加(新的Provider1());
//providers.add(新Provider2..等)
列表代码=Arrays.asList(“123”、“456”);
SearchMethod=SearchMethod.GEOCODE;
列出可用酒店=findAvailHotels(供应商、方法、代码);
}
公共静态列表findAvailHotels(列表提供程序、SearchMethod方法、列表代码){
列表结果=新建ArrayList();
列出部分结果;
对于(可提供的提供程序:提供程序){
partResult=provider.findAvailHotels(方法、代码);
result.addAll(partResult);
}
返回结果;
}
}
当然,您应该在单独的文件中实现这些类-我只是将它们放在一个文件中以缩短它。您的问题仍然有点过于抽象,无法提出“最佳”解决方案,但Timothy到目前为止是对的-在这两种情况下,您都可以使用polimorphism
我建议使用策略模式,因为您可以通过使用接口来定义广泛的结构,并为每个算法创建一个专用的类(在您的例子中是提供者)
这至少有两个优点:
您有一个易于监督的类形式的算法列表
您可以通过策略对象的循环替换外部开关
嗯-既然你要求它-这里是一些示例代码(虽然有点大…)
import java.util.ArrayList;
导入java.util.List;
公共级塔夫酒店{
私人静态级酒店{/*做任何事…*/}
私有枚举搜索方法{
酒店代码,
目的代码,
地理编码
}
可提供的专用接口{
列出findAvailHotels(搜索方法、列表代码);
}
私有静态类Provider1实现可提供{
@凌驾
公共列表findAvailHotels(搜索方法,列表代码){
//要创建列表,请执行以下操作。。。
返回null;
}
}
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
列表提供程序=新的ArrayList();
添加(新的Provider1());
//providers.add(新Provider2..等)
列表代码=Arrays.asList(“123”、“456”);
SearchMethod=SearchMethod.GEOCODE;
列出可用酒店=findAvailHotels(供应商、方法、代码);
}
公共静态列表findAvailHotels(列表提供程序、SearchMethod方法、列表代码){
列表结果=新建ArrayList();
列出部分结果;
对于(可提供的提供程序:提供程序){
partResult=provider.findAvailHotels(方法、代码);
result.addAll(partResult);
}
返回结果;
}
}
当然,您应该在单独的文件中实现这些类-我只是将它们放在一个文件中以缩短它。您应该研究访问者模式和双重分派
四人帮将访客定义为:
表示要在对象结构的元素上执行的操作。Visitor允许您定义新操作,而无需更改其操作的元素的类
在您的案例中,提供者是对象,方法是操作
在计算的选择取决于其参数的运行时类型的情况下,双重分派非常有用。在您的情况下:您希望根据提供程序和方法的类型执行某些操作。您应该研究访问者模式和双重分派
四人帮将访客定义为:
表示要在对象的元素上执行的操作
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;
}
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;
}
}