我有一个对象,它基于它的属性,将在它的服务层执行不同的操作。
假设它是一个具有以下状态的客户: Registered、RegisteredWithoutContactOnFile和NoRegistration。
这些状态基于对象上设置的属性。因此,它将类似于以下内容:
public class Customer
{
public Registration Registration {get; set;}
public string Email {get; set;}
public int Id {get; set;}
}然后是CustomerService,它根据输入的内容执行不同的数据库操作,如下所示:
public class CustomerService
{
public void RegisterCustomer(Customer customer)
{
if (customer.Registration != null && customer.Id == 0) //Registered without contact -- insert a new contact into the database
else if (customer.Registration == null && customer.Id == 0) // No registration/contact -- insert both a registration and contact into the database
else if (customer.Registration != null && customer.Id > 0) //Registered and contact on file -- update contact and registration information in the database
}我基本上想摆脱服务层中的if/else语句,并使其成为我对象中的状态,这样我就可以更容易地测试它。有没有人可以帮我解决这个问题,或者如果我做错了?我会说我对状态模式很感兴趣,因为我一直在为AI代理开发有限状态机,但我觉得它在这里也是有意义的。也许一种策略模式会起作用?简而言之,我只是试图从服务层中提取逻辑,使其更具可测试性……任何有见地的人都会非常感谢!
发布于 2020-10-03 00:58:37
在没有转换和新状态的情况下,您不能拥有状态机。这看起来更像是验证检查。它可以使用模式匹配和switch语句来实现,例如:
switch (customer.Registrarion,customer.Id)
{
case (null,0):
//No Registration, contact:
break;
case (Registration r,0):
//Registered without contact
break;
case (Registration r, _):
//Registered with contact
break;
defaut:
throw new InvalidOperationException("Invalid state!");
}可以使用带切换表达式的模式匹配来实现状态机,如this example from the docs:
var newState = (state, operation, key.IsValid) switch
{
(State.Opened, Operation.Close, _) => State.Closed,
(State.Opened, Operation.Open, _) => throw new Exception(
"Can't open an opened door"),
(State.Opened, Operation.Lock, true) => State.Locked,
(State.Locked, Operation.Open, true) => State.Opened,
(State.Closed, Operation.Open, false) => State.Locked,
(State.Closed, Operation.Lock, true) => State.Locked,
(State.Closed, Operation.Close, _) => throw new Exception(
"Can't close a closed door"),
_ => state
};此表达式使用原始状态、操作和参数来决定新状态
发布于 2020-10-03 00:14:42
呃..。
重构多if或嵌套if语句可以有许多不同的方式,例如,您可以使用模板模式,例如,通过州将您的客户转换为不同类型,然后拥有一个字典,核心业务逻辑成为
handlers[customer.GetType()].Handle(customer) 另一种方法是不使用if-statement,而是使用(每个状态的)具体类型,然后进行模式匹配。
另一种更有趣的方式是雇佣一个参与者来处理这件事。演员自带一个内置的自然FSM。
您可以做的是发出一条消息,您的处理参与者调用Becomes,该actor进入一种状态,该状态将只处理该状态下的消息。
https://stackoverflow.com/questions/64174849
复制相似问题