2016-12-15 56 views
1

我一直在尋找開關在類型爲Java,我在這裏找到一個解決方案突破:Switch over type in java的Java 8開關的情況下默認與類類型

但是這個問題,解決方案是不是一個真正的switchbreak就像,相信這會發生,因爲我遍歷Consumer S,我想知道的好辦法修改我當前的代碼或清潔替代擁有的東西來處理我的課型,並斷處理的第一場比賽和違約後是處理無與倫比的(這裏是父類StripeObject)。

我的業務是從webhooks處理條紋的事件,我使用stripe-java,所以我現在的代碼是這樣的:

public void handleWebHookEvent(Event eventJson) throws CardException, APIException, AuthenticationException, InvalidRequestException, APIConnectionException { 
     Stripe.apiKey = configuration.getString(AppConstants.STRIPE_API_KEY); 

     // Verify the event by fetching it from Stripe 
     Event event = Event.retrieve(eventJson.getId()); 
     Logger.debug(AppUtils.concatStrings("|-> Event Received: [", event.getId(), "] Type: [", event.getType(), "] Request ID: [", event.getRequest(), "]")); 
     handleEventObject(event.getData().getObject()); 
    } 

    private void handleEventObject(StripeObject stripeObject) { 
     switchType(stripeObject, 
       caze(Customer.class, this::handleEventObject), 
       caze(Card.class, this::handleEventObject), 
       caze(Charge.class, this::handleEventObject), 
       caze(Transfer.class, this::handleEventObject) 
       caze(StripeObject.class, object -> Logger.debug(AppUtils.concatStrings("|--> !!! Not Handled StripeObject !!! [", object.toString(), "]"))) 
     ); 
    } 

    private void handleEventObject(Customer customer) { 
     Logger.debug(AppUtils.concatStrings("|--> Customer ID <Description> : [", customer.getId(), " <", customer.getDescription(), ">]")); 
    } 

    private void handleEventObject(Card card) { 
     Logger.debug(AppUtils.concatStrings("|--> Card ID <Brand> : [", card.getId(), " <", card.getBrand(), ">]")); 
    } 

    private void handleEventObject(Charge charge) { 
     Logger.debug(AppUtils.concatStrings("|--> Charge ID <Description , Customer , Amount> : [", charge.getId(), " <", charge.getDescription(), " , ", charge.getCustomer() ," , ", charge.getAmount(), ">]")); 
    } 

    private void handleEventObject(Transfer transfer) { 
     Logger.debug(AppUtils.concatStrings("|--> Transfer ID <Description , Destination , Amount> : [", transfer.getId(), " <", transfer.getDescription(), " , ", transfer.getDestination() ," , ", transfer.getAmount(), ">]")); 
    } 

    @SuppressWarnings("unchecked") 
    private static <T> void switchType(StripeObject stripeObject, Consumer... consumers) { 
     for (Consumer consumer : consumers) 
      consumer.accept(stripeObject); 
    } 

    private static <T> Consumer caze(Class<T> clazz, Consumer<T> consumer) { 
     return obj -> Optional.of(obj).filter(clazz::isInstance).map(clazz::cast).ifPresent(consumer); 
    } 

在當前的代碼,如果evnet爲客戶爲例,將打印:

|--> Customer ID <Description> ... etc 

然後

|--> !!! Not Handled StripeObject !!! ... etc 

它必須只打印第一行,而不打印第二行。

回答

3

你只需要改變方法switchTypecaze使用Predicate,而不是一個Consumer,因此該循環可以在第一場比賽停止。代碼的其餘部分不需要任何改變:

@SafeVarargs 
private static void switchType(StripeObject so, Predicate<Object>... predicates) { 
    for(Predicate<Object> predicate : predicates) 
     if(predicate.test(so)) return; 
} 

private static <T> Predicate<Object> caze(Class<T> clazz, Consumer<T> consumer) { 
    return obj -> { 
     if(clazz.isInstance(obj)) { 
      consumer.accept(clazz.cast(obj)); 
      return true; 
     } 
     return false; 
    }; 
} 

注意,這還是從switch語義不同,作爲switch聲明一般排除不確定的情況下。在這裏,其中一種類型仍然可能是另一種類型的子類型,因此,與switch聲明不同,case聲明的順序確實很重要。

如果所有情況都不同,這不是問題。

+0

是的工作,非常感謝你 –