C++ The Modern Factory

Vintage car factory

I think I have architected, designed and implemented, what might be a (bit) better  Factory Pattern. Of course, I am pretty sure someone else has discovered the same variation.

Of all the patterns, very often, I was particularly bothered with “classical” aka legacy, Factory. Yes, once implemented, you can relatively easily make it create new “things”, but on the design and usability level, to me,  it does not look very flexible and expandable.

On the C++ level, it requires code repetition and the use of smart pointers. In essence, these two combined, somehow do not look to me like modern C++ at all.

Classical aka “Legacy” Factory Pattern. Looking at the diagram this seems very simple and obvious. For this post, we will use the real-life use-case of the “Car Factory”.  In particular to try and explain the architectural issues.

Now consider this.  Using the architecture above, how would you serve contemporary customers and offer them “build your own car” service?  Some online page, where customers start with some half-finished base of the car and then pick and mix a variety of engines, headlights, wheels, seats, sunroof, etc … all the way to the details like in-car sound and vision, and a such.

The architecture above is made for factories that deliver ready-made, possibly pre-built, finished cars. It is surely possible to re-organize the internals of the factory to make different variations to each model, but there is a practical limit. The more customers can pick-n-mix, the number of ever so different models raises exponentially.

The inherent flaw in this architecture is the high level of abstraction granularity. Which in turn greatly lowers the level of architecture flexibility and resilience to change.

Implementation issues

I have come to the conclusion, in each Factory pattern variation, the actual factory method, class, or whatever, is the focal point of quality issues, where one can feel the design on top of which the implementation resides.

Here is the factory method of the classical factory.

What is wrong with this code? Not much. It is only that this is almost C++98.

As the only modern thing, car_smart_pointer is usually implemented; with us at least since C++11, which was standard since Aug 2011 (gasp!) But there were many quality smart pointer implementations before that. (Of course, I do not mean std::smart_ptr ).

We need to use the (smart) pointer here. It is not possible to return an instance of Abstract Base Class. And this is how the automobile is implemented.

And then we implement our two-car models by simply inheriting from this ABC.

class cabriolet from the diagram is almost the same. This is where we meet head-on, two things I do not like :

  • Inheritance
  • Code repetition

And then we invent clever design and then we “invent” coding idioms to mitigate the issues of these two.   If you are by now, standing in shock or are in hot disagreement, please refer to numerous online discussions on classical factory pattern implementation issues.

I particularly like Sean Parent’s  Inheritance Is The Base Class of Evil. It is about that and much more important things. Every minute is full of quality c++ and quality design decisions. Not easy to follow but worth it.

Modern Factory

The variation that I am calling “Swappable engines factory”. It is not just engines but this makes for a short title, which I think succinctly conveys the message.

Swappable engines factory
Swappable engines factory

Here the factory method is not the second fiddle. It is instead the key player. The product (Car in this use case) is actually assembled (put together)  in the factory function. There is no such thing as a “finished car” in this architecture.

Let us discuss the factory method.

This is a proper modern C++.  No smart pointers needed. We are enjoying the value semantics made much easier to use with the help of a modern C++ compiler.

Copy elision on return by value is now de-facto standard in all modern compilers. C++ 17 “Guaranteed Copy Elision”, very simple explanation.

Above is C++17 and in essence compiled into:

But beware. That is far from simple as it seems above.

This architecture will be easy to extend to offer the flexibility of composing the car, not before the customer (aka client) code requests a particular combination. For example.

“Swappable Engine Factory” architecture users. do not have to worry about how many different models there are and will be. Implementation of it simply builds the car on the spot. Usage is rather simple.

There are few more important details that are making this design possible to implement into simple and resilient modern C++.   On the next page is the GitHub gist.

The Conclusion

This code is compiled and tested in Visual Studio 2017, with the latest MSVC as of 2018 June. This is not a “production code” it is more of a “proof of concept”. In case of bugs found, just wishing to comments or whatever please do not hesitate to contact me.

The eagle-eyed reader might jump on me using inheritance even in this modern factory.  And native pointer, gasp!  My answer: I know about Polymorphism without inheritance. It is not the focus of this post. It might be in the very near future in some future posts on this same subject.

Also in this architecture, this is also an “implementation detail”. So do we use it and will we change it, is completely hidden from the client code, which will work unchanged, in case of changes.

https://gist.github.com/DBJDBJ/c4df39f5df2188de41dce6de260a7c58

I hope you will be able to apply this rather improved factory pattern to your use cases and projects.