简体   繁体   中英

Design point : is polymorphism appropriate in my case

I have a situation similar to the one that follows :

interface IAbstractPaymentService { void ProcessPayment(); }
interface IPaymentGateway1Service : IAbstractPaymentService { } // Do not define extra methods but needed for IoC container configuration
interface IPaymentGateway2Service : IAbstractPaymentService { } // Do not define extra methods but needed for IoC container configuration

public abstract class PaymentProcessor 
{ 
    protected abstract void ThisMethodNeedsASpecializedService(IAbstractPaymentService abstractPaymentService);
}

public class PaymentGateway1Processor : PaymentProcessor
{
    protected override void ThisMethodNeedsASpecializedService(IAbstractPaymentService abstractPaymentService)
    {
        return ThisMethodNeedsASpecializedService(abstractPaymentService as IPaymentGateway1Service) // Don't worry, I do security checks
    }

    public void ThisMethodNeedsASpecializedService(IPaymentGateway1Service paymentGateway1Service)
    {
        paymentGateway1Service.ProcessPayment(); 
    }
}

public class PaymentGateway2Processor : PaymentProcessor
{
    protected override void ThisMethodNeedsASpecializedService(IAbstractPaymentService abstractPaymentService)
    {
        return ThisMethodNeedsASpecializedService(abstractPaymentService as IPaymentGateway2Service) // Don't worry, I do security checks
    }

    public void ThisMethodNeedsASpecializedService(IPaymentGateway2Service paymentGateway2Service)
    {
        paymentGateway2Service.ProcessPayment(); 
    }
}

I'm not really happy with this abstraction, because the idea of polymorphism is that you don't care about the underlying type, you just want a certain behaviour to be applied. But here, even if I create a factory of PaymentProcessor, every time the consumer will need to call ThisMethodNeedsASpecializedService(), he will need to know the underlying type to inject the correct service.

I was thinking of storing the Service in an internal property, so that I could create a Factory that would inject the service at creation time and the consumer wouldn't need to know about the service used - and therefore, wouldn't care about the underlying type. But I have always seen the fact of storing a service instance in a property a bad practice, and am not sure if I should go that way.

What do you think about it, and would you do it differently ?

A better way to impement your structure is to inject IAbstractPaymentService via PaymentProcessor costructor. For example:

public abstract class PaymentProcessor 
{ 
    protected abstract void ThisMethodNeedsASpecializedService();
}

public class PaymentGateway1Processor : PaymentProcessor
{
    private IPaymentGateway1Service paymentGateway1Service;

    public PaymentGateway1Processor(IPaymentGateway1Service paymentGateway1Service){
        this.paymentGateway1Service = paymentGateway1Service;
    }

    public void ThisMethodNeedsASpecializedService()
    {
        this.paymentGateway1Service.ProcessPayment(); 
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM