Search code examples
c#design-patternscoding-styleclean-architecturesolid-principles

How do I have a method return one of almost the same classes case to case?


I am integrating a new payment way into our service project. I coded everything. Now I want it to be convenient to Solid principles. However, I am stuck how to overcome a case. Our service already have a method that called GetPaymentProfile and returns a class named PaymentProfile. After Integration I had to add a new PaymentProfile and method, because this new class has a new property.

Because of this, I obtained two class and two methods. Every step coded twice needlessly. I just want you to advise how I can do to overcome this.

preexisting method a class:

public class PaymentProfile
{
    public String Property1 = "";
    public String Property2 = "";
    public String Property3 = "";
    public String Property4 = "";
}

public PaymentProfile GetPaymentProfile(long aTicketType) {..}

class and method obtained after integration

public class PayCorePaymentProfile
{
    public String Property1 = "";
    public String Property2 = "";
    public String Property3 = "";
    public String Property4 = "";
    public String Property5 = "";
}

public PayCorePaymentProfile GetPayCorePaymentProfile(long aTicketType) {..}

What I thought

Creating a base class and then binding all sub-class with this base class, but I think it is not suitable for this case. Because I would return this base class without new property.

If I put everything in this base class, the old model has a new property needlessly.

*sorry for grammar rules and mistakes


Solution

  • There can be 1 Interface/BaseClass (with common properties) and 2 implementation of it with specific properties.

    public abstract class Profile
    {
        public string Property1 {get;set;}
        public string Property2 {get;set;}
        public string Property3 {get;set;}
        public string Property4 { get; set; }
    }
    
    public class PayCorePaymentProfile : Profile
    {
        public string Property5 { get; set; } = "9";
    }
    
    public class PaymentProfile : Profile
    {
        public string Property6 { get; set; } = "8";
    }
    

    Then based on the type, same Interface/BaseClass can be returned.

        public Profile GetPaymentProfile(string aTicketType)
        {
            if (aTicketType == "usePayCore")
                return new PayCorePaymentProfile(); 
            else
                return new PaymentProfile(); 
        }
    

    Then typecast can be used to get actual implementation

        public void ShowProfile1()
        {
            var profile1 = (PayCorePaymentProfile) GetPaymentProfile("usePayCore");
        }
    
        public void ShowProfile2()
        {
            var profile2 = (PaymentProfile)GetPaymentProfile("other");
        }