[英]Subtype polymorphism without adding dependencies to derived classes
假设我有一个树形结构,其节点都派生自抽象类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
的实现者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.