我有以下代码:

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的某些结果。我的想法是创建用于存储结果的容器类,然后将其注入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的结果才能正常运行,那么为什么ServiceB取决于ServiceA

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的执行的线程安全检查,用于生成特定IService的Flyweight工厂,具有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; }
}


谁使用这些Service

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容器)

10-05 19:38