smi*_*ith 9 perl design-patterns perl-module perl-data-structures
我想构建一堆Perl子程序,它们都具有相同的模板if elsif elsif else,可以根据因子变量做出决定.这是子程序模板的一个例子:
sub get_age{
my $factor=shift;
if ($factor == 1 ){ print "do something" }
elsif ($factor == 2 ){ print "do somthing2" }
elsif ($factor == 3 ){ print "do somthing3" }
elsif ($factor == 4 ){ print "do somthing4" }
else { print "error" }
}
Run Code Online (Sandbox Code Playgroud)
我想知道在Perl上是否有一些设计模式if else用更优雅的解决方案替换条件,如果我需要更改某些条件或删除其中某些条件,将来是否容易维护?
bri*_*foy 10
有几个人提到了调度表.有两件事,有时让它们分开是件好事.有可能发生的事情列表,以及使它们发生的事情.如果你把两者结合起来,你就会坚持使用你的解决方案.如果将它们分开,以后会有更大的灵活性.
dispatch表将行为指定为数据而不是程序结构.这有两种不同的方法.在你的例子中,你有整数和类似的东西可能使用数组来存储东西.哈希示例是相同的想法,但略微不同地查找行为.
还要注意我的因素print.当您重复这样的代码时,尝试将重复的内容移动到一个级别.
use v5.10;
foreach my $factor ( map { int rand 5 } 0 .. 9 ) {
say get_age_array( $factor );
}
my @animals = qw( cat dog bird frog );
foreach my $factor ( map { $animals[ rand @animals ] } 0 .. 9 ) {
say get_age_hash( $factor );
}
sub get_age_array {
my $factor = shift;
state $dispatch = [
sub { 'Nothing!' }, # index 0
sub { "Calling 1" },
sub { 1 + 1 },
sub { "Called 3" },
sub { time },
];
return unless int $factor <= $#$dispatch;
$dispatch->[$factor]->();
}
sub get_age_hash {
my $factor = shift;
state $dispatch = {
'cat' => sub { "Called cat" },
'dog' => sub { "Calling 1" },
'bird' => sub { "Calling 2, with extra" },
};
return unless exists $dispatch->{$factor};
$dispatch->{$factor}->();
}
Run Code Online (Sandbox Code Playgroud)
更新:请务必阅读以下brian的评论; 基本上,由于他在链接中评论的各种问题,最好使用for而不是given.我已经更新了我的建议以结合他的改进,他在Use for(而不是given()中概述了它:
如果您使用的是perl 5.10或更高版本,given/when那么您正在寻找神奇的对,但您确实应该使用它for/when.这是一个例子:
use strict;
use warnings;
use feature qw(switch say);
print 'Enter your grade: ';
chomp( my $grade = <> );
for ($grade) {
when ('A') { say 'Well done!' }
when ('B') { say 'Try harder!' }
when ('C') { say 'You need help!!!' }
default { say 'You are just making it up!' }
}
Run Code Online (Sandbox Code Playgroud)