Как разбить большие «макро» классы? - PullRequest
2 голосов
/ 28 ноября 2010

Одно приложение, над которым я работаю, делает только одно, глядя из внешнего мира.Принимает файл как входной файл и через ~ 5 минут выплевывает другой файл.

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

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

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

main
{
    try
    {
        result1 = Action1(inputFile);
        result2 = Action2(inputFile);
        result3 = Action3(result2.value);
        result4 = Action4(result1.value, inputFile);
        ... //You get the idea. There is no pattern passed paramteres
        resultN = ActionN(parameters);
        write output
    }
    catch
    {
        something went wrong, display the error
    }
}

Как бы вы смоделировали основную функцию этого приложения, чтобы это был не просто длинный список команд?

Ответы [ 4 ]

2 голосов
/ 28 ноября 2010

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

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

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

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

0 голосов
/ 06 декабря 2010

Прежде всего, это решение весьма неплохое. Если действия не разделены, я имею в виду, что нет глобальных параметров или других скрытых зависимостей между различными действиями или между действиями и средой, это хорошее решение. Легко поддерживать или читать, а когда вам нужно расширить функциональность, вам нужно просто добавить новые действия, когда «количество» меняется, вам нужно просто добавить или удалить строки из последовательности макросов. Если нет необходимости часто менять цепочку процессов: не двигайтесь !

Если это система, в которой реализация действий не часто изменяется, но их порядок и параметры да, вы можете разработать простой язык сценариев и преобразовать класс макросов в этот сценарий. Этот сценарий должен поддерживать кто-то, кроме вас, кто-то, кто знаком с проблемной областью на уровне ваших «действий». Таким образом, он / она может собрать приложение, используя язык сценариев, без вашей помощи.

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

Википедия (хорошая отправная точка): http://en.wikipedia.org/wiki/Dataflow_programming http://en.wikipedia.org/wiki/Flow-based_programming

Сайт JPM (книга, вики, всё): http://jpaulmorrison.com/fbp/

Я думаю, у больших систем должна быть точка разделения, которую вы описываете как "макрос". Даже игры имеют эту точку зрения, например В играх FPS есть 3D-движок и сценарий игровой логики, или есть SCUMM VM, которая одинакова.

0 голосов
/ 29 ноября 2010

Можно подумать о реализации последовательного рабочего процесса из рабочего процесса Windows

0 голосов
/ 28 ноября 2010

Не уверен, что это лучший подход, но у вас может быть объект, который будет хранить все результаты, и вы будете передавать его каждому методу по очереди. Каждый метод будет читать параметры, которые ему нужны, и записывать свой результат там. После этого вы можете получить набор действий (в виде делегатов или объектов, реализующих интерфейс) и вызывать их в цикле.

class Results
{
  public int Result1 { get; set; }
  public string Result2 { get; set; }
  …
}


var actions = new Action<Results>[] { Action1, Action2, … };

Results results = new Results();

foreach (var action in actions)
  action(results);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...