My team works on an HTTP web server in C++. The codebase has aged over time, and has a widespread problem of 12+ parameters being passed to every function.

A fake example: We need to build a Car, but in order to do that, we have the following function:

MaybeBuildCar(engine_params, steering_params, interior_params, fuel_params, available_inventory, parts, &debug);

Someone on our team has proposed that we create a wrapper CarBuilder class whose constructor takes in the params and "stateful" objects like available_inventory, then has a separate function for BuildCar as follows:

CarBuilder car_builder(engine_params, steering_params, interior_params, fuel_params, available_inventory, &debug);

auto car = car_builder.BuildCar(parts);

Personally, I don't see much value in having a class with a single public function that is always called. We'll always need these parameters, and we'll always need the parts, so this just adds more steps to build the car. It could even add confusion, as now a user of CarBuilder must know to both construct it and call BuildCar.

Admittedly, this simplifies our helper functions within car_builder.cc, as they also require passing these params, but to me that's misusing what a class is for: maintaining state.

Is creating this CarBuilder a misuse of the class, or is simply cleaning up function signatures a valid use? Does anyone have any suggestions on how to tackle this problem?

  • 2
    "Is creating this CarBuilder a misuse of the class" - no; unlike C structs, classes (or, rather objects) are not primarily for maintaining state, but for modeling behavior. The fact that you're considering leaving the parts parameter indicates a certain usage pattern: perheps parts changes more often than the others (e.g., maybe you can construct the car_builder once, but create several car objects with different parts - that's less code to write). Or you can create several preconfigured builders - maybe that's useful. You can also pass the builder object around to other components. – Filip Milovanović Feb 11 at 23:39
  • Interesting. Indeed, the parts change more than the other params. – DonutGaz Feb 11 at 23:51
  • For whatever it's worth, you can do something similar in a more ad-hoc fashion using lambdas: auto just_add_parts = [=](auto parts_arg) { MaybeBuildCar(engine_params, steering_params, interior_params, fuel_params, available_inventory, parts_arg, &debug); };. That lets you do auto car = just_add_parts(parts); later, and you don't have to design a builder class mechanism. Which is best varies. – Tony Feb 20 at 1:16

Your Answer

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

Browse other questions tagged or ask your own question.