[英]Subtype polymorphism without adding dependencies to derived classes
Suppose I have a tree structure with nodes all deriving from abstract class FruitNode
. 假设我有一个树形结构,其节点都派生自抽象类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();
}
All derived classes contain a method with which some additional fields on the derived class are set. 所有派生类都包含一种方法,通过该方法可以设置派生类上的一些其他字段。 These private fields are required to compute the magical fruit value. 这些私有字段是计算神奇水果价值所必需的。
For instance, a Banana
derived class may look like this. 例如, 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());
}
}
And an Orange
derived class. 还有一个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());
}
}
The FruitNode
tree is first set as a "skeleton", with none of the additional information on each node being set. 首先将FruitNode
树设置为“骨架”,而没有设置每个节点上的任何附加信息。
At some later stage in the program, I need to set the additional data on each node in the FruitNode
tree. 在程序的稍后阶段,我需要在FruitNode
树的每个节点上设置其他数据。 All of the additional data for the fruit nodes stems from the same object of type Economy
. 水果节点的所有其他数据都来自同一类型的Economy
对象。
The current solution is to loop over all of the nodes in the tree structure, and implement a switch
on what the FruitType
of the node is. 当前的解决方案是循环遍历树结构中的所有节点,并对节点的FruitType
进行switch
。 The node is then cast to its corresponding derived class. 然后将该节点强制转换为其相应的派生类。
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
}
}
}
But this is ugly . 但这是丑陋的 。 To me, this looks like a great use case for subtype polymorphism. 在我看来,这似乎是子类型多态性的一个很好的用例。 I could add a 我可以添加一个
public abstract void SetAdditionalData(Economy economy);
to the abstract base FruitType
class, and then delegate the logic to each derived class itself to proceed with whatever calculations it needs from the Economy
. 到抽象的FruitType
类基类,然后将逻辑委托给每个派生类本身,以进行从Economy
所需的任何计算。
However , Economy
is an external dependency from the FruitType
tree classes, and I am not permitted to have the FruitType
classes become dependent on the Economy
class, which they evidently would become if I proceeded with the abstract method approach. 但是 , Economy
是FruitType
树类的外部依赖关系,不允许我让FruitType
类依赖于Economy
类,如果我继续使用抽象方法方法,它们显然会变得如此。
My question is , is there another way in which you can emulate polymorphic subtyping without adding a dependency in the subclasses on the parameters of the method in question? 我的问题是 ,还有另一种方法可以模拟多态子类型, 而无需在子类中添加对所讨论方法的参数的依赖性吗?
My apologies for the possibly contrived example (I'm not very strong with OOP), if anything is unclear please do let me know and I will clarify accordingly. 我为可能是人为的例子(我对OOP不太强)道歉,如果有任何不清楚的地方,请告诉我,我将作相应说明。
Implement an interface called IFruitNode
which all fruit nodes implement. 实现一个名为IFruitNode
的接口,所有水果节点都实现该接口。 One of its methods would be SetAdditionalFruitTreeData
. 其方法之一是SetAdditionalFruitTreeData
。 Your example Tree<FruitNode>
would then be Tree<IFruitNode>
and thus your existing SetAdditionalFruitTreeData
would just loop all node and call the IFruitNode.SetAdditionalFruitTreeData()
method. 然后,您的示例Tree<FruitNode>
将是Tree<IFruitNode>
,因此您现有的SetAdditionalFruitTreeData
只会循环所有节点并调用IFruitNode.SetAdditionalFruitTreeData()
方法。 The FruitTree
class would then have no dependency on the implementors of IFruitNode
. 然后, FruitTree
类将不依赖于IFruitNode
的实现者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.