我想要一个关于如何避免大量构造函数参数的通用解决方案。我在此处提供的示例只是示例,对于此处的确切示例,我不想要具体的答案。话虽如此,我的问题显然是在我的构造函数中有太多参数。
我有一个用于任何类型的人(士兵、巫师、商人等)的基类,称为Person
. 我的Person
课程相当简单,它实现了每个人都有的基本事物。假设我有以下属性,我的构造函数为每个属性接受一个参数:
string firstName
string surname
uint health
uint maxHealth
- 我们不希望任何人拥有 999999999 的健康...uint movementSpeed
- 并不是每个人都以同样的速度奔跑,对吧?
所以构造函数看起来像:
Person::Person(const string &firstName="Missing first name",
const string &surname="Missing surname",
const uint health=100,
const uint maxHealth=100,
const uint movementSpeed=50) :
m_firstName(firstName),
m_surname(surname),
m_health(health),
m_maxHealth(maxHealth),
m_movementSpeed(movementSpeed)
{}
现在想象一个新类,在继承树的深处,称为Wizard
. 大多数巫师都是为了战斗而存在的,所以他们也可以攻击等等。巫师的构造函数可能如下所示:
Wizard::Wizard(const string &firstName="Missing first name",
const string &surname="Missing surname",
const string &wizardName="Missing wizard name",
const uint health=100,
const uint maxHealth=100,
const uint mana=100,
const uint maxMana=100,
const uint strength=50, // physical damage
const uint witchcraft=50, // spell damage
const uint armor=30, // vs. physical damage
const uint resistance=30, // vs. spell damage
const uint movementSpeed=50) :
Warrior(firstName, surName, health, maxHealth, strength, armor, resistance, movementSpeed),
m_wizardName(wizardName),
m_mana(mana),
m_maxMana(maxMana),
m_witchcraft(witchcraft)
{}
可能还有更多的争论,但我想你明白了。这看起来可能还不错,但想象一下看一个陌生人的代码并看到如下内容:
Wizard *wiz = new Wizard("Tom", "Valedro", "Lord Voldemort", 300, 400, 200, 200, 10, 500, 30, 400, 300)
有人可能会说“还不错,看文档就行了!” 海事组织。这太糟糕了,并且使代码非常难以阅读甚至编写。此外,参数的顺序也很难让人跟踪。
我想到的解决方案很少,但它们也有缺点。一件事是使用默认构造函数并且根本不给它任何参数,然后使用 setter 来完成这项工作:
Wizard *wiz = new Wizard;
wiz->setFirstName("Tom");
wiz->setSurname("Valedro");
...
当然,这会产生几十行额外的文本,而且有些人几乎不反对 getter 和 setter。它将摆脱没有意义的数字,至少你可以阅读每个数字的作用(wiz->setHealth(100);
显然告诉我们在这里设置健康)。
另一种解决方案是将一些属性组合到结构中。我可以轻松地将firstName
,surname
和wizardName
( 甚至更好地使用nickname
) 合并到一个Name
类或结构中。这将减少我在此示例中的论点数量,但正如我所说,我想要一个针对此类问题的一般答案。即使在组合了其中一些参数之后,仍然可能存在非常多的论点,或者您可能无法组合任何原因它们根本不相似。