关于继承和运算符重载的OOP设计问题

时间:2011-02-16 17:13:35

标签: c# oop design-patterns

对于数学包,我正在尝试为不同类型的矩阵提供类,例如典型的矩形矩阵,三角矩阵,对角矩阵等。原因很自然地是节省了有效存储和特殊矩阵的高效算法实现。但是我仍然希望具有重载运算符的灵活性,其中C = A + B将A和B作为任何类型的矩阵并返回相应的结果(如果其中一个操作数是矩形的,则结果可以降级为典型的矩形矩阵)

我想到了两个可能的想法,这两个想法都很混乱:

(1)一个IMatrix接口,它列出了需要为每种类型的矩阵实现的所有方法,例如转置,反转等,其有效实现对于每种类型的矩阵是不同的。这里有两个问题:(a)运算符重载是静态方法,因此不能在接口中列出,甚至不能在实现接口的基类中列出。运算符重载必须分别写在每个类中,我不可能实现C = A + B类型的操作(如上所述),没有在客户端代码中进行混乱的类型检查和转换,我真的想避免。 (b)当我定义运算符重载时,我不能将两个操作数都作为接口:即,我不能在DiagonalMatrix类中执行以下操作:

public override IMatrix operator +(IMAtrix lhsMatrix, IMatrix rhsMatrix)
{ ... }

(2)可以有一个矩阵类,矩阵类型变量存储在类中(可以是枚举)。根据类型,我们可以实现数据结构和算法。然后,操作员重载将无缝地工作。这里有一个问题:(a)在启动特定算法之前,类可能会有很大的可能用于检查矩阵类型的switch-case语法。对于每个二元运算符,我必须有n ^ 2个case,n是我想要实现的矩阵类型的数量。可能也是维护的噩梦。

看起来,如果没有运算符重载细节,我可以使用Factory patternVisitor pattern,但不能使用op重载。什么是解决这个问题的最佳方法?

到目前为止我找到的资源:

  1. 这里有一个related thread
  2. Explanation of a similar problem面对另一个OS C#Numerics包的开发。
  3. 编辑:

    2011年4月25日:到目前为止,我已经找到了有关此问题的更多资源。

1 个答案:

答案 0 :(得分:7)

如果这是我的项目,我会使用#1的变体:定义一个抽象的Matrix类,它由更具体的类型(如TriangularMatrix)继承。这将允许您创建运算符(即使所述运算符只是抛出NotImplementedException),然后您可以在派生类中重写它们。它还允许您使用该常用功能集处理任何矩阵作为矩阵。

你唯一丢失的是编译器检查你实际上是否覆盖了方法和运算符;由于运算符是静态的,因此不能使它们变得抽象。如果您愿意,可以通过使基类中的运算符只调用可在基类中抽象的等效命名方法(例如,+将调用Add方法)来解决此问题,从而强制子类实现它。

数学问题:可以将三角矩阵添加到矩形矩阵中,还是两个加数必须在类型和/或尺寸上匹配?如果是前者,请考虑在基类Matrix中实现运算符,并让该运算符实现策略模式,调用可以对每种类型组合执行实际操作的内部类。如果是后者,只需覆盖该类型矩阵的有效运算符的基类实现。