(Вложенный?) Множественная отправка [Шаблон посетителя]

Я столкнулся с препятствием в архитектуре моего приложения. Я только начал использовать шаблон посетителя для выполнения определенных алгоритмов для абстрактных объектов, тип которых я не знаю во время выполнения. Моя проблема в том, что мой алгоритм также зависит от типа вложенного абстрактного типа.

Позвольте мне проиллюстрировать, что я имею в виду:

У меня есть абстрактный класс DataSource. Исходя из этого, я реализую конкретные классы DataSourceReference и DataSourceExplicit. У меня также есть абстрактный класс Report (десериализованные метаданные), из которого я реализую конкретные классы Report ReportTypeA и ReportTypeB. Когда эти объекты созданы, их DataSource может быть любым расширяющимся классом DataSource.

Мне нужны и , и фактический тип отчета, и тип источника данных, чтобы я мог выполнять соответствующие действия. Я могу получить отчет о концерте, используя шаблон посетителя, но не знаю, как сделать то же самое для DataSource впоследствии / также .

Я не могу посетить 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);
}
5
задан svick 20 February 2012 в 01:45
поделиться