Removing duplicate code with C++ policy-based design
Lately, I’ve been interested in some C++ template topics that help me design more flexible code. I didn’t explicitly search for them, but I met some cases that led me to find new ways of solving some specific problems.
A case is code duplication. I wanted to find a pattern for some duplicate code. I started with the idea of building components that I can compose however is needed. The first draft was using some lambdas and it was somehow OK. It did the job.
Then, looking around other aspects, I remembered that a friend keeps mentioning policy-based design. I had looked over it before, but I hadn’t found the need for it. But at that moment it clicked.
Let me get into code. I’m showing an oversimplified example because I don’t want to hide the main idea with details. If your real code is just as simple as the one I’m analyzing, do not jump on the idea before considering other approaches.
To give some hints about what follows: static polymorphism, composition, compile-time strategy. There are other approaches (runtime strategy, dynamic decoration), but I wanted to solve this at compile-time.
The goal
Straight forward, I want to remove the duplicate code using C++ policy-based design. It looks complicated at first. Just have patience.
I want to stick to the goal, so I omitted good naming, encapsulation, const correctness, noexcept and other details,
The problematic code
This is the code that has a duplicate piece of code – look for “DUPLICATE LINE” on lines 15 and 27 (for simplicity, it’s just one duplicate line):
#include <cassert> struct Object { int prop_1{}; int prop_2{}; int prop_3{}; }; void set_object_properties_1(Object& object) { if (object.prop_1 == 0) { object.prop_1 = 1; } object.prop_2 = object.prop_1 * 4; // DUPLICATE LINE object.prop_3 = object.prop_2 * 5 + object.prop_1 * 2; } void set_object_properties_2(Object& object) { if (object.prop_1 == 0) { object.prop_1 = 3; } object.prop_1 *= 2; object.prop_2 = object.prop_1 * 4; // DUPLICATE LINE object.prop_3 = object.prop_1 * object.prop_2; } int main() { Object object_1{}; set_object_properties_1(object_1); assert(object_1.prop_1 == 1); assert(object_1.prop_2 == 4); assert(object_1.prop_3 == 22); Object object_2{}; set_object_properties_2(object_2); assert(object_2.prop_1 == 6); assert(object_2.prop_2 == 24); assert(object_2.prop_3 == 144); }