class Item
{
// public:
// virtual int GetDamage() const { return -1; }
};
class Weapon : public Item
{
public:
Weapon(int InDamage)
:Damage(InDamage)
{
}
int GetDamage() const { return Damage; }
// virtual int GetDamage() const override { return Damage; }
private:
int Damage = 0;
};
class Armor : public Item
{
public:
Armor(int InDefence)
:Defence(InDefence)
{
}
int GetDefence() const { return Defence; }
private:
int Defence = 0;
};
class ItemManager
{
public:
ItemManager()
{
ItemMap.insert
({
{"Weapon", new Weapon(50)},
{"Armor", new Armor(100)},
});
}
Item* GetItem(const std::string& ItemName) const
{
const auto It = ItemMap.find(ItemName);
return It->second;
}
private:
std::map<std::string, Item*> ItemMap;
};
int main()
{
ItemManager Manager;
Item* ItemInst = Manager.GetItem("Weapon");
// const int Damage = ItemInst->GetDamage()
// Weapon* WeaponInst = dynamic_cast<Weapon*>(ItemInst);
// std::cout << WeaponInst->GetDamage() << std::endl;
return 0;
}
这是代码示例。
我所拥有的从物品中获得武器伤害的解决方案是
我对这些解决方案感到非常不舒服。
这就像我试图破坏“SOLID设计原则”。
我确信,有更好的解决方案,只是我不知道。
请教我最好的代码设计。
提前致谢。
使用dynamic_cast将物品投射到武器上。
没有
在 Item 类中添加 GetDamage 虚函数,并覆盖它,即使盔甲不需要。
也没有。如果您的所有项目都可以共享一个像
item->getName();
这样的通用接口,那么这个解决方案会很好。然而,在你的情况下,damage
显然只与武器相关,而defence
与盔甲相关。您的设计很快就会因您被迫覆盖的不相关方法而爆炸。
您的一个解决方案是使用通用接口来获取您的项目属性:
class Item {
public:
virtual ~Item() = default;
virtual int getProperty(std::string propName) = 0;
};
class Weapon : public Item {
public:
Weapon(int dam) { _props["damage"] = dam; }
int getProperty(std::string propName) override {
if (!_props.count(propName)) {
throw std::runtime_error("Property not found");
}
return _props[propName];
}
private:
std::unordered_map<std::string, int> _props;
};
你还可以有一个接口来获取所有这些,检查 prop 是否存在(无一例外),等等