【问题标题】:Designing good classes and hierarchies设计好的类和层次结构
【发布时间】:2014-12-06 07:48:50
【问题描述】:

我正在学习 C#,并决定为矩阵及其功能编写一个类库,以获得一些经验和实践。

好的,现在我有以下类模型:

class Matrix // For rectangular matrices
{ }

class SquareMatrix : Matrix
{ }
class RowMatrix : Matrix
{ }
class ColumnMatrix : Matrix
{ }

每个类都有一个合适的构造函数来获取特定矩阵的维度或顺序。

现在我的 SquareMatrix 类有一个特定的函数来查找和返回行列式。我在这里面临的问题是,如果我的库的用户创建了尺寸为 n 和 n 的 Matrix 类型的实例,那么他将无法使用 Determinant() 方法,因为它仅驻留在 SquareMatrix 中,而他的实例是 Matrix 类型.

其他方法也可能出现类似问题。


所以我的问题是:

  1. 我的班级设计有缺陷吗?
  2. 有没有办法解决这个问题? (或者(尽管机会很少)我应该期望用户正确实例化对象吗?)

提前谢谢大家:)

【问题讨论】:

  • 没有完美的解决方案,只是在继承方面没有很好地表示关系。见circle-ellipse problem
  • 非常好的链接,谢谢!
  • 好吧,当然,最简单的解决方案是简单地摆脱所有继承并使用异常或布尔返回来检查有效性。但这并不是 OOP 的真正意义在于......

标签: c# class inheritance


【解决方案1】:

好问题。

我认为:

用户应负责实例化正确的实例。如果用户想要一个矩阵,那么这就是他得到的。如果 Matrix 中不存在该函数,那就太糟糕了。

但是,如果您有一个通用函数,它的行为取决于它是什么类型的 Matrix,那么在这种情况下,您将创建一个返回 Matrix 的工厂。它将根据参数返回适当的矩阵。用户会在 Matrix 上调用该函数,但它的行为实际上会有所不同,具体取决于您实际返回的 Matrix。

【讨论】:

  • 好主意。因此,我可以将所有构造函数设为私有,并拥有另一个静态成员来实例化并返回适当类型的矩阵。但是,我是否不需要用户使用对象的“动态”创建来允许这样做?动态不会对性能造成轻微影响吗?
【解决方案2】:

您在这里要对抗的是 Liskov 替换原则。基本上你需要做的不是使用旧的“... is a ...”来计算超/子类。而是尝试使用“...Is substitutable for...”

如果您刚开始使用 C#,那么您的第一站应该是学习 SOLID 的原理。对于您在 S 和 L 上的回答工作

这将帮助您解决 L,http://www.oodesign.com/liskov-s-substitution-principle.html

看看这个 SOLID,http://www.codeproject.com/Articles/703634/SOLID-architecture-principles-using-simple-Csharp

当你想在 I 和 D 上工作时,他们是我的最爱

戴尔

【讨论】:

    猜你喜欢
    • 2011-05-07
    • 2013-11-21
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多