[英]What creational design pattern would suit these requirements?
我有一个场景,我将数据'请求'对象传递给服务,服务本身必须根据请求中的数据创建许多不同的'处理器'。
每个处理器本身可以是许多不同类型中的一种。 例如,粗略的丑陋实现可能如下所示:
public Collection<IProcessor> UglyCreationalMethod(Request request)
{
var processors = new Collection<IProcessor>();
if(request.Type == RequestType.SomeVal)
{
if(request.Id > 1000)
{
processors.Add(new ProcessLargeRequest(request));
}
else
{
processors.Add(new ProcessSmallRequest(request));
}
}
else (request.Type == RequestType.SomeOtherVal)
{
if(request.Source == RequestSource.User)
{
processors.Add(new ProcessUserRequest(request));
}
else
{
processors.Add(new ProcessCorpRequest(request));
}
}
if(request.SomeProp == "blah")
processors.Add(new ProcessBlahRequest(request));
// ... etc ad infinitum :)
return processors;
}
我正在寻找一种可扩展的模式,并隐藏了决定服务需要创建的处理器类型的讨厌逻辑,因此它比上面的丑陋代码更清晰,更易于维护。
我知道工厂方法,但仅靠这些方法是不够的。
建议表示赞赏。
浮现在脑海中的一种模式是责任链 (也许不是创造模式)
首先,您需要RequestHandlers
public interface IRequestHandler
{
bool CanHandle(Request req);
void Handle(Request req);
}
public class LargeRequestHandler : IRequestHandler
{
public bool CanHandle(Request req)
{
return (req.Type == RequestType.SomeVal && req.id > 1000);
}
public void Handle(Request req)
{
processors.Add(new ProcessLargeRequest(request));
}
}
public class SmallRequestHandler : IRequestHandler
{
public bool CanHandle(Request req)
{
return (req.Type == RequestType.SomeVal && req.id < 1000);
}
public void Handle(Request req)
{
processors.Add(new SmallLargeRequest(request));
}
}
...同样可以根据需要为更多处理程序添加类。
然后创建这些处理程序链
public class RequestChain
{
IRequestHandler[] handlers;
public RequestChain()
{
handlers = new[] { new LargeRequestHandler(), new SmallRequestHandler() };
}
public void ProcessRequest(Request req)
{
foreach (var handler in handlers)
{
if (handler.CanHandle(req))
{
handler.Handle(req);
}
}
}
}
希望这可以帮助。 干杯。
工厂可能是正确的方法,但你需要更多的东西,即配置。
例如,您可能需要一个类似的配置文件
<processor type="typename">
<rules>
<rule type="requestIdThresholdRule">
<configuration evaluationType="ExceedsThreshold" threshold="1000"/>
</rule>
</rules>
</processor>
<processor type="othertypename">
<rules>
<rule type="yadda">
<configuration evaluationType="DoesNotMeetThreshold" threshold="1000"/>
</rule>
</rules>
这使您可以灵活地定义基于上下文的运行时评估创建的类型。 您没有一大堆代码存在于工厂方法本身,而是在一些主要由配置值驱动的规则中。 代码少得多,灵活性更高。
然后你就像这样称呼它:
List<ISomething> items = ISomethingFactory.CreateISomethingsForContext(context);
你想要做的是创建一个Factory,主要的问题是你想如何配置它。 我喜欢遵循一种方法,选择应该创建哪种方法属于Factory的职责而不是正在创建的类 - 这会带来更好的可配置性,并且更易于管理。
我会创建这样的东西:
public struct ProcessorCreationSettings
{
public Predicate<Request> Predicate;
public Func<Request, IProcessor> Creator;
}
public class ProcessorFactory
{
protected static List<ProcessorCreationSettings> settings = new List<ProcessorCreationSettings>();
static ProcessorFactory()
{
settings.Add(new ProcessorCreationSettings
{
Predicate = r => r.Type == RequestType.SomeOther && r.Id > 1000,
Creator = r => new ProcessLargeRequest(r)
});
settings.Add(new ProcessorCreationSettings
{
Predicate = r => r.Type == RequestType.SomeOther && r.Id <= 1000,
Creator = r => new ProcessSmallRequest(r)
});
}
public List<IProcessor> Create(Request request)
{
return settings
.Where(s => s.Predicate(request))
.Select(s => s.Creator(request))
.ToList();
}
}
配置部分由静态列表完成,但是如果它具有此功能,您也可以使用IoC容器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.