我有一个通用的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
重复了许多操作符/克隆...等方法,我觉得这可以避免,也许使用泛型?
谢谢!
答案 0 :(得分:1)
我建议制作两个算法类,它们可以将任何数据结构作为参数并完成它们的工作。我不认为需要所有这些OOP继承,它只会增加复杂性。
答案 1 :(得分:1)
接口将允许仅读取或仅写入向量/矩阵的例程接受预期向量/矩阵类型的子类型或超类型的向量/矩阵。我不确定这对于矩阵通常是否有用,但它对于某些矢量应用可能很方便。
类的接口的另一个优点可能是更适用于您的情况,它们可以允许可变,不可变和写时复制对象之间的平滑互操作(后者需要额外的间接级别)。如果你有许多矢量或矩阵将是彼此的副本,这可能是有用的,但其中一些将最终得到修改。方法AsImmutable
,AsNewMutable
和AsPossiblyExistingMutable
对此非常有用。第一种方法(如果在可变对象上调用)将创建一个新的不可变对象,其内容与调用时的主题相匹配,或者(如果在不可变对象上调用),只返回其主题。第二个将创建一个新的可变对象,无论现有对象是可变的还是不可变的。如果可变,第三种方法将返回其主题,或者创建一个新的可变对象;它通常只应用于对象的持有者知道,如果对象是可变的,它只保留唯一的引用。
例如,如果我有_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>
将失败。尽管如此,很多人不同意这样的概念。