Хорошо, чтобы не использовать все параметры в конструкторе?- Пересмотрено - PullRequest
0 голосов
/ 24 августа 2011

Этот класс внедряет все зависимости в конструкторе, но одновременно используется только одна зависимость.Считается ли это плохим дизайном?

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 должна создавать экземпляры потенциально тяжелых классов, даже если они не все используются, я не уверен, насколько это хорошо.

Так, какой из них вы бы использовали?Или, может быть, другая реализация?

Ответы [ 2 ]

1 голос
/ 24 августа 2011

Я бы реорганизовал или извлек бы общий интерфейс из ICashPayment и ICreditCardPayment. В вашем примере кода показано, что оба метода вызывают xPayment.Pay, что выглядит хорошим кандидатом для вашего общего метода интерфейса.

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

Ваши более специализированные интерфейсы могут наследовать и расширять его.

В общем, я бы избегал, чтобы конструкторы (или любой метод) принимали аргументы, которые остаются неиспользованными, или если один аргумент используется, другой - нет. Обычно это признак того, что вы либо не работаете на должном уровне абстракции, либо что у вашего класса / метода слишком много обязанностей.

0 голосов
/ 24 августа 2011

Вам нужна операция, которая требует всего следующего:

  • способ оплаты
  • выплачиваемая сумма
  • заказ, который оплачивается
  • Какую обработку необходимо выполнить до оплаты, исходя из заказа и суммы, подлежащей оплате

Вы пытаетесь определить какой-то порядок операции независимо от того, что выполняется в операции. Инъекция зависимости также может использоваться на уровне метода.

вам нужен такой метод:

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...