Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/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# 如何构造一个包含大量IF语句的程序(proces)_C#_Design Patterns - Fatal编程技术网

C# 如何构造一个包含大量IF语句的程序(proces)

C# 如何构造一个包含大量IF语句的程序(proces),c#,design-patterns,C#,Design Patterns,我必须为一种复杂的过程创建一个程序。 这个过程并不复杂,但有很多变量控制着这个过程。 我不能详细讲述这个过程,所以我编了一个,它有相同的IF负载: 过程是:我们是否应该停止铁熔炉。 我们得到了这些参数: 如果温度超过800摄氏度,停止它 除此之外,当我们预计在接下来的20分钟内2号烤箱将提供冷水时,我们可以继续 除此之外,当温度在接下来的10分钟内上升10度时,我们不能再等10分钟来喝冷水,所以我们必须停下来 除此之外,当温度因某种原因下降到790-800度并持续5分钟时,我们需要额外的冷却水的

我必须为一种复杂的过程创建一个程序。 这个过程并不复杂,但有很多变量控制着这个过程。 我不能详细讲述这个过程,所以我编了一个,它有相同的IF负载:

过程是:我们是否应该停止铁熔炉。 我们得到了这些参数: 如果温度超过800摄氏度,停止它 除此之外,当我们预计在接下来的20分钟内2号烤箱将提供冷水时,我们可以继续

除此之外,当温度在接下来的10分钟内上升10度时,我们不能再等10分钟来喝冷水,所以我们必须停下来

除此之外,当温度因某种原因下降到790-800度并持续5分钟时,我们需要额外的冷却水的时间增加了5分钟

除此之外,当温度因某种原因下降到780-790度并持续5分钟时,我们需要额外的冷却水的时间增加了5分钟

等等等等

除了“如果”和“那么”,你们都能想到另外20个

在我们的过程中,我们有超过50种情况,都是为了一个目标:机器是否应该停止

我必须说,对于一个目标/问题,我通常没有那么多的情况(即:是否停止机器),这也是有时间限制的:如果这种情况持续10分钟,那么……我们必须每分钟再次计算一次情况

有没有一种聪明的编程方法


(还有单元测试,因为我们有负载和组合负载,我想它们都是独立的单元测试?

不是根据您对烤箱工作原理的了解手动确定所有必须停止烤箱的情况,而是让计算机为您执行此操作

尝试为烤箱的工作方式编程一个模型,在每个时间点,您都可以对未来10分钟左右的情况进行模拟。如果模拟显示很快会出现严重问题,则您可以立即停止烤箱,否则让它运行一分钟,读取输入并再次运行模拟

编写一个精确的模型需要一些努力,但随着您的需求发生轻微变化(例如,您的over已升级或修复),更新模型将相对容易-在最佳情况下,您只需修改模型参数或更新单个公式

按照目前的方法,如果您稍微修改烤箱,您必须首先手动计算将产生的效果,然后逐行检查所有代码以更新不同的条件



关于单元测试-理想情况下,您应该在各种情况下使用真实烤箱中的数据测试您的模型,并检查您的模拟是否预测了实际测量结果(允许存在一些读取不准确的公差)。如果这是不可能的,那么您可以硬编码一些示例场景和预期结果(例如过热),并测试模拟是否正确预测结果。

一些问题空间不适合OOP原则。听起来,在基于规则的范例中,您的情况可以得到更好的管理(特别是当规则发生变化时)。
下面是一个基于规则的.NET框架示例:

+1 bump MrDosu关于规则引擎的回答。像WF规则引擎这样的简单规则引擎可能足以满足您的需要。只要您使用.NET 3.0+,就可以通过编程方式使用它,而无需使用工作流

编辑:单元测试这应该很容易,但要创建所有要测试的场景却很费劲。作为输入发送到规则引擎的数据(类)是场景的当前状态。创建许多状态或场景,并在单元测试中将它们发送到规则引擎。或者,您可以在单个单元测试中一个接一个地组合多个状态,以测试逻辑进程

EDIT2:使用WF规则集的一些源代码

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.ServiceModel.Description;  
using System.Xml.Schema;  
using System.Workflow.Activities.Rules;  
using System.Workflow.ComponentModel.Serialization;  

namespace ServiceMediation.Behaviors  
{  
    public class TransformingMessageServiceBehavior : IServiceBehavior  
    {  
        private string _ruleSetPath = null;  
        private RuleSet _ruleSet = null;  

        public TransformingMessageServiceBehavior(string ruleSet)
        {
            if (!string.IsNullOrWhiteSpace(ruleSet))
            {
                _ruleSetPath = ruleSet;
                WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
                XmlTextReader reader = new XmlTextReader(_ruleSetPath);
                RuleDefinitions rules = serializer.Deserialize(reader) 
                    as RuleDefinitions;
                _ruleSet = rules.RuleSets[0];
            }
        }
...
然后像

RuleValidation validation = new RuleValidation(typeof(EvaluationData), null);
RuleExecution exec = new RuleExecution(validation, data);  
_ruleSet.Execute(exec);  

使用
EvaluationData
=您作为输入提供的数据。这些规则是为此数据键入的。它还可以作为输出结果,检查对数据属性执行规则集的结果。

您对问题的推理方式与状态机非常相似


因此,更多的是关于建模状态以及在每个状态中可以做些什么。提到WF是为了不同的用途(实际上是它的规则集),但我会更多地关注基于状态的工作流,因为在这里,您可以关注这些状态中的每一个,以及如何在它们之间进行转换。

找到一个库,为您的流程提供实现,并将其建模为fsm。stackoverflow上有许多关于fsms的问题:.

是“除外”对象还是它的意思与英语一样?因为我看到像“停止它,除非”,“继续除非”和“除非,当温度……”这样的词。沃德康:我想他只是忘记了几个句号。像平常的英语一样,读它像“做a,除非这是真的,然后做b,除非c做某事10分钟,然后做c等等。我想我的[进入]不要出现:)我在房间里多放了几张票text@Michel从您发布的示例来看,更多的是关于许多特殊条件,而不是关于“许多变量”。在你试图解决的实际问题中,也许你有超过50种情况,但只有<10个变量?+1,但这将是一个严重的策略变化,如果他们已经开始编写代码,可能太晚了。这个答案正在我的脑海中沉入,如何建立这样一个系统model@Michel:你需要对烤箱的工作原理有一些了解。如果当前温度为400摄氏度,并将其设置为500摄氏度,则温度不会立即改变。如果你能找到一个描述温度变化率的公式,你可以用它来预测1分钟、2分钟等时间内的温度。如果你不知道这个公式,你可以查看一些实际数据,找到一个拟合良好的公式,