表示Perl中允许的状态转换图

jon*_*nny 6 perl graph data-structures

在我们的应用程序中有类似状态更改检查逻辑的内容.

目前检查由丑陋的if语句处理

我想用转换矩阵替换它:

my %allowed_status_changes = (
    1 => (2,5),     
    2 => (1,2,3,4,5),
    3 => (4,2),     
    4 => (3,2),     
    5 => (),        
);
my $is_allowed_transition = 
    $submitted_status ~~ $allowed_status_changes {$original_status};

if ($prerequestsites && !$is_allowed_transition) {
    return;
}
Run Code Online (Sandbox Code Playgroud)

某些过渡只能在附加条件下允许,因此我需要类似的东西

2 => ( 
    (target => 1)
    (target => 2, condition => $some_condition)
    (target => (3,4), condition => $other_condition), 
    (target => 5)
),
Run Code Online (Sandbox Code Playgroud)

(在我看来太长了)

如果你应该关注可读性和可维护性,你会在这种情况下使用什么结构?

您将如何解析它以检查是否允许转换?

DVK*_*DVK 2

如果条件非常普遍(例如,几乎每个允许的转换都有它们),那么后面的结构就完全没问题,除了用“()”而不是“{}”表示哈希引用的语法错误。

如果情况很少见,我建议使用#1,并通过类似于#2 的可选结构进行增强。

请注意,恕我直言,检查代码的可读性非常清晰,尽管内容庞大且不太惯用。

OTOH,矩阵的可维护性很高 - 你有来自 #1 的简洁但可读的语法,不需要任何条件,并且有一个清晰但较长的条件语法,对于每个设置的许多条件(如你的 #2)来说足够灵活。

my %allowed_status_changes = (
    1 => [2,5],
    2 => [1,5,{targets=>[2], conditions=>[$some_condition]}
             ,{targets=>[3,4], conditions=>[$other_condition, $more_cond]}]
    3 => [4,2],     
    4 => [3,2],
    5 => [],        
);

sub is_allowed_transition {
    my ($submitted_status, $original_status ) = @_;
    foreach my $alowed_status (@$allowed_status_changes{$original_status}) {
        return 1 if !ref $alowed_status && $alowed_status == $submitted_status;
        if (ref $alowed_status) {
            foreach my $target (@$alowed_status{targets}) {
                foreach my $condition (@$alowed_status{conditions}) {
                    return 1 if check_condition($submitted_status
                                              , $original_status, $condition);    
                }
            }
        }
    }
    return 0;
}

if ($prerequestsites
  && !$is_allowed_transition($submitted_status, $original_status )) {
    return;
}
Run Code Online (Sandbox Code Playgroud)