While identifying the survival kit class we left out a presumably important method like purchase.
The initial hunch was to define it in the SurvivalKit class though a survival kit seems to better relate with an order (hint).
Looking at the SurvivalKitOrder there is a code property and a collection of SurvivalKit(s). (people might want to order more than 1 kit after all) Should we define the purchase method in the SurvivalKitOrder? Let's see.
First of all, in order for the purchase method to work we need to have both the ShippingMethod and the Address to dispatch. Should the SurvivalKitOrder class use the ShippingMethod and Address through its purchase method?
Ask yourself the following questions.
- Would you send the same order to the same address using a different shipping method?
- Would you send the same order to a different address on the same shipping method?
- Would you send the same order to a different address all together?
In any case, an order it's not something you would reuse, since each must have a unique code. Thus you will need to create a new one every time.
So it only makes sense that you define both the ShippingMethod and the Address as properties to the SurvivalKitOrder. (after all an order must have a shipping method and an address associated)
Single responsibility is one thing and indeed SurvivalKitOrder sole responsibility is dealing with a purchase but don't forget about the importance of well defined class relationships. The SurvivalKitOrder suddenly has a strong (e.g. can't have one without a ShippingMethod and an Address) relationship with 2 other classes. Now there is nothing inheritly wrong with that, but there might be a better way. After all you don't need another complicated relationship in your hands.
Leave your thoughts below on where you would define the purchase method. Don't forget your reasoning behind it.
Disclaimer: As in every object oriented design there is a reasoning behind it all. Depending on the problem you are trying to solve most likely will differ. Not everything related to software engineering should be treated as gospel and as a developer you should apply critical thinking before making any decisions. Use that.