Как сделать самый чистый код при сообщении пользователю о прогрессе? - PullRequest
11 голосов
/ 18 ноября 2008

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

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.

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

РЕДАКТИРОВАТЬ :: Я ищу больше информации об архитектурной информации, а не о конкретной реализации. Код указан очень упрощенно.

Ответы [ 13 ]

9 голосов
/ 18 ноября 2008

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

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

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);
3 голосов
/ 18 ноября 2008

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

3 голосов
/ 18 ноября 2008

Не могли бы вы, возможно, использовать Аспектно-ориентированное программирование и разработать Progress Aspect?

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

2 голосов
/ 18 ноября 2008

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

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

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

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

1 голос
/ 18 ноября 2008

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

1 голос
/ 18 ноября 2008

Довольно простым и понятным способом было бы создать абстрактный класс с 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() для целого ряда других задач. Это может быть легко рекурсивно, поскольку любая задача может затем запустить несколько подзадач.

1 голос
/ 18 ноября 2008

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

1 голос
/ 18 ноября 2008

Если предположить, что вы делаете следующее:

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

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

Просто идея.

1 голос
/ 18 ноября 2008

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

0 голосов
/ 18 ноября 2008

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

Вы можете сделать то же самое с вашей задачей. Вы можете просто определить класс задачи с помощью фабрики, которая создает объект с помощью фабрики объектов Enterprise Library и автоматически добавлять в задачу сообщения «До» и «После». Это дало бы ТОЧНО то, что вы хотите, с изяществом, которое требуется.

Веселись!

...