Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实现状态模式_C#_Oop_Design Patterns - Fatal编程技术网

C# 实现状态模式

C# 实现状态模式,c#,oop,design-patterns,C#,Oop,Design Patterns,我有一个基于其属性的对象,它将在其服务层中执行不同的操作 假设它是具有以下状态的客户:已注册、已注册但没有ContactOnFile和未注册 这些状态基于对象上设置的属性。因此,它将类似于以下内容: public class Customer { public Registration Registration {get; set;} public string Email {get; set;} public int Id {get; set;}

我有一个基于其属性的对象,它将在其服务层中执行不同的操作

假设它是具有以下状态的客户:已注册、已注册但没有ContactOnFile和未注册

这些状态基于对象上设置的属性。因此,它将类似于以下内容:

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语句,并使它成为我的对象中的一个状态,这样我就可以更容易地测试它。有人能帮我做这件事吗?或者如果我做得不对?我会说我对状态模式很感兴趣,因为我一直在为一个人工智能代理开发有限状态机,但我觉得它在这里也有意义。也许战略模式会奏效?简言之,我只是想让服务层的逻辑变得更加可测试。。。如有任何见解,将不胜感激

重构multi-if或嵌套if语句可以有许多不同的方式,比如您可以使用模板模式,即按状态将您的客户转换为不同的类型,然后使用[,]的字典,核心业务逻辑就变成了

handlers[customer.GetType()].Handle(customer) 
另一种方法是不使用if语句,而是使用具体类型(每个状态),然后进行模式匹配

另一个有趣的方法是雇佣一个演员来处理这个问题。演员天生就有FSM

您可以做的是发出一条消息,处理参与者调用的
变为
,进入的状态将仅处理该状态下的消息。

重构multi-if或嵌套if语句可以有许多不同的方式,比如您可以使用模板模式,即按状态将您的客户转换为不同的类型,然后使用[,]的字典,核心业务逻辑就变成了

handlers[customer.GetType()].Handle(customer) 
另一种方法是不使用if语句,而是使用具体类型(每个状态),然后进行模式匹配

另一个有趣的方法是雇佣一个演员来处理这个问题。演员天生就有FSM


您可以做的是发出一条消息,处理参与者调用的
变为
,进入的状态将仅处理该状态下的消息。

没有转换和新状态,您就无法拥有状态机。这看起来更像是验证检查。它可以通过模式匹配和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!");
}
与开关表达式的模式匹配可用于实现状态机,如:


此表达式使用原始状态、操作和参数来决定新状态

没有转换和新状态,状态机是不可能存在的。这看起来更像是验证检查。它可以通过模式匹配和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!");
}
与开关表达式的模式匹配可用于实现状态机,如:


此表达式使用原始状态、操作和参数来决定新状态

如果您有这样的状态,则必须限制或自定义设置器集。无论调用什么方法,都必须确保类的状态不变量保持不变。另外,不要为您的状态设置一个setter。使用模式匹配编写状态机是很简单的——它只是一个接受当前状态和事件并返回新状态的表达式。在这种情况下,什么是状态机?没有联系就注册是什么意思?@PanagiotisKanavos简言之,这意味着他们注册/同意接收电子邮件,但实际上从未将电子邮件存档。。。这比那要复杂一点,但这就是它的要点。@g_bor我实际上在考虑为州增加一个二传手,所以谢谢你的澄清。像GetState()这样的方法根据if/else条件返回状态有意义吗?@Dan我的意思不仅仅是要点。这是一种行动吗?要返回的值?在不知道如何处理转换的情况下,用一个例子来回答问题是不可能的。如果你有这样一种状态,你将不得不限制你的设置程序集,或者自定义它们。无论调用什么方法,都必须确保类的状态不变量保持不变。另外,不要为您的状态设置一个setter。使用模式匹配编写状态机是很简单的——它只是一个接受当前状态和事件并返回新状态的表达式。在这种情况下,什么是状态机?没有联系就注册是什么意思?@PanagiotisKanavos简言之,这意味着他们注册/同意接收电子邮件,但实际上从未将电子邮件存档。。。这比那要复杂一点,但这就是它的要点。@g_bor我实际上在考虑为州增加一个二传手,所以谢谢你的澄清。像GetState()这样的方法根据if/else条件返回状态有意义吗?@Dan我的意思不仅仅是要点。这是一种行动吗?要返回的值?如果不知道应该如何处理过渡,应该发生什么,或者不知道这些,就不可能用一个例子来回答问题。状态机可以在函数内部轻松创建。简单的
如果/else
足够好,但是很详细,动作可以作为
Action
Func
参数传递给函数,模式匹配可以将转换转换为单个表达式。当然,这就是为什么一开始我
ugh
的原因,因为这样的问题没有对错,只是你想如何写和读你的代码,你认为测试你的个人逻辑是最容易的,完全是个人的偏好,或者这些都不是。状态机可以很容易地在