Composite design pattern: how to pass results from one component into another?

前端 未结 1 528
终归单人心
终归单人心 2021-01-21 13:22

I have the following code:

interface IService
{
    void Execute();
}

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

class ServiceB : IService         


        
1条回答
  •  不思量自难忘°
    2021-01-21 13:49

    If ServiceB needs ServiceA's result for it to function properly then why not have ServiceB depending on 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; }
    }
    

    Then in the case that you execute all Services in a collection you can add a ServiceBase to make sure this service executes only once: (Full example)

    On this basic implementation you can add: Async Execute, Thread-safe checking of the executing of InnerExecute, Flyweight factory for the generation of the specific IService, Have a ResponseBase with derived responses for each 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; }
    }
    

    And whoever uses these Services:

    public enum ServicesTypes 
    {
        ServiceA,
        ServiceB....
    }
    
    public interface IServiceFactory
    {
        IEnumerable GetServices();
    
        IService GetServices(ServicesTypes servicesTypes);
    }
    
    public class SomeOtherThatExecuteServices
    {
        public SomeOtherThatExecuteServices(IServiceFactory serviceFactory)
        {
            ServiceFactory = serviceFactory;
        }
    
        public IEnumerable ExecuteServices()
        {
            return ServiceFactory.GetServices()
                                 .Select(service => service.Execute());
        }
    
        public IServiceFactory ServiceFactory { get; set; }
    }
    

    Probably you will want to access the factory by some mapping key and probably you will want proper logic in the SomeOtherThatExecuteServices but all this will put you on the right way (+Using some proper IoC Container)

    0 讨论(0)
提交回复
热议问题