c# - 复合设计模式 : how to pass results from one component into another?

标签 c# design-patterns composite design-principles

我有以下代码:

interface IService
{
    void Execute();
}

class ServiceA : IService
{
    public void Execute() { ... }
}

class ServiceB : IService
{
    public void Execute() { ... }
}

class ServiceComposite : IService
{
    List<IService> _services = new List<IService>();

    public ServiceComposite()
    {
        _services.Add(new ServiceA());
        _services.Add(new ServiceB());
    }

    public void Execute()
    {
        foreach (IService service in _services)
        {
            service.Execute();
        }
    }
}

问题在于 ServiceB 依赖于 ServiceA 的某些结果。我的想法是创建用于存储结果的容器类,然后将其注入(inject)到 ServiceA 和 ServiceB 中:

class ServiceResults
{
    public string SomeProperty {get; set;}
}

public ServiceComposite()
{
    ServiceResults result = new ServiceResults();
    _services.Add(new ServiceA(result));
    _services.Add(new ServiceB(result));
}

我想知道这是否是解决问题的最佳方法。也许它违反了一些我不知道的原则或规则,或者仅仅是“代码味道”。执行此操作的更好方法是什么?

最佳答案

如果 ServiceB 需要 ServiceA 的结果才能正常运行,那么为什么不根据 ServiceA 使用 ServiceB >?

public interface IService 
{
    void Execute();
}

public class ServiceA : IService
{
    public void Execute() { ... }
}

class ServiceB : IService
{
    public ServiceB(IService service)
    {
        Service = service;
    }

    public void Execute() { ... }

    public IService Servie { get; set; }
}

然后如果您执行一个集合中的所有 Service,您可以添加一个 ServiceBase 以确保该服务只执行一次:(完整示例)

在这个基本实现上,您可以添加:异步 ExecuteInnerExecute 执行的线程安全检查、用于生成特定 的享元工厂code>IService,有一个 ResponseBase,其中包含每个 Service 的派生响应....

public class ServiceResponse { }
public interface IService
{
    ServiceResponse Execute();
}

public abstract class ServiceBase : IService
{
    public ServiceResponse Execute()
    {
        if (_response == null)
        {
            _response = InnerExecute();
        }
        return _response;
    }

    public abstract ServiceResponse InnerExecute();

    private ServiceResponse _response;
}

public class ServiceA : ServiceBase
{
    public override ServiceResponse InnerExecute()
    {
        return new ServiceResponse();
    }
}

public class ServiceB : ServiceBase
{
    public ServiceB(IServiceFactory serviceFactory)
    {
        ServiceFactory= serviceFactory;
    }

    public override ServiceResponse InnerExecute()
    {
        return ServiceFactory.GetServices(ServicesTypes.ServiceA).Execute();
    }

    public IServiceFactory ServiceFactory { get; set; }
}

无论谁使用这些服务:

public enum ServicesTypes 
{
    ServiceA,
    ServiceB....
}

public interface IServiceFactory
{
    IEnumerable<IService> GetServices();

    IService GetServices(ServicesTypes servicesTypes);
}

public class SomeOtherThatExecuteServices
{
    public SomeOtherThatExecuteServices(IServiceFactory serviceFactory)
    {
        ServiceFactory = serviceFactory;
    }

    public IEnumerable<ServiceResponse> ExecuteServices()
    {
        return ServiceFactory.GetServices()
                             .Select(service => service.Execute());
    }

    public IServiceFactory ServiceFactory { get; set; }
}

您可能希望通过一些映射键访问工厂,并且您可能希望在 SomeOtherThatExecuteServices 中有适当的逻辑,但所有这些都会让您走上正确的道路(+使用一些适当的IoC 容器)

关于c# - 复合设计模式 : how to pass results from one component into another?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38481859/

相关文章:

c# - 如何在私有(private)嵌套类中设置私有(private)字段的值?

java - Java个人项目,如何访问数据库?

gwt - 为什么在 CellTable 中没有使用 CompositeCell 的体面示例?

ruby-on-rails - 为移动和网络构建后端

swift - Swift 中的枚举模式匹配

design-patterns - 组件和复合之间具有双向关联的复合模式

java - 复合 Material 的关键听众?

c# - 使用 AspNetCoreModuleV2 使用相同的应用程序池托管多个 .net 核心

c# - 如何在连接表(Fluent NHibernate)上使用带有属性(列)的 NHibernate ManyToMany

c# - mono mcs 'Winforms Hello World' 给出编译错误 CS006 : Metadata file 'cscompmgd.dll' could not be found