java - 嵌套开关还是多功能,什么才是更好的设计?

标签 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) {
                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;
    }

因此,每次我需要添加提供程序时,我都需要向该提供程序添加一个案例,然后针对这个新提供程序重复方法切换。

我从一位同事那里得到了一个建议,应该将每个方法分为不同的方法,例如,而不是上面的,它将是

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 做常见的事情(尽管有方法) )那么这个常见的事情需要在每个方法中重复/复制(如上面代码中的 //TODO 所示),这意味着更多的代码行,但这可能有点无关紧要。

我想听听对此的一些想法,您认为哪一个更具可读性和更简洁?还有更好的选择吗?

<小时/>

编辑:为了提供更多背景信息,我与酒店提供商合作。大多数提供商有 3 种常见的搜索方法(hotel_code、destination_code、geo)。从该方法之外我可以执行 hotel_code 搜索所有提供者(通过循环提供者枚举并使用 hotel_code 枚举参数调用每个提供者的方法)..或者我可以对特定提供者执行此操作。

最佳答案

您的问题仍然有点太抽象,无法提出“最佳”解决方案,但蒂莫西到目前为止是对的 - 无论哪种情况,您都可以使用多态性。

我建议策略模式,因为您通过使用接口(interface)定义广泛的结构,并为每个算法(在您的情况下提供者)创建一个专用的类。

这至少有两个优点:

  1. 您有一个易于监督的类形式的算法列表。
  2. 您可以通过策略对象循环替换外部开关。

嗯 - 既然你要求它 - 这里是一些示例代码(虽然有点大......)

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;
  }

}

当然,您应该在单独的文件中实现这些类 - 我只是将它们放入一个文件中以缩短它。

关于java - 嵌套开关还是多功能,什么才是更好的设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46421979/

相关文章:

c# - 用于在平面文件中对字段进行分组和结构化数据的设计模式

java - 实现 Spring bean 的最佳实践

php - `return $this;` 设计模式还是反模式?

java - 无法在使用 Java7u13 JFX2.2.5 的最新 Linux 和 Mac 上的浏览​​器中运行

java - Google App Engine appcfg.py 引发值错误

javascript - 创建子类,其属性是该父类对应属性的子类

java - 当两个线程同时调用 "getInstance()"时,Singleton 的行为如何?

java - jSTL中如何获取值

Java时间: preserve date and time to other timezone

PHP 如何从返回的对象中检索值