我很难理解有时打破单一职责原则是否可以接受,或者是否应该不惜一切代价避免。
请注意,以下代码已简化为仅保留相关部分。
我有 Hero
类,代表一个角色,它可以拥有多个不同的 Items
。
我有多个继承自 Items
的类,例如 QuestItems
和 BackpackItems
。
当我想在我的 Hero
上添加一个 Item
时,根据 Item
的种类,我应该采取不同的行动。
我尝试了 2 种不同的方法来做到这一点,第一种尊重 SRP:
public abstract class Item
{
private string _Name{get;set;}
public string Name
{
get
{
return _Name;
}
protected set
{
if (_Name != value)
{
_Name = value;
}
}
}
}
public class QuestItem: Item
{
public QuestItem(String name)
{
Name = name;
}
}
public class BackpackItem: Item
{
public BackpackItem(String name)
{
Name = name;
}
}
public class Hero
{
public void AddItem(Item item){
if(item is QuestItem){
//Do stuff to add QuestItem
return;
}
if(item is BackpackItem){
//Do stuff to add BackpackItem
return;
}
}
}
优点:SRP受到尊重
缺点:如果我创建了一个继承自 Item
的新项目种类,而忘记更改 Hero
中的 AddItem
函数,我会冒很多麻烦的风险。
我的第二个不遵守 SRP 的解决方案:
我的 AddItem 函数变成了
public void AddItem(Item item){
item.AddToHero(this);
}
我的 Items 类变成了:
public abstract class Item
{
private string _Name{get;set;}
public string Name
{
get
{
return _Name;
}
protected set
{
if (_Name != value)
{
_Name = value;
}
}
}
public abstract void AddToHero(Hero hero);
}
public class QuestItem: Item
{
public QuestItem(String name)
{
Name = name;
}
public override void AddToHero(Hero hero)
{
//Do my stuff to add my QuestItem to Hero
}
}
public class BackpackItem: Item
{
public BackpackItem(String name)
{
Name = name;
}
public override void AddToHero(Hero hero)
{
//Do my stuff to add my BackpackItem to Hero
}
}
优点:我不能忘记新项目种类的添加方法,因为我会在编译时出错。 缺点:我不尊重 SRP,但我现在真的不明白为什么会这么糟糕。
我应该更喜欢使用哪种实现方式? (另一个?)
最佳答案
那么,存储库中只能 Heros“拥有”项目吗?难道没有地点、非英雄角色(也许是怪物)等也可以拥有元素吗?
由于您提到这是简化的,因此很难就正确的方法是什么给出明确的答案。也许两者都不是。
对我来说,这类问题与其说是关于 SRP,不如说是关于某物应该有多通用,以及如何平衡它与 KISS。例如,它可能是一个更好的解决方案,可以将 Items 和 Heros 完全分开,而是有交互规则来确定可以以何种方式使用哪个对象是哪个英雄或角色。因为你可能面临的下一个问题是你有不同类型的英雄,可能是法师和战士,他们不能用相同的元素做相同的事情。
此外,请记住,OOP(单一)继承通常不能很好地映射到现实世界的情况;考虑改用更具组合性的模型。
关于c# - 是否应始终遵守 SRP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39795116/