Подпрограммы для вызова другой подпрограммы


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

my $stats = analyze_model_vectors( $reference_vector, $prediction_vector );
print_result( $stats, $tolerance );

В print_result подпрограммы просто называет более конкретные методы.

sub print_result
{
  if($outformat eq "text")
  {
    print_result_text(@_);
  }
  elsif($outformat eq "xml")
  {
    print_result_xml(@_);
  }
  else
  {
    # Should not reach this far if input checking is done correctly
    printf(STDERR "Error: unsupported output format '%s'\n", $outformat);
  }
}

Это хорошая практика? Какие еще альтернативы существуют и каковы их плюсы/минусы? Я могу придумать следующие варианты.

  • Тест для формата в самом центре алгоритм, и вызвать соответствующую подпрограмму печати есть.
  • Я никогда не использовал подпрограмму ссылки раньше, но, возможно, когда я мог оставить ссылку на правильный подпрограммы в скалярной переменной и вызвать метод print с этого скаляра в центре алгоритм.
  • Поместить код для всех форматов в одном подпрограммы, разделенных если/elsif операторы/другой отчетности.

Имейте в виду, там может быть больше выходных форматов, необходимых в ближайшем будущем.



601
13
задан 20 января 2011 в 08:01 Источник Поделиться
Комментарии
2 ответа

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

sub print_result
{
my $subroutine = shift;
&$subroutine( @_ );
}

print_result( \&print_result_text, $arg1, $arg2 )

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

sub print_result
{
my %print_hash = ( text => \&print_result_text,
xml => \&print_result_xml );

if( exists( $print_hash{ $outformat } ) )
{
&{$print_hash{ $outformat }}( @_ );
}
else
{
printf(STDERR "Error: unsupported output format '%s'\n", $outformat);
}
}

15
ответ дан 20 января 2011 в 10:01 Источник Поделиться

Я стараюсь избегать Perl, если я могу, так это более общий ответ: я закодирован, как это в старое приложение в VB6. Каждая функция выхода имеет функцию-оболочку, которая тогда называлась требует реализации с помощью серии МФС. Иногда тот или иной метод вывода не нужно ничего - ЭГ. "Начни с новой строки" актуален для текста выходного файла, но не изощряются выходного листа.

Я сейчас в процессе портирование/переписывание, что конкретное приложение на C#/.Сеть 4, где мне удалось взять гораздо более объектно-ориентированный подход.
У меня определили "выход базового класса" с стандартному интерфейсу. Это потом наследуется различных реализаций. Как я начала выход, я могу создать необходимый выполнения, используя метод фабрики класса, и передавать данные через стандартный интерфейс.

Эта конкретная реализация будет на самом деле многопоточная, поэтому основную часть выходного базовый класс-это на самом деле поток & управления очередью. Данные передаются с помощью небольшой "кусок данных" классе, и в очереди на выход через потокобезопасную очередь.

4
ответ дан 20 января 2011 в 08:01 Источник Поделиться