2011-08-24 53 views
0

該類在構造函數中注入所有依賴項,但一次只使用其中一個依賴項。這被認爲是不好的設計?確定不要在構造函數中使用所有參數? - 重新訪問

public class OrderPayment 
{ 
    ICreditCardPayment _ccPayment; 
    ICashPayment _cashPayment; 

    public OrderPayment(ICreditCardPayment ccPayment, ICashPayment cashPayment) 
    { 
     _ccPayment = ccPayment; 
     _cashPayment = cashPayment; 
    } 

    private void PrepareOrder(Order order) 
    { 
     // Do stuff with the order 
    } 

    public PaymentResult PayByCreditCard(Order order) 
    { 
     PrepareOrder(order); 
     return _ccPayment.Pay(order); 
    } 

    public PaymentResult PayByCreditCard(Order order) 
    { 
     PrepareOrder(order); 
     return _cashPayment.Pay(order); 
    } 
} 

另一種方法是這樣的:

public class OrderPayment 
{ 
    private void PrepareOrder(Order order) 
    { 
     // Do stuff with the order 
    } 

    public PaymentResult PayByCreditCard(Order order, ICreditCardPayment ccPayment) 
    { 
     PrepareOrder(order); 
     return ccPayment.Pay(order); 
    } 

    public PaymentResult PayByCreditCard(Order order, ICashPayment cashPayment) 
    { 
     PrepareOrder(order); 
     return cashPayment.Pay(order); 
    } 
} 

這一個函數調用稍微複雜化。即使不是每個構造函數參數都被使用,你會用第一個看起來更乾淨的嗎?考慮到DI框架必須實例化可能很重要的類,儘管它們可能並不全部使用,但我不確定它有多好。

那麼你會使用哪一個?或者也許是不同的實現?

+1

我問了一個非常類似的問題在這裏:http://stackoverflow.com/questions/6960686/is-the-di-pattern-limiting-wrt-昂貴-對象創建耦合與 - 不頻繁 – ckittel

回答

1

我將重構或從ICashPaymentICreditCardPayment提取一個通用接口。你的代碼示例表明你的方法都調用了xPayment.Pay,這看起來很適合你的通用接口方法。

public interface IPayment 
{ 
    PaymentResult Pay(Order order); 
} 

您的更專業的接口可以繼承並構建它。

一般來說,我會避免具有構造(或任何方法)接受去未使用的,或者如果有一個參數被使用的參數,另一種是不。這通常表明您不是在適當的抽象層次上操作,或者您的班級/方法負有太多責任。

0

你需要,要求所有的下列操作:

  • 的付款方式
  • 量被支付
  • 正在被支付
  • 的順序是什麼處理需要做的事情付款之前,根據訂單和付款金額

您正在嘗試定義op的某些順序獨立於操作中正在執行的操作。在方法級別也可以使用依賴注入。

你需要這樣一個方法:

public PaymentResult Pay(Amount amount, Order order, IOrderService orderService, 
    IPaymentService paymentService) { 
    var updatedOrder = orderService.Process(order); // don't alter the original in 
                // case you need to roll back 
    var result = paymentService.Pay(amount, updatedOrder); 
    return result; // this result should include the updated order, so that the system 
       // can determine what to do upon successful payment 
}