我正在努力遵守良好的 OO 设计原则和设计模式等。因此,在开发我的这个 C# 应用程序时,我经常可以找到设计和架构问题的多种解决方案,我一直想找到并实现更“规范”的一个,以期构建高度可维护和灵活的软件,并成为一个更好的 OO 程序员.
假设我有这两个抽象类:Character
和 Weapon
.
abstract class Weapon
{
public string Name { get; set; }
}
abstract class Character
{
public Weapon weapon { get; set; }
}
派生类可能是 Sword
和 Staff
来自 Weapon
, 和 Warrior
和 Mage
来自 Character
等(这都是假设,与我的实际软件无关!)。
每个 Character
有一个 Weapon
, 但对于 Character
的每个实现我知道 Weapon
的实现方式它将有。例如,我知道(并且我想强制执行!)在运行时 Warrior
的每个实例会有一个 Weapon
类型 Sword
.我当然可以这样做:
class Sword : Weapon
{
public void Draw() { }
}
class Warrior : Character
{
public Warrior()
{
weapon = new Sword();
}
}
但是这样,每次我想使用我的Weapon
在 Warrior
中正确地放置对象,我必须表演 Actor ,我认为这是一种不太好的练习。我也没有办法防止自己搞砸,那就是没有类型安全!
理想的解决方案是能够覆盖 Weapon weapon
Warrior
中的属性(property)类 Sword weapon
属性,这样我就有了类型安全,如果用户使用我的 Warrior
作为Character
, 他仍然可以使用我的 Sword
作为Weapon
.遗憾的是,C# 似乎不支持这种构造。
所以这是我的问题:这是某种经典的 OO 问题,有名称和有据可查的解决方案吗?在那种情况下,我非常想知道问题的名称和解决方案。一些指向良好阅读 Material 的链接将非常有帮助! 如果不是,您会建议采用哪种类设计来以优雅和惯用的方式维护功能并强制类型安全?
感谢阅读!
最佳答案
更新:这个问题是 a series of articles on my blog 的灵感来源.感谢您提出有趣的问题!
is this some kind of classical OO problem, with a name and a well-documented solution?
您在这里遇到的根本问题是,在 OO 系统中很难向 子类 添加限制。说“角色可以使用武器”然后“战士是一种只能使用剑的角色”很难在 OO 系统中建模。
如果您对此背后的理论感兴趣,您会想要寻找“Liskov 替换原则”。 (还有关于为什么“Square”不是“Rectangle”的子类型的任何讨论,反之亦然。)
但是有一些方法可以做到。这是一个。
interface ICharacter
{
public IWeapon Weapon { get; }
}
interface IWeapon { }
class Sword : IWeapon { }
class Warrior : ICharacter
{
IWeapon ICharacter.Weapon { get { return this.Weapon; } }
public Sword Weapon { get; private set; }
}
现在 Warrior 的public表面区域有一个始终是剑的武器,但是任何使用 ICharacter
界面的人都会看到一个 Weapon
属性这是 IWeapon
类型。
这里的关键是摆脱“是一种特殊的”关系,转向“可以履行契约”的关系。与其说“战士是一种特殊的角色”,不如说“战士是一种在需要角色的时候可以使用的东西”。
综上所述,您将着手处理一个充满迷人问题的世界,您会发现 OO 语言在表示这些事物方面的真正表现有多么糟糕。一旦开始提出更复杂的问题,例如“当战士使用锋利的剑攻击穿着皮甲的兽人时会发生什么? “并发现你有四个类层次结构——角色、武器、怪物、盔甲——所有这些都有影响结果的子类。虚方法只允许您分派(dispatch)一个运行时类型,但您会发现您需要两层、三层、四层或更多层的运行时类型分派(dispatch)。
事情变得一团糟。考虑不要尝试在类型系统中捕获太多内容。
关于c# - 强制继承类中继承成员的类型安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28521381/