mardi 19 février 2019

Custom visitor pattern implementation

I'm trying to implement a sort of visitor pattern. Most of examples on web show a visitor class with a "visit" method and multiple overloads of that method. In this case i've called my "visit" method CalculateFee (it's a semantic matter) with its overloads. Everything it's ok so far, but now i need to implement a visitor again to execute another method "CalculateExtraCharge", so i have added another method called CalculateExtraCharge with its overloads. But now i have two questions

1) Is this a wrong implementation of the pattern?

2) Should i always call my method "visit"?

Here is an overview of my code, i have omited some parts of it to focus only in what is important for my question.

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

        }

    }

Aucun commentaire:

Enregistrer un commentaire