如何使这个C++代码更干?

Mac*_*cha 8 c++ dry code-cleanup

我在一个只有一个方法调用不同的类上有这两个方法.显然,这是非常干燥的,特别是因为两者都使用相同的公式.

int PlayerCharacter::getAttack() {
    int attack;
    attack = 1 + this->level;
    for(int i = 0; i < this->current_equipment; i++) {
        attack += this->equipment[i].getAttack();
    }
    attack *= sqrt(this->level);
    return attack;
}
int PlayerCharacter::getDefense() {
    int defense;
    defense = 1 + this->level;
    for(int i = 0; i < this->current_equipment; i++) {
        defense += this->equipment[i].getDefense();
    }
    defense *= sqrt(this->level);
    return defense;
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能在C++中整理它?

Bil*_*rin 18

一种简单的方法是在数组中表示设备的所有属性,由枚举索引.

enum Attributes {
  Attack, 
  Defense,
  AttributeMAX
};

class Equipment {
  std::vector<int> attributes;

  Equipment(int attack, int defense): attributes(AttributeMAX)
  {
    attributes[ATTACK] = attack;
    attributes[DEFENSE] = defense;
  }

};
Run Code Online (Sandbox Code Playgroud)

然后你将你的功能改为

int PlayerCharacter::getAttribute(int& value, Attribute attribute) {
    value = 1 + this->level;
    for(int i = 0; i <= current_equipment; i++) {
        value += this->equipment[i].attributes[attribute];
    }
    value *= sqrt(this->level);
    return value;
}
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它

  player.getAttribute(player.attack, Attack);
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案,因为它不会混淆代码的意图.但是,它确实倾向于混淆使用.但这很容易通过创建两个名为getAttack和getDefence的包装程序来解决,而这些例程又用例程调用.(编辑)但我会说,player.getAttribute(player.attack,Attack)本身就很清楚了. (2认同)

War*_*rty 12

在我看来,你所拥有的是好的,因为它可以让你调整攻击/防御比你用一个函数代表他们两个更多.一旦你开始测试你的游戏,你将开始平衡攻击/防御公式,所以为它们提供单独的功能是好的.

DRY [不重复自己]的整个概念[希望]可以防止你的代码成为一个巨大的复制和粘贴节目.在你的情况下,防御/攻击公式会随着时间而改变[例如,如果角色有buff /状态 - 疾病怎么办?特定状态疾病可能会将防御减少一半,同时将攻击力提高2(Berserk,FF参考,heh)]


Ecl*_*pse 6

从严格的重构角度来看,您可以这样做:

int PlayerCharacter::getDefense() {
    return getAttribute(&EquipmentClass::getDefense);
}

int PlayerCharacter::getOffense() {
    return getAttribute(&EquipmentClass::getOffense);
}

int PlayerCharacter::getAttribute(int (EquipmentClass::*attributeFun)()) {
    int attribute = 0;
    attribute= 1 + this->level;
    for(int i = 0; i <= current_equipment; i++) {
        attribute += this->equipment[i].*attributeFun();
    }
    attribute *= sqrt(this->level);
    return attribute;
}
Run Code Online (Sandbox Code Playgroud)


Nai*_*ler 5

好吧,我至少会考虑将提取sqrt(this.level);作为一个单独的函数称为getLevelModifier()

defense = 1 + this.level;

attack = 1 + this.level;
Run Code Online (Sandbox Code Playgroud)

可能

defense = getBaseDefense();

attack= getBaseAttack();
Run Code Online (Sandbox Code Playgroud)

这不仅增加了灵活性,而且还自动记录了您的功能。