Maintaining encapsulation seems to promote redundant classes I have two classes that are extremely similar and it seems a bit redundant but I want to maintain encapsulation.

First I have a servicestack route that accepts the following Request class:

public class CreateManualShipmentRequest
{
    public Address Sender { get; set; }
    public Address Recipient { get; set; }
    public PackageSizeAndWeight Package { get; set; }
    public Payor Payor{ get; set; }

    public List&lt;string&gt; SpecialServices { get; set; }
    public decimal InsuredValue { get; set; }
    public string ServiceType { get; set; }
    public string ServiceProvider { get; set; }

    public string LabelImageFormat { get; set; }
    public bool TestMode { get; set; }
}


So I need to take this information and pass it to a function that creates a specific request based on the provider. For example:

FedexHelpers.BuildFedexCreateShipmentRequest();


The easiest way to pass the information I need would be to make the function accept the request object as a parameter. These seems to violate encapsulation however because the function doesn't need to know it's a request, what provider has been selected. This lead me to create a new class:

public class ShipmentRequestInfo
{
    public Address Sender { get; set; }
    public Address Recipient { get; set; }
    public PackageSizeAndWeight Package { get; set; }
    public Payor Payor { get; set; }

    public List&lt;string&gt; SpecialServices { get; set; }
    public decimal InsuredValue { get; set; }
    public string ServiceType { get; set; }
}


So now I can pass the builder function this object without sharing any information about the request object at all. I even created a constructor that accepts the request object:

public ShipmentRequestInfo(CreateManualShipmentRequest request)
{
    Sender = request.Sender;
    Recipient = request.Recipient;
    Package = request.Package;
    Payor = request.Payor;

    SpecialServices = request.SpecialServices;
    InsuredValue = request.InsuredValue;
    ServiceType = request.ServiceType;

    LabelImageFormat = request.LabelImageFormat;
}


I feel I have achieved encapsulation this way as I can create the ShipmentRequestInfo wherever I need but it seems redundant to have such a similar class.

I was thinking about other possibilities and came up with a few:


Have the request class contain a ShipmentRequestInfo object. This will make it harder to read, you'd have to dig into the ShipmentRequestInfo class to read the object. It would also require the JSON sent to the API route to be nested one layer further.
Overload the builder function to accept a request object or a generic object. This might cut down on a bit of code, I wouldn't need the constructor in the ShipmentRequestInfo object, and I wouldn't have to create it to pass it to the builder function. What I don't want to end up is with a function that has too many overloads though.
Have CreateManualShipmentRequest inherit ShipmentRequestInfo. I'm not sure if this is a better option than having ShipmentRequestInfo as a property of CreateManualShipmentRequest, it seems pretty similar except that it couples the classes together more tightly?


I'm pretty new to OOP and want to make sure I'm considering all my options and designing classes properly.
What I see here is a great scenario for composition!

What you say is that you're annoyed because CreateManualShipmentRequest already has the shipment informations. Alright so, why doesn't CreateManualShipmentRequest contains ShipmentRequestInfo instead of repeating all the information?

public class ShipmentRequestInfo
{
    public Address Sender { get; set; }
    public Address Recipient { get; set; }
    public PackageSizeAndWeight Package { get; set; }
    public Payor Payor { get; set; }

    public List&lt;string&gt; SpecialServices { get; set; }
    public decimal InsuredValue { get; set; }
    public string ServiceType { get; set; }
}

public class CreateManualShipmentRequest
{
    public ShipmentRequestInfo ShipmentRequestInfo { get; set; }

    public string ServiceProvider { get; set; }

    public string LabelImageFormat { get; set; }
    public bool TestMode { get; set; }
}


You're right that having redundant code is a code smell, but creating another class to keep encapsulation is most of the time a pretty good thing to do.

I wanted to address the comment stating that you could use interfaces. I feel like it's not a bad solution, but I don't think it's the right one.

Implementing an interface is kind of a "is a" relationship.

But, could you say : "CreateManualShipmentRequest is a ShipmentRequestInfo? I don't think so. Though, saying "CreateManualShipmentRequest contains ShipmentRequestInfo" seems pretty logical to me!

Sure, readability and serialization are good points. For the serialization, well.. APIs are good, you'll have to write a little bit more code to deal with that. Readability itself isn't that affected. But are those points valuable than :


Not having redundant code
Passing the wrong object to a method
Implementing an interface that is misleading


? I feel like you should use composition.