I have a naive question about OOP design patterns. This is over-architecture, but I need a recommendation, not judgment. Suppose you have a class hierarchy dictated by “business requirements”. So, you’ve got a deeper version of Pizza : Freight, Flowers : Freight and a TonOfBricks : Freight and you’ve got an IDispatchService<F> where F : Freight and an IDeliveryService<F> where F : Freight.
Now suppose that different IDeliveryService implementations want different information about the freight. What they want does not parallel your class hierarchy, and you have no clue what delivery service (ie. API) you’re gonna use in a month for what kind of parcel. Furthermore, you may have enough information to send one pizza through a vacuum tube, but maybe not the next.
Now you realized that you can also hire people to deliver your pizzas on rollerblades, but you’ll need to specify the center of mass of every object delivered this way or else insurance will kill you. Do you implement it as an IDeliveryService<Pizza>? Are you also adding a new interface IHasCenterOfMass and maybe implementing as IDeliveryService<IHasCenterOfMass>? If so, how’s the dispatcher gonna like it? Are you adding a relation to your database for center of mass?
The trick is not to violate the substitution principle which states that every derived should be changeable with another derived as long as they share the same base class/interface. Therefore my recommendation would be to make your services accept a XXXServiceInformation instance which contains the specific information for that required service and knows how to potentially read it from source. Example: