0

我正在使用六边形架构,我想知道访问者模式会如何尊重它?

被访问对象是域对象,但访问者旨在将所述域对象实现动态分派到域对象和数据传输对象之间的适当映射器。

我的第一个想法是将访问者的抽象暴露到域中,并将其实际实现留在基础架构中,类似于存储库。

它不是将基础设施暴露到域中吗?访问者模式是实现细节,对吧?它没有带来任何商业价值,所以它不属于域,不是吗?但是我需要在我的业务对象中使用接受方法来实现这种模式。

你对此有什么想法?

编辑代码示例(C# 语法,但没什么花哨的):

namespace Domain
{
    public interface IFlow
    {
        void Accept(IFlowVisitor visitor);
    }

    public class Cashflow : IFlow
    {
        void Accept(IFlowVisitor visitor)
        {
            visitor.Visit(this);
        }

        // some properties
    }

    public class Assetflow : IFlow
    {
        void Accept(IFlowVisitor visitor)
        {
            visitor.Visit(this);
        }

        // some properties
    }

    public interface IFlowVisitor
    {
        void Visit(Assetflow flow);
        void Visit(Cashflow flow);
    }
}

namespace Infra
{
    public class FlowVisitor : IFlowVisitor
    {
        public FlowVisitor(ICashflowMapper cashflowMapper, IAssetflowMapper assetflowMapper, IDao dao)
        {
            CashflowMapper = cashflowMapper;
            AssetflowMapper = assetflowMapper;
            Dao = dao;
        }

        private readonly ICashflowMapper CashflowMapper {get; set;}
        private readonly IAssetflowMapper AssetflowMapper {get; set;}
        private readonly IDao Dao {get; set;}

        public void Visit(Assetflow flow)
        {
            Assetflow assetflowDto = AssetflowMapper.Map(flow);
            dao.Persist(assetflowDto);
        }

        public void Visit(Cashflow flow)
        {
            CashflowDto cashflowDto = CashflowMapper.Map(flow);
            dao.Persist(cashflowDto);
        }
    }

    public interface ICashflowMapper
    {
        CashflowDto Map(Cashflow domainObject);
    }

    public interface IAssetflowMapper
    {
        AssetflowDto Map(Assetflow domainObject);
    }

    public interface IDao
    {
        void Persist(CashflowDto dto);
        void Persist(AssetflowDto dto);
    }

    public class cashflowDto 
    {
        // property bag
    }
    public class assetflowDto
    {
        // property bag
    }

    public class Test
    {
        public void TestMethod()
        {
            ICashflowMapper cashflowMapper = new CashflowMapper();
            IAssetflowMapper assetflowMapper = new AssetflowMapper();
            IDao dao = new Dao();
            IFlowVisitor visitor = new FlowVisitor(cashflowMapper, assetflowMapper, dao)
            List<IFlow> flows = new List<IFlow> { new Assetflow(), new Cashflow(), new Assetflow() };

            foreach(var flow in flows)
            {
                flow.Accept(visitor);
            }
        }
    }
}
4

1 回答 1

0

确实,这种特定的访问者模式实现涉及到对领域的轻微污染,但务实往往比纯粹主义者要好。如果这将是您选择的语言最实用的解决方案,或者您最终会得到更复杂的技术实现,那么利大于弊,就这样吧。

幸运的是,C# 支持使用dynamic关键字进行动态分派,这使您不必Accept在域对象上使用方法。

例如

public class FlowVisitor {

    public void Visit(IFlow flow) {
        Visit((dynamic) flow);
    }

    // Specific visit methods (private)...
}
于 2019-02-03T16:01:09.197 回答