Как сделать самый чистый код при представлении отчета пользователю?

Я боролся за последние пару месяцев, чтобы придумать чистый код, чтобы сообщить о прогрессе для пользователя. Кажется, что все всегда сводится к:

ReportProgress("Starting Task 1");
doTask1();
ReportProgress("Task 1 is done");

ReportProgress("Starting Task 2");
doTask2();
ReportProgress("Task 2 is done");

//etc... where report progress does some form of output to the user.

Хороший кодер во мне кричит: "Там должен быть более чистый путь!" Но я в тупике. Любые мысли?

EDIT:: Я больше ищу информацию о архитектурной информации, а не конкретную реализацию. Приведенный код very упрощен.

Ответ 1

настроить свои задачи как поток событий и обработать отчет об обработке событий "двигатель". Каждый экземпляр события может иметь свое имя, отчет о расписании выполнения/шаблон и т.д., Если вы хотите зайти так далеко

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

EventQueue tasks = new EventQueue();
tasks.Add(new TaskEvent(this.doTask1,"Foo-ing the bar"));
tasks.Add(new TaskEvent(this.doTask2,"Bar-ing the foo"));
tasks.Add(new TaskEvent(this.doTask3,"Glitching and whinging"));
...
tasks.Execute(this.ProgressEventHandler);

Ответ 2

Не могли бы вы использовать Aspect Oriented Programming и разработать аспект прогресса?

Существует несколько реализаций AOP. В мире Java 2 наиболее распространенными являются AspectJ и Spring (который использует аспекты AspectJ или Proxy).

Ответ 3

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

Ответ 4

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

Все это будет в конфигурации spring: Конфигурация xml будет снабжать объект задачи своим именем и параметрами. затем добавьте эти задачи в коллекцию и передайте эту коллекцию задачатору.

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

Я не согласен с тем, что здесь следует использовать АОП. излишество.

Ответ 5

Было бы естественно иметь отчет внутри вызовов doTask().
Как правило, репортер был бы единственным, что все объекты, посланные сообщениям, и класс репортера были бы неприемлемы для принятия решения о том, где и где его показывать: строка состояния, файл журнала, stderr и т.д.

Ответ 6

Предположим, что шаблон в том, что вы делаете:

  • Запуск задачи журнала
  • выполнить задачу
  • завершение задачи журнала

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

Просто идея.

Ответ 7

Я бы не стал вручную указывать числовые части отображаемых сообщений (в любое время, когда вам нужно добавлять или удалять действия или изменять последовательность, в которой вы столкнулись с проблемой вырезания и вставки). Вы хотите, чтобы какой-либо объект обрабатывал метод ReportProgress, чтобы автоматически увеличивать себя, когда он идет.

Ответ 8

Простым и понятным способом было бы создать абстрактный класс, который имеет методы do() и абстрактные методы doTask() и getName():

do() {
    ReportProgress("Starting " + this.getName());
    doTask();
    ReportProgress("Finished " + this.getName());
}

Затем в ваших задачах:

class Task1 extends Task {
    getName(){return "Task 1";}
    doTask() {
        //do stuff here
    }
}

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

Ответ 9

+1 по предложению АОП. Это классическая перекрестная озабоченность, что АОП будет решать элегантно.

Ответ 10

Вы можете вызвать ReportProgress из методов doTask, что может заставить его выглядеть немного чище, вместо этого вы просто имеете:

doTask1();
doTask2();

Отчетность будет обрабатываться внутри этих методов.

Вы можете использовать AOP, но мой мозг кричит KISS!! (Keep It Simple Stupid) в этом случае. Если это просто простое представление о чем-то более сложном, с которым вы имеете дело, AOP может быть вариантом.

Ответ 11

К сожалению, я думаю, что лучший способ сделать это зависит от деталей - по крайней мере, какого языка вы используете. Например, в python вы можете использовать контекстный менеджер, чтобы разрешить писать код следующим образом:

with progress_report("Task 1"):
    do_task_1()

Это может, например, гарантировать, что "Задача 1 выполнена", даже если do_task_1() вызывает исключение. Если бы вы захотели, вы могли бы обрабатывать исключения отдельно и печатать что-то другое, например "Не удалось выполнить задачу 1" или "Задача 1 прервана".

Ответ 12

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

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

Ответ 13

Если вы используете .NET, я бы предложил использовать блок приложений внедрения политики из Enterprise Library (минимальная версия: 3.1). Я использовал подобный материал, чтобы сделать "Вернуть идентификатор пула приложений" для веб-сайта, который был тяжелым для олицетворения.

Вы можете сделать то же самое с вашей задачей. Вы можете просто определить класс задачи с factory, который строит объект с объектом Enterprise Library factory и автоматически добавляет к заданию сообщение "До" и "После". Это точно задало бы то, что вы хотите, с требуемой элегантностью.

Удачи!