Я пытаюсь реализовать своего рода шаблон посетителя. Большинство примеров в Интернете показывают класс посетителя с методом «посетить» и несколькими перегрузками этого метода. В этом случае я назвал свой метод "посещения" CalculateFee (это семантический вопрос) с его перегрузками. Пока все в порядке, но теперь мне нужно снова реализовать посетителя, чтобы выполнить другой метод «CalculateExtraCharge», поэтому я добавил еще один метод с именем CalculateExtraCharge с его перегрузками. Но теперь у меня есть два вопроса
1) Это неправильная реализация шаблона?
2) Должен ли я всегда называть свой метод «посещением»?
Вот обзор моего кода, я опустил некоторые его части, чтобы сосредоточиться только на том, что важно для моего вопроса.
public class CreditCard : IPaymentMethod
{
public decimal Amount { get; set; }
public decimal GetFee(IPaymentCalculationsVisitor visitor)
{
return visitor.CalculateFee(this);
}
public decimal GetExtraCharge(IPaymentCalculationsVisitor visitor)
{
return visitor.CalculateExtraCharge(this);
}
}
public class Check : IPaymentMethod
{
public decimal Amount { get; set; }
public decimal GetFee(IPaymentCalculationsVisitor visitor)
{
return visitor.CalculateFee(this);
}
public decimal GetExtraCharge(IPaymentCalculationsVisitor visitor)
{
return visitor.CalculateExtraCharge(this);
}
}
public interface IPaymentCalculationsVisitor
{
decimal CalculateFee(CreditCard creditCard);
decimal CalculateFee(Check check);
decimal CalculateExtraCharge(CreditCard creditCard);
decimal CalculateExtraCharge(Check check);
}
public class PaymentCalculationsVisitor: IPaymentCalculationsVisitor
{
public decimal CalculateFee(CreditCard creditCard)
{
return creditCard.Amount * 0.15m;
}
public decimal CalculateFee(Check check)
{
return check.Amount * 0.10m;
}
public decimal CalculateExtraCharge(CreditCard creditCard)
{
return 15;
}
public decimal CalculateExtraCharge(Check check)
{
return 10;
}
}
public class PaymentProcessor
{
public void ProcessPayment()
{
var paymentMethods = new List<IPaymentMethod>()
{
new CreditCard(),
new Check()
};
var calculationsVisitor = new PaymentCalculationsVisitor();
foreach (var paymentMethod in paymentMethods)
{
//First i need to get the fee
var fee = paymentMethod.GetFee(calculationsVisitor);
//Then i do do some other stuff, validations, other calculations etc
//Finally i get the extra charge
var extraCharge = paymentMethod.GetExtraCharge(calculationsVisitor);
}
}
}
IPaymentMethod
будет работать, особенность шаблона заключается в том, чтобы разрешить логику новых посетителей без необходимости изменять посещенные типы. Именно поэтому метод однократного посещения является наиболее распространенным. Нет ничего плохого в двух методах посещения, но шаблон разработан таким образом, чтобы не добавлять дополнительные методы. Вместо этого вы создаете новые классы посетителей и передаете их существующему методу посещения. - person jaco0646   schedule 20.02.2019