我遇到了应用程序架构中的障碍。我刚刚开始使用访问者模式在运行时我不知道的抽象对象上执行特定的算法。我的问题是我的算法也取决于嵌套抽象类型的类型。
让我来说明我的意思:
我有一个抽象的 DataSource 类。从此我实现了具体的 DataSourceReference 和 DataSourceExplicit 类。我还有一个抽象的 Report 类(反序列化的元数据),我从中实现了具体的 Report 类 ReportTypeA 和 ReportTypeB。创建这些对象时,它们的 DataSource 可以是任何扩展的 DataSource 类。
我需要实际的 Report 类型和 DataSource 类型,以便我可以相应地执行。我可以使用访问者模式获取 Concerte Report 类型,但不知道之后/也不知道如何对 DataSource 执行相同的操作。
访问报告后我无法访问数据源,因为我会丢失报告的具体类型(因为您必须让它接受基本报告类型:Accept(SomeDataSourceVisitor d, MetaReport m) - 或重载每种可能的报告类型,这违背了访问者模式的目的。看到我的问题了吗?
有任何想法吗?我想远离使用动态,因为它不需要新报告类型的开发人员来确保调度员(访问者)支持新报告。
当前代码:
public abstract class DataSource
{
}
public class DataSourceReference : DataSource
{
// reference thing(s)
}
public class DataSourceExplicit : DataSource
{
// explicit thing(s)
}
public abstract class Report
{
// some shared Report attribute(s)
// ...
public DataSource DataSource { get; set; }
public abstract FinalReport Execute(IReportExecutionDispatcher d);
}
public class ReportA : Report
{
// ReportA specific attribute(s)
// ...
public override Execute(IReportExecutionDispatcher d)
{
d.ExecuteReport(this);
}
}
public class ReportB : Report
{
// ReportB specific attribute(s)
// ...
public override Execute(IReportExecutionDispatcher d)
{
d.ExecuteReport(this);
}
}
public interface IReportExecutionDispatcher
{
FinalReport ExecuteReport(ReportA);
FinalReport ExecuteReport(ReportB);
}
最佳答案
在搜索互联网时也发现了这一点。将其张贴在这里以供将来引用和讨论。
Selective Visitor Pattern
Use the Selective Visitor pattern when
- you're using a programming language that supports multiple classification (and ideally method overloading).
- you want to perform different kinds of operations on the (potentially disparate kinds of) elements in an object structure.
- you want to avoid contaminating the element classes with operations that do not relate to their essential responsibilities.
- you want to be able to easily add new kinds of elements to the structure without compromising their existing designs.
关于architecture - (嵌套?)多次调度【访客模式】,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9342435/