Thursday, April 21, 2011

Design Patterns - The WHY

Over time I have had the pleasure and indeed on rare occasions the misfortune to interview many software engineers.

One thing that you learn in interviews is how poorly some basic ideas are understood....

Factories
A very common misconception is the humble Factory Class.

A lot of people seem to miss the point. It's often been described as a place to collect together constructors, as if bunching them together in a single file was a goal in itself.

It's the WHY question that matters. Why on earth would you use a factory class?

The answer is quite simple. It's all about reducing dependencies.

It's all about dependencies
If I have a class ShapeManager that understands and cares about shapes, but has no particular need to know about or care about the particular type of a shape, then I want to preserve that separation. I am prepared to go to quite some lengths to prevent that class ever knowing about a Square, Circle or Triangle. As soon as it does know about individual shapes all is lost.

For example, if I suddenly see the error of my ways and change all the Simple Regular Polygons to a single class, my ShapeManager should ideally remain unchanged. I should not have to go into ShapeManger and look for all places where I have a particular instance of Square, Triangle, Pentagon, etc. and change them. That way lies madness.

Loading Shapes
Somewhere it the ShapeManger, I may care to load in Shape from a file. I could code it directly, but then my ShapeManager needs to start knowing about the types of Shape in the file. Madness I tell you.

What if I pass in an IShapeFactory, in this case an instance of ShapesFromAFileFactory()?

Now my ShapeManager sees an Interface which has a Function GetNextShape(), which unsurprisingly returns a Shape.

Now when I add a Simple Regular Polygon, or change the way shapes are stored, or even move the storage of the Shapes to the database, ShapeManager remains unchanged.

And I can also pass in an ShapesForTestingFactory() in my unit tests and run the tests without any external dependence on databases or Files.

The ShapeManager code is now more testable, it's less fragile, and please don't underestimate this part, it's more understandable to people who know about standard design patterns.
That bit matters a lot in a large software team. Depending on schedules, any of a half a dozen engineers with a passing knowledge of an area may be working on a change or a fix. If they see a Factory and know from roughly what is going on, then there's less "figuring out" to do before they can get started.

No comments:

Post a Comment