运行 多种算法的面向对象设计
Object oriented design for running multiple algorithms
我有一个基地 class Node
在做模拟器的繁重工作。我有一些使用相同基数 class 的不同算法,所以我从 Node
继承了 NodeA
和 NodeB
。还有另一个 class 负责视觉表示。这些节点能够 运行 并在没有视觉表示的情况下工作,因此它们位于不同的库项目中。
我做不到的是,如果你喜欢 class VisualNode
我一次只能继承 class 中的一个 运行ning 我的可视化应用程序,我实际上初始化了 VisualNode
的实例以启动作业。我想提供用户能够 select 哪个算法到 运行。
在这种情况下,正确的设计是什么?请记住虚拟妓女的方法。
以下是我的 classes:
public abstract class Node
{
protected abstract void UserDefined_ReceiveMessageProcedure ( Message m );
public virtual void VisualizeMessage ( Message m )
{
/// hooker method for visual interfaces - empty block in this class will be overriden in derived class
}
}
public class NodeA : Node
{
protected override void UserDefined_ReceiveMessageProcedure ( Message receivedMessage )
{
/// real implementation lies here
....
/// VisualizeMessage is called in here
}
}
public class NodeB : Node
{
protected override void UserDefined_ReceiveMessageProcedure ( Message receivedMessage )
{
/// real implementation lies here
....
/// VisualizeMessage is called in here
}
}
还有另一个 class 应该能够像这两种行为一样:
public class VisualNode : NodeA // NodeB
{
public Brush NodeColor { get; set; }
....
public VisualNode ( ... )
{
/// some setup
}
public bool OnIt ( Point p )
{
/// some checks
}
public void Draw ( ... )
{
/// draw it
}
public override void VisualizeMessage ( AsyncSimulator.Message m )
{
/// visualizing the message
/// this method is called via superclass
}
}
Strategy pattern 看起来很适合您的情况。它定义了一系列算法,封装了每一个算法,并使它们可以互换。策略让算法独立于使用它的客户而变化。所以这种方法将帮助你
I have some different algorithms using the same base class, So I have inherited NodeA and NodeB from Node
而不是VirtualNode
继承自NodeA
或NodeB
,让它使用NodeA或NodeB。
Perfer Composition 总是比 Inheritance 更好。你必须选择一个更有意义的。在这种情况下,组合更有意义,因为显然继承不能解决您的问题(至少很容易)。
您可以将其实现为 Decorator pattern or Strategy pattern。使用第一种方法 VirtualNode
将从 Node
继承并包装另一个 Node
。后者不继承自 Node
但使用 Node.
甚至更好,只需扔掉 VisualNode 并向 Node 注入一个 Visualizer(策略模式)。
public abstract class Node
{
public IMessageVisualizer MessageVisualizer { get; set; }
protected abstract void UserDefined_ReceiveMessageProcedure(Message m);
protected void VisualizeMessage(Message m)
{
MessageVisualizer.Visualize(m);
}
}
public interface IMessageVisualizer
{
void Visualize(Message m);
}
public class MessageVisualizer : IMessageVisualizer
{
public Brush NodeColor { get; set; }
public void Visualize(Message m)
{
/// visualizing the message
}
public bool OnIt()
{
/// some checks
}
public void Draw()
{
/// draw it
}
}
您的 NodeA 和 NodeB 保持不变。您可以将其用作
Node node = new NodeA();
node.MessageVisualizer = new MessageVisualizer();
node.DoSomethingThatMightVisualize();
当你不想可视化时,你可以像下面这样提供一个空的 MessageVisualizer 实现
public class NullVisualizer : IMessageVisualizer
{
public void Visualize(Message m)
{
//Don't visualize
}
}
Node node = new NodeA();
node.MessageVisualizer = new NullVisualizer();//don't visualize
node.DoSomethingThatMightVisualize();
现在您可以根据用户的选择创建 NodeA 或 NodeB。但可视化工具保持不变。
再次投票给策略模式。它看起来像这样,我想(我的 C# 很生疏):
public interface IVisualizeMessageStrategy
{
void VisualizeMessage(Message m);
}
public class Node
{
public IVisualizeMessageStrategy VisualizeMessageStrategy ( Message m ) { get; set; }
protected override void UserDefined_ReceiveMessageProcedure ( Message receivedMessage )
{
/// real implementation lies here
....
/// VisualizeMessage is called in here
this.VisualizeMessageStrategy.VisualizeMessage(receivedMessage);
}
}
使用方法:
Node nodeA = new Node();
nodeA.VisualizeMessageStrategy = new InstanceOfAlgorithmOneAsAClass();
Node nodeB = new Node();
nodeB.VisualizeMessageStrategy = new InstanceOfAlgorithmTwoAsAClass();
您不需要 NodeA class 或 NodeB class。您 assemble 根据您要使用的算法在运行时使用它们。
我有一个基地 class Node
在做模拟器的繁重工作。我有一些使用相同基数 class 的不同算法,所以我从 Node
继承了 NodeA
和 NodeB
。还有另一个 class 负责视觉表示。这些节点能够 运行 并在没有视觉表示的情况下工作,因此它们位于不同的库项目中。
我做不到的是,如果你喜欢 class VisualNode
我一次只能继承 class 中的一个 运行ning 我的可视化应用程序,我实际上初始化了 VisualNode
的实例以启动作业。我想提供用户能够 select 哪个算法到 运行。
在这种情况下,正确的设计是什么?请记住虚拟妓女的方法。
以下是我的 classes:
public abstract class Node
{
protected abstract void UserDefined_ReceiveMessageProcedure ( Message m );
public virtual void VisualizeMessage ( Message m )
{
/// hooker method for visual interfaces - empty block in this class will be overriden in derived class
}
}
public class NodeA : Node
{
protected override void UserDefined_ReceiveMessageProcedure ( Message receivedMessage )
{
/// real implementation lies here
....
/// VisualizeMessage is called in here
}
}
public class NodeB : Node
{
protected override void UserDefined_ReceiveMessageProcedure ( Message receivedMessage )
{
/// real implementation lies here
....
/// VisualizeMessage is called in here
}
}
还有另一个 class 应该能够像这两种行为一样:
public class VisualNode : NodeA // NodeB
{
public Brush NodeColor { get; set; }
....
public VisualNode ( ... )
{
/// some setup
}
public bool OnIt ( Point p )
{
/// some checks
}
public void Draw ( ... )
{
/// draw it
}
public override void VisualizeMessage ( AsyncSimulator.Message m )
{
/// visualizing the message
/// this method is called via superclass
}
}
Strategy pattern 看起来很适合您的情况。它定义了一系列算法,封装了每一个算法,并使它们可以互换。策略让算法独立于使用它的客户而变化。所以这种方法将帮助你
I have some different algorithms using the same base class, So I have inherited NodeA and NodeB from Node
而不是VirtualNode
继承自NodeA
或NodeB
,让它使用NodeA或NodeB。
Perfer Composition 总是比 Inheritance 更好。你必须选择一个更有意义的。在这种情况下,组合更有意义,因为显然继承不能解决您的问题(至少很容易)。
您可以将其实现为 Decorator pattern or Strategy pattern。使用第一种方法 VirtualNode
将从 Node
继承并包装另一个 Node
。后者不继承自 Node
但使用 Node.
甚至更好,只需扔掉 VisualNode 并向 Node 注入一个 Visualizer(策略模式)。
public abstract class Node
{
public IMessageVisualizer MessageVisualizer { get; set; }
protected abstract void UserDefined_ReceiveMessageProcedure(Message m);
protected void VisualizeMessage(Message m)
{
MessageVisualizer.Visualize(m);
}
}
public interface IMessageVisualizer
{
void Visualize(Message m);
}
public class MessageVisualizer : IMessageVisualizer
{
public Brush NodeColor { get; set; }
public void Visualize(Message m)
{
/// visualizing the message
}
public bool OnIt()
{
/// some checks
}
public void Draw()
{
/// draw it
}
}
您的 NodeA 和 NodeB 保持不变。您可以将其用作
Node node = new NodeA();
node.MessageVisualizer = new MessageVisualizer();
node.DoSomethingThatMightVisualize();
当你不想可视化时,你可以像下面这样提供一个空的 MessageVisualizer 实现
public class NullVisualizer : IMessageVisualizer
{
public void Visualize(Message m)
{
//Don't visualize
}
}
Node node = new NodeA();
node.MessageVisualizer = new NullVisualizer();//don't visualize
node.DoSomethingThatMightVisualize();
现在您可以根据用户的选择创建 NodeA 或 NodeB。但可视化工具保持不变。
再次投票给策略模式。它看起来像这样,我想(我的 C# 很生疏):
public interface IVisualizeMessageStrategy
{
void VisualizeMessage(Message m);
}
public class Node
{
public IVisualizeMessageStrategy VisualizeMessageStrategy ( Message m ) { get; set; }
protected override void UserDefined_ReceiveMessageProcedure ( Message receivedMessage )
{
/// real implementation lies here
....
/// VisualizeMessage is called in here
this.VisualizeMessageStrategy.VisualizeMessage(receivedMessage);
}
}
使用方法:
Node nodeA = new Node();
nodeA.VisualizeMessageStrategy = new InstanceOfAlgorithmOneAsAClass();
Node nodeB = new Node();
nodeB.VisualizeMessageStrategy = new InstanceOfAlgorithmTwoAsAClass();
您不需要 NodeA class 或 NodeB class。您 assemble 根据您要使用的算法在运行时使用它们。