1

The "D" in SOLID stands for dependency inversion. If I have for example, a Blacksmith class that depends on Hammer, I should create my Hammer externally and pass it to Blacksmith, rather than having Blacksmith create her own Hammer. This makes it easy for me to give my Blacksmith a DeluxeMagicHammer instead without having to modify her behavior.

This makes sense when my dependencies are defined and instantiated in code. But what if my dependencies are defined in data instead, for example in a JSON or XML schema? I'd like to hand war-cart-blueprints.xml to my Blacksmith and have her read and use that information to create 4 Wheels, 2 Axles, a Cabin, etc., and put them together into a WarCart. This seems like I'm now creating a tight coupling between Blacksmith and these various components.

To satisfy SOLID, do I need to separate these dependencies somehow? Would I need a WheelFactory, AxleFactory, and CabinFactory, each of which look at the same war-cart-blueprints.xml to build the components they're responsible for, and then pass them to Blacksmith for assembly? What if there are some dependencies between WheelFactory and AxleFactory, such that they would need to communicate to accomplish their respective tasks? For example Wheels might have a central hole diameter, but the blueprints only specify that diameter in the Axle specifications. Or, the dimensions of Cabin are determined from some complex calculation based on the length of the Axles and the number of Wheels.

It seems like it would be much simpler to let Blacksmith create and assemble the components herself, especially if she is the only one who is ever going to use them.

  • 2
    Rather than asking SOLID to make your design for you, I think you should make your own design, and then have SOLID inform that design in ways that improve it. The goal of any design is to solve a computing problem, not to satisfy SOLID. The computing problem comes first, in other words. – Robert Harvey Apr 4 '16 at 1:38
4

If I hand my blacksmith a hammer, that means that the blacksmith doesn't need to know the finer details of which hammer to get; I just need to hand him the most appropriate hammer for my intended job.

Whether your dependencies are in code or data does not matter. In all likelihood, if your dependencies are in data, they represent configuration information for objects that you're going to hand to the blacksmith via DI anyway.

The real difference between your two scenarios is that the dependencies are much more complex in the car scenario. Because of this, you're more likely to hand the "blacksmith" an Abstract Factory or a collection of car parts.

  • If the final assembly of the cart is trivial compared to manufacturing the components, couldn't I just have Blacksmith be my abstract factory, and then implement a WarCartBlacksmith? – alexw Apr 4 '16 at 2:08
3

The questions to ask in designing:

What information does Blacksmith need when they are "building" an object?

How do the different things a blacksmith can make affect the behaviour of Blacksmith?

Does Blacksmith need to know details like axles and wheels? Or does it just need to know it is building a WarCart and it will require 7 iron and 3 wood, and take 4 days with a standard Hammer.

So - WarCart is a Buildable object - it has components (which are also Buildable) like wheels and axles which each have material and time costs. Now all Blacksmith needs to do is ask the Buildable interface of WarCart how much of what material and time is needed with methods like cost() and time().

I would then have a BuildableFactory that takes the configuration for the object being built and its components, and generates the WarCart or Trebuchet or whatever.

So, your various blacksmiths can then call on the BuildableFactory whenever you want to add a buildable item into their build queues.

2

You just hit one of the more nuanced problems with SOLID. That it greatly increases complexity of your application. Especially dependency injection. But you get much greater flexibility with your code for that complexity.

So it is up to you to use your experience and expertise as software developer : Is the improvement in flexibility of the code worth the increase in complexity? This is extremely hard question to answer, and for which there exists no "patterns" or "principles". And we won't be able to help you unless we know and fully understand ALL requirements you have and understand your domain so we can at least somehow predict changes in those requirements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.