Как я могу структурировать программу (процесс) с очень большим количеством операторов IF - PullRequest
13 голосов
/ 22 сентября 2010

Мне нужно создать программу для какого-то сложного процесса.Ну, процесс не сложный, но есть много переменных, которые контролируют процесс.Я не могу подробно рассказать о процессе, поэтому я составил один, который имеет ту же нагрузку, что и IF:

Процесс таков: мы должны остановить печь для плавки железа или нет.У нас есть эти параметры: если температура поднимается выше 800 градусов по Цельсию, остановите его, за исключением того, что, когда мы ожидаем, что в течение 2-х минут из холодной печи будет поступать холодная вода, мы можем продолжить

За исключением случаев, когдатемпература поднимается на 10 градусов в течение следующих 10 минут, мы не можем ждать еще 10 минут для холодной воды, поэтому мы должны остановиться.

За исключением случаев, когда температура по какой-то причине понижается до 790-800 градусовв течение 5 минут мы добавляем дополнительные 5 минут ко времени, когда нам нужна дополнительная холодная вода.

За исключением случаев, когда температура снижается по какой-либо причине до 780-790 градусов в течение 5 минут, мы добавляем дополнительные 5минут до времени нам нужна дополнительная холодная вода.

и т. д.и т. д.

Вы можете вспомнить еще 20, за исключением / if / then

. В нашем процессе мы имеем> 50 ситуаций, все для одной цели: остановится машина или нет.

Я должен сказать, что обычно у меня не так много ситуаций для одной цели / проблемы (а именно: остановить машину или нет), и она также ограничена по времени: если это происходит в течение 10 минут, то ...., имы должны вычислять ситуацию каждую минуту снова.

Есть ли способ запрограммировать это умным способом?

(а также модульный тест, потому что у нас есть нагрузки и нагрузки комбинаций, которыевсе отдельные модульные тесты, я думаю?)

Ответы [ 5 ]

7 голосов
/ 22 сентября 2010

Вместо того, чтобы вручную обрабатывать все ситуации, в которых вы должны остановить печь, основываясь на своих знаниях о том, как работает печь, вы можете заставить компьютер сделать это за вас.

Попробуйте запрограммировать модельо том, как работает печь, и в каждый момент времени вы можете запустить симуляцию того, что произойдет в следующие 10 минут или около того.Если симуляция показывает, что в скором времени возникнет серьезная проблема, то вы можете остановить печь сейчас, в противном случае дайте ей поработать минуту, прочитайте входные данные и запустите симуляцию снова.

Кодирование точной модели потребует некоторых усилий, но по мере того, как ваши требования изменятся незначительно (например, ваше обновление было обновлено или отремонтировано), будет относительно легко обновить модель - в лучшем случае вы просто измените параметры модели или обновите одну формулу.

Сваш текущий подход, если вы слегка изменили печь, вам придется сначала вручную рассчитать, какие эффекты это будет иметь, а затем построчно пройти весь код, обновляя различные условия.


Относительно единицы измерениятестирование - в идеале вы должны тестировать свою модель на данных из реальной печи в различных ситуациях и проверять, что ваша симуляция предсказывает фактические результаты измерений (с некоторым допуском для неточностей считывания).Если это невозможно, вы можете жестко закодировать некоторые примеры сценариев и ожидаемый результат (например, перегрев) и проверить, что симуляция правильно предсказывает результат.

6 голосов
/ 22 сентября 2010

Некоторые проблемные пространства не очень элегантно вписываются в принцип ООП. Похоже, что ваша ситуация может управляться намного лучше в парадигме, основанной на правилах (особенно, когда правила меняются). Вот пример структуры на основе правил для .NET: http://www.codeproject.com/KB/cs/Drools_NETPrimer.aspx

4 голосов
/ 22 сентября 2010

imho, то, как вы рассуждаете о проблеме, очень похоже на конечный автомат.

Так что это больше о модельных состояниях и о том, что вы можете сделать в каждом из них. WF упоминался для другого использования (на самом деле это набор правил), но я бы больше посмотрел на рабочие процессы на основе состояний, поскольку там вы можете сосредоточиться на каждом из этих состояний и на том, как вы можете переходить между ними.

2 голосов
/ 22 сентября 2010

+ 1 удар ответ 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 = данные, которые вы вводите в качестве ввода.Правила вводятся в эти данные.Он также служит выходным результатом, проверяет результат выполнения набора правил для свойства данных.

1 голос
/ 24 сентября 2010

Найдите библиотеку, которая обеспечивает реализацию для конечного автомата и смоделируйте ваш процесс как fsm. Есть несколько вопросов о fsms на stackoverflow: http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=fsm+site:stackoverflow.com.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...