假设我有3项任务:注册,评估,注册。
我希望能够让我的应用程序在这个过程中具有这三个可互换的位置。因此,对于一个设置,我可以进行注册 - >评估 - >注册。我可以将其他设置更改为注册 - >注册 - >评定。
而且我还需要能够打开/关闭某些任务功能(如注册)。
你们能告诉我从哪里开始吗?
答案 0 :(得分:2)
我会设置一个chain of responsibility。来自GoF:
通过为多个对象提供处理请求的机会,避免将请求的发送者耦合到其接收者。链接接收对象并沿链传递请求,直到对象处理它。
这是一个使用您已经提供的业务流程名称的准系统示例:
// These all should be named something relevant to your domain
public interface IHandler
{
void Handle(string request);
}
public class Handler
{
protected IHandler successor;
protected Handler(IHandler successor)
{
this.successor = successor;
}
protected virtual void Successor(string request)
{
successor?.Handle(request);
}
}
public class Registration : Handler, IHandler
{
public Registration(IHandler successor)
: base(successor) { }
public void Handle(string request)
{
Console.WriteLine($"Registration handled request {request}");
base.Successor(request);
}
}
public class Enrollment : Handler, IHandler
{
public Enrollment(IHandler successor)
: base(successor) { }
public void Handle(string request)
{
Console.WriteLine($"Enrollment handled request {request}");
base.Successor(request);
}
}
public class Assessment : Handler, IHandler
{
public Assessment(IHandler successor)
: base(successor) { }
public void Handle(string request)
{
if (request.Equals("Bob", StringComparison.InvariantCulture))
{
Console.WriteLine("Bob failed assessment.");
return;
}
Console.WriteLine($"Assessment handled request {request}");
base.Successor(request);
}
}
和示例使用:
// Consumers of this don't need to know anything more than it's an IHandler service
// Consumers of this don't need to know anything more than it's an IHandler service
IHandler noregistrationHandlers = new Assessment(new Enrollment(null));
// or Autofac
// builder.Register(c => new Assessment(c.Resolve<Enrollment>(null))).Named("NoRegistration");
// or your favorite IoC container
noregistrationHandlers.Handle("Smith");
IHandler registrationHandlers = new Registration(new Assessment(new Enrollment(null)));
// builder.Register(c => new Registration(c.Resolve<Assessment>(c.Resolve<Enrollment>(null)))).Named("Registration");
registrationHandlers.Handle("Bob");
以上是对此的讨论 - 消费代码(使用示例)除了将请求发送给处理程序的格式外,不需要知道任何内容。在示例中调用构造函数的事实仅仅是为了方便起见,例如。你很可能拥有一个依赖于IHandler
的MVC控制器,但对此却一无所知。
public class UserController
{
private readonly IHandler handler;
public UserController(IHandler handler)
{
if (handler == null) throw new NullReferenceException(nameof(handler));
this.handler = handler;
}
// ...
public ActionResult Save(string id)
{
handler(id);
}
}