Search code examples
c#oopobject-oriented-analysisooad

c# Multiple base classes


I'm having a little problem designing my classes.

What I want to do is the following: There are 4 classes with each their own properties. A physical and mailing address can be national or international. The contact class should have two properties of some type where I can access all the needed properties.

I've tried to a create base classes for national/international and for physical/mailing but I'm struggeling with the fact they all have different properties.

How would you model the classes in a proper way? Is it even possible in c#? I'm afraid I'll just have to create 4 properties on Contact for each of the 4 classes and do a null check to see which type of adress the object has.

class Program
{
    static void Main(string[] args)
    {
        Contact c = new Contact();
    }
}

public class Contact
{
    public xxx PhysicalAddress { get; set; }
    public xxx MailingAddress { get; set; }
}

public class NationalAddress
{
    public bool IsDeleted { get; set; }
    public DateTime CreationDate { get; set; }

    public Country Country { get; set; }
    public PhoneNumber Landline { get; set; }

    public string Street{ get; set; }
    public string HouseNumber{ get; set; }
    public string PostalCode{ get; set; }
    public string City{ get; set; }
}

public class InternationalAddress
{
    public bool IsDeleted { get; set; } 
    public DateTime CreationDate { get; set; }

    public Country Country { get; set; }
    public PhoneNumber Landline { get; set; }

    public string AdresRule1 { get; set; }
    public string AdresRule2 { get; set; }
    public string AdresRule3 { get; set; }
}

public class PhysicalAddress
{        
    public bool IsDeleted { get; set; }
    public DateTime CreationDate { get; set; }

    public bool IsVerified { get; set; }
    public DateTime ValidFrom { get; set; }
    public DateTime? ValidTo { get; set; }

    //Semi-detached/Terraced/Appartment/...
    public TypeOfBuilding Building{ get; set; } 
    public bool Occupied { get; set; } 
}

public class MailingAddress
{
    public bool IsDeleted { get; set; }
    public DateTime CreationDate { get; set; }

    public bool IsVerified { get; set; }
    public DateTime ValidFrom { get; set; }
    public DateTime? ValidTo { get; set; }

    public bool AllowCommercialPress { get; set; }
    public bool AllowOfficialPress { get; set; }
}

Regards,

Miscode


Solution

  • Part 1

    A different approach this time --> I refactored your original properties / classes a bit.

    AddressRule vs separate properties

    Why doesn't an InternationalAddress have a Street, HouseNumber, ... etc? I refactored this into a List which can have one entry for your NationalAddress and multiple entries for your InternationalAddress.

    Validation properties

    Why are these validation properties in the Physical / Mailing address? From what I can tell these should be in the highest level.

    public class Contact
    {
        public PhysicalAddress PhysicalAddress { get; set; }
        public MailingAddress MailingAddress { get; set; }
    }
    
    public class AddressRule
    {
        public string Street { get; set; }
        public string HouseNumber { get; set; }
        public string PostalCode { get; set; }
        public string City { get; set; }
    }
    
    public class BaseAddress
    {
        public bool IsDeleted { get; set; }
        public DateTime CreationDate { get; set; }
    
        public Country Country { get; set; }
        public PhoneNumber Landline { get; set; }
    
        public List<AddressRule> AdressRules { get; set; }
    
        public bool IsVerified { get; set; }
        public DateTime ValidFrom { get; set; }
        public DateTime? ValidTo { get; set; }
    }
    
    public class PhysicalAddress : BaseAddress
    {        
        //Semi-detached/Terraced/Appartment/...
        public TypeOfBuilding Building { get; set; }
        public bool Occupied { get; set; }
    }
    
    public class MailingAddress : BaseAddress
    {       
        public bool AllowCommercialPress { get; set; }
        public bool AllowOfficialPress { get; set; }
    }
    

    Part 2

    If you really need a separate class for International and National I propose to create a property of type AddressBase in your Physical / Email class which. This AddressBase property can then be either International or National.

    public class Contact
    {
        public PhysicalAddress PhysicalAddress { get; set; }
        public MailingAddress MailingAddress { get; set; }
    }
    
    public class AddressBase
    {
        public bool IsDeleted { get; set; }
        public DateTime CreationDate { get; set; }
        public Country Country { get; set; }
        public PhoneNumber Landline { get; set; }
    }
    
    public class NationalAddress : AddressBase
    {
        public string Street { get; set; }
        public string HouseNumber { get; set; }
        public string PostalCode { get; set; }
        public string City { get; set; }
    }
    
    public class InternationalAddress : AddressBase
    {
        public string AdresRule1 { get; set; }
        public string AdresRule2 { get; set; }
        public string AdresRule3 { get; set; }
    }
    
    
    //I'm guessing Mailing and Physical is meant to know where to ship to, hence the "Transport" prefix.
    public class TransportAddressBase
    {
        **public AddressBase AddressBaseInformation{ get; set; }**
    
        public bool IsVerified { get; set; }
        public DateTime ValidFrom { get; set; }
        public DateTime? ValidTo { get; set; }
    }
    
    
    
    public class PhysicalAddress : TransportAddressBase
    {       
        //Semi-detached/Terraced/Appartment/...
        public TypeOfBuilding Building { get; set; }
        public bool Occupied { get; set; }
    }
    
    public class MailingAddress : TransportAddressBase
    {       
        public bool AllowCommercialPress { get; set; }
        public bool AllowOfficialPress { get; set; }
    }