我正在编写一个符号数学库。我有一个界面
interface IDifferentiable {
string Name;
Expression<IDifferentiable> Differentiate(Variable v);
}
具体类
class Variable : IDifferentiable {
}
这两个结构相互依赖,并且还有第三个泛型类,它基本上是一个简单的树,用于表示这两个类所依赖的表达式。
我的根本问题是:这种循环依赖是一件坏事吗?有人告诉我,这种事永远不应该发生,并被认为是一种“设计味道”。似乎没有办法将它们分成不同的组件。从根本上讲,让它们相互依赖是有意义的,因为
Differentiate
方法特别需要 Variable
并且无法使用不同的 IDifferentiable
。同样,Variable
类需要实现IDifferentiable
,否则我将不得不重新考虑程序的整个结构,这是我最满意的组件之一。
我实际上只考虑了一种解决方案:更改接口方法以采用
IDifferentiable
而不是Variable
。目前,微分方法不依赖于 Variable
中不存在的任何组件,因此这不会立即造成问题。我知道接口引用自身也是一种常见的做法。然而,我这样做感到不舒服,因为 IDifferentiable
专门需要 Differentiate
是有意义的。这是一个有效的问题吗?是否有不需要重新设计整个项目的解决方案?我仍处于早期阶段,这就是为什么我如此担心这一点,因为我打算在未来扩展功能。以这种方式做事,但在依赖项中存在任何类型的循环通常会令人困惑。 在这种情况下,您可以通过添加
Variable
实现的中间
IVariable
接口来解决循环问题,并在 Variable
方法定义中引用该接口:Differentiate
这不会在您的依赖树中引入任何循环,但我承认为此拉出一个接口有点奇怪。如果您担心依赖循环,那么这是解决它的一种方法。
它的一个优点是您可以拥有满足接口规范的不同类,例如实现
interface IVariable
{
string Name { get; }
object Value { get; }
}
interface IDifferentiable
{
string Name { get; }
Expression<IDifferentiable> Differentiate(IVariable variable);
}
class Variable : IVariable, IDifferentiable
{
public string Name { get; }
public object Value { get; }
public Variable(string name, object value)
{
Name = name;
Value = value;
}
public IDifferentiable Differentiate(IVariable other)
{
// compute differentiation (whatever that is) here.
throw new NotImplementedException();
}
}
但不实现
IVariable
的类型,反之亦然。