Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Improve on a 13-parameter constructor

Thank Microsoft for Intellisense and Atomineer for Atomineer Utils...All of these parameters are required and immutable.

Is there a better way to do this?

/**************************************************************************************************
 * <summary>Initializes a new instance of the ADTBattleCharacter class.</summary>
 * <param name="name">         The name of the character.</param>
 * <param name="max_HP">       The maximum hit points.</param>
 * <param name="max_MP">       The maximum magic power.</param>
 * <param name="strength">     The strength.</param>
 * <param name="agility">      The agility.</param>
 * <param name="attack_power"> The attack power.</param>
 * <param name="defense_power">The defense power.</param>
 * <param name="gold">         The gold carried by the character.</param>
 * <param name="experience">   The experience the character is worth.</param>
 * <param name="stop_resist">  The character's resistance to stopspell.</param>
 * <param name="sleep_resist"> The character's resistance to sleep.</param>
 * <param name="hurt_resist">  The character's resistance to hurt/hurtmore.</param>
 * <param name="spell_list">   Available spells.</param>
 **************************************************************************************************/
ADTBattleCharacter(std::string name, unsigned char max_HP, unsigned char max_MP,
                   unsigned char strength, unsigned char agility,
                   unsigned char attack_power, unsigned char defense_power,
                   unsigned short gold, unsigned short experience,
                   double stop_resist, double sleep_resist, double hurt_resist,
                   std::bitset<SPELL_MAX> spell_list);
like image 728
Casey Avatar asked Jun 17 '12 02:06

Casey


2 Answers

Looking at your specific case, it seems to me that you haven't broken things out very well.

Conceptually, a character in your system has:

  • A name.
  • A stat block, containing their basic stats (HP, defense, etc).
  • The character's secondary attributes (experience).
  • An inventory, which would include their current list of spells and their gold, among potentially other things.

That's 4 parameters, not 13. When you're writing a function, and you see that it's taking a large number of parameters, odds are good that some of those parameters are conceptually linked to each other. And odds are also good that other functions will want to use those linked parameters.

For example, you may want to display a character's stat block. Does the function that does this really need the character? No; it just needs the stat block. So it should take a stat block object.

Just like the character's constructor does.

like image 162
Nicol Bolas Avatar answered Oct 13 '22 00:10

Nicol Bolas


The better way is to use the Builder design pattern. Or, more simply, you can declare a class that contains fields for all the parameters to your current constructor. The parameter class can itself have a constructor (or constructors) that initialize the fields to reasonable default values, and you change the values by accessing the fields directly. Then either implement a function in the parameter class to construct your object, or define an object constructor that takes an instance of the parameter class.

like image 45
Ted Hopp Avatar answered Oct 13 '22 00:10

Ted Hopp