Vector和Matrix类的接口?

时间:2012-04-22 15:57:46

标签: c# design-patterns interface matrix

我有一个通用的Vector<T>类和一个通用的Matrix<T>类,我想知道让这两个类实现一个接口是不是一个好主意。

基本上,我正在实现两种算法:AlgorithmA和AlgorithmB,它们都执行非常相似的操作(重置,平均等等),但使用不同的算法并对不同的结构起作用: AlgorithmA使用Vector<double>AlgorithmB使用Matrix<Complex>

到目前为止我的设计:

abstract class AlgorithmArray
{
   // Operator overloading
}

class AlgorithmAArray : AlgorithmArray
{
    private Vector<double> _vector;

    // Overrides
}

class  AlgorithmBArray : AlgorithmArray
{
     private Matrix<Complex> _matrix;

     // Overrides
}

我希望从AlgorithmAArray派生Vector<T>并实现接口“IAlgorithmArray”(而不是抽象类)。无论如何,这些算法然后用于模拟两个位置之间的传输/接收:

public class CommunicationParameters
{
         private AlgorithmArray _transmission;
         private AlgorithmArray _receiving;

         public void Compute()
        {
            if(_transmission != null)
                 _transmission.Compute();

            if(_receiving != null)         
                 _receiving.Compute()

        }
}

有没有更好的方法来解决我的问题?

注意:基类AlgorithmArray重复了许多操作符/克隆...等方法,我觉得这可以避免,也许使用泛型?

谢谢!

2 个答案:

答案 0 :(得分:1)

我建议制作两个算法类,它们可以将任何数据结构作为参数并完成它们的工作。我不认为需要所有这些OOP继承,它只会增加复杂性。

答案 1 :(得分:1)

接口将允许仅读取或仅写入向量/矩阵的例程接受预期向量/矩阵类型的子类型或超类型的向量/矩阵。我不确定这对于矩阵通常是否有用,但它对于某些矢量应用可能很方便。

类的接口的另一个优点可能是更适用于您的情况,它们可以允许可变,不可变和写时复制对象之间的平滑互操作(后者需要额外的间接级别)。如果你有许多矢量或矩阵将是彼此的副本,这可能是有用的,但其中一些将最终得到修改。方法AsImmutableAsNewMutableAsPossiblyExistingMutable对此非常有用。第一种方法(如果在可变对象上调用)将创建一个新的不可变对象,其内容与调用时的主题相匹配,或者(如果在不可变对象上调用),只返回其主题。第二个将创建一个新的可变对象,无论现有对象是可变的还是不可变的。如果可变,第三种方法将返回其主题,或者创建一个新的可变对象;它通常只应用于对象的持有者知道,如果对象是可变的,它只保留唯一的引用。

例如,如果我有_thing类型的私有字段IReadableVector<Foo>,我的设置者可以将其设置为value.AsImmutable(),我的获取者可以返回_thing.AsImmutable()。我的变异方法会在调用变异方法之前设置_thing = _thing.AsPossiblyExistingMutable()。如果我在收到它之后没有尝试变异_thing,它将是一个不可变对象(其他对象也可能包含引用)。我第一次改变它,它将被复制到一个新的可变对象。然而,后续的突变可能会继续使用相同的可变对象,因为它永远不会暴露给任何外部代码。

PS - 支持和反对IImmutableVector<T>IImmutableMatrix<T>作为接口,而不仅仅有ImmutableVector<T>ImmutableMatrix<T>类。一方面,如果它们是接口,则可以实现无需实际存储所有元素的有用实现。例如,可以有一个像AllMatchingVector<T>这样的类,它继承IImmutableVector<T>但只包含一个T和一个表示其长度的数字;它的索引getter只会返回该元素,而不管指定的索引如何,或DiagonalMatrix<T>只为其对角线的内容保留IImmutableVector<T>,而T将在其他地方返回;特别是对于大型矢量/矩阵,这样的类可以节省内存。另一方面,没有办法确保没有人使用实际上不可变的类实现其中一个接口。我个人的感觉是,使用接口是很好的。毕竟,很少有人抱怨如果一个类以不产生不可变排序关系的方式实现SortedDictionary<T>IComparable<T>将失败。尽管如此,很多人不同意这样的概念。