子类型多态性,而不向派生类添加依赖项
本文关键字:派生 添加 依赖 类型 多态性 | 更新日期: 2023-09-27 18:02:32
Setup
假设我有一个树结构,其节点都派生自抽象类FruitNode
。
public abstract class FruitNode : Tree<FruitNode>
{
public double NodeId { get; private set; }
public FruitType Type { get; private set; }
protected FruitNode(double nodeId, FruitType fruitType)
{
NodeId = nodeId;
Type = fruitType;
}
public abstract double GetMagicalFruitValue();
}
所有派生类都包含一个方法,用于设置派生类上的一些附加字段。这些私人字段是计算神奇水果价值所必需的。
例如,Banana
派生类可能如下所示。
public class Banana : FruitNode
{
private List<double> _bananaSecretValues;
public Banana(double id) : base(id, FruitType.Banana) {}
public void SetAdditionalBananaData2(List<double> computedBananaValues)
{
_bananaSecretValues = computedBananaValues;
}
public override double GetMagicalFruitValue()
{
return Math.Exp(_bananaSecretValues.Sum());
}
}
以及一个Orange
派生类。
public class Orange : FruitNode
{
private List<double> _orangeSecretValueList1;
private List<double> _orangeSecretValueList2;
public Orange(double id) : base(id, FruitType.Orange) {}
public void SetAdditionalOrangeData(List<double>
computedList1Values, List<double> computedList2Values)
{
_orangeSecretValueList1 = computedList1Values;
_orangeSecretValueList2 = computedList2Values;
}
public override double GetMagicalFruitValue()
{
return Math.Cos(_orangeSecretValueList1.Zip(_orangeSecretValueList2,
(one, two) => one - two).Average());
}
}
问题
FruitNode
树首先设置为"骨架",没有设置每个节点上的附加信息。
在程序的稍后阶段,我需要在FruitNode
树中的每个节点上设置其他数据。水果节点的所有其他数据都来自类型 Economy
的同一对象。
当前的解决方案是遍历树结构中的所有节点,并实现对节点FruitType
是什么的switch
。然后将节点强制转换为其相应的派生类。
public void SetAdditionalFruitTreeData(IEnumerable<FruitNode> nodesInFruitTree, Economy economy)
{
foreach (var node in nodesInFruitTree)
{
switch (node.Type)
{
case FruitType.Banana:
{
List<double> computedBananaValues = new List<double>();
// do some manipulations with the economy to add values to
// the computed banana values
// cast the node to the derived type Banana, and call
// the SetAdditionalBananaData class
break;
}
case FruitType.Orange:
{
List<double> computedBananaValues = new List<double>();
// do some manipulations with the economy to add values to
// the computed banana values
// cast the node to the derived type Orange, and call
// the SetAdditionalOrangeData
break;
}
// continued for other fruit types
}
}
}
但这很丑陋。对我来说,这看起来像是亚型多态性的一个很好的用例。我可以添加一个
public abstract void SetAdditionalData(Economy economy);
到抽象基FruitType
类,然后将逻辑委托给每个派生类本身,以继续从Economy
进行所需的任何计算。
但是,Economy
是来自FruitType
树类的外部依赖关系,我不允许FruitType
类依赖于Economy
类,如果我继续使用抽象方法方法,它们显然会成为。
我的问题是,有没有另一种方法可以模拟多态子类型,而无需在子类中添加对所讨论方法参数的依赖关系?
<小时 />对于可能人为的例子,我深表歉意(我对 OOP 不是很强烈(,如果有任何不清楚的地方,请告诉我,我会相应地澄清。
实现一个名为 IFruitNode
的接口,所有水果节点都实现该接口。它的方法之一是 SetAdditionalFruitTreeData
.然后,您的示例Tree<FruitNode>
将被Tree<IFruitNode>
,因此您现有的SetAdditionalFruitTreeData
将只循环所有节点并调用IFruitNode.SetAdditionalFruitTreeData()
方法。然后,FruitTree
类将不依赖于IFruitNode
的实现者。