2017-09-26 59 views
0

我有,看起來我需要添加一個供應商,我需要的情況下添加到供應商,然後重複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; 
    } 

所以每次都像一個大方法。

我從應該被劃分成每個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所示),這意味着更多的線代碼,但這可能有點不相關。

我想聽聽一些關於這方面的想法,您認爲哪些更具可讀性和更乾淨?任何更好的選擇?


編輯:爲了讓更多的背景,我與酒店供應商工作..大多數供應商具有搜索(hotel_code,DESTINATION_CODE,GEO)的3種常見方法..此方法之外,我可以做一個hotel_code搜索對於所有提供者(通過遍歷Provider枚舉並調用每個提供者的方法,使用hotel_code枚舉參數)..或者我可以將它提供給特定的提供者。

+0

不好,但沒有開關語句可行:反射。另一方面,它聽起來像你可以通過使用繼承來解決這個問題。在基類中收集常見信息並將修改部分放在子類中 – ParkerHalo

+1

@ParkerHalo使用* reflection *應該是在Java中做某件事的最後手段! –

+0

@TimothyTruckle這就是爲什麼我寫了_「不好」_...這也是爲什麼我沒有做出答案,並建議繼承/多態 – ParkerHalo

回答

2

您的問題仍然有點過於抽象,不足以提出「最佳」解決方案,但蒂莫西目前爲止是正確的 - 無論哪種情況,您都可以使用多態性。

我建議策略模式,因爲您通過使用接口定義廣義結構併爲每個單一算法(提供者在您的情況下)創建一個專用類。

這至少有兩個好處:

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

} 

當然你應該實現在單獨的文件中的類 - 我只是把它們整合到一個文件中以縮短它。

+0

我編輯了上面的代碼,並添加更多的上下文,使其更清晰 – prettyvoid

+0

那麼那就是那個。因爲你的「findAvailHotels ...」方法已經有了相同的簽名,你可以用方法參數將所有三個方法聯合爲一個方法,並將它作爲接口的一部分。 – ospf

+0

當你得到時間時,你會善意舉一個簡單的例子嗎?因爲這會讓我更清楚地理解。謝謝 – prettyvoid

1

除非你switch語句是在工廠你應該更好地利用多態性

0

你應該看看訪問者模式和雙重調度。

四人幫訪問者定義爲:

表示待上的對象結構的元素執行的操作。訪問者可以讓你定義一個新的操作而不需要改變它所操作的元素的類。

在你的情況提供商是對象,而方法是操作。

在計算的選擇取決於參數的運行時類型的情況下,雙重調度非常有用。在你的情況下:你想根據供應商方法的類型做些什麼。

相關問題