モジュールで構成される複雑なロジックを持つ大規模なアプリケーションを構築しています。私は以前、より単純なメソッドのより大規模なメソッドを構築していました。たとえば、
# fig. 1
package Foo;
sub highlevel {
my ($self, $user, $event) = @_;
my $session = $self->get_session($user);
my $result = $self->do_stuff($session, $event);
$self->save_session($session);
return $result;
};
(これはもちろん単純化されています)。結果が返され、例外がスローされ、誰もが幸せになります。
現在、AnyEvent に移行しています。私のモジュールは最上位レベルではないので、単に行うことはできません
# fig. 2
my $cv = AnyEvent->condvar;
# do stuff
return $cv->recv;
これまでに見たほとんどの AE モジュールは次のように機能します。
# fig. 3
$module->do_stuff( $input,
on_success => sub { ... },
on_error => sub { ... }
);
だから私は下位レベルのメソッドを書き直して、highlevel() を進めようとしました...
# fig. 4
package Foo;
sub highlevel {
my ($self, $user, $event, %callbacks) = @_;
my $done = $callbacks{on_success};
my $error = $callbacks{on_error};
$self->get_session( $user,
on_error => $error,
on_success => sub {
my $session = shift;
$self->do_stuff( $session, $event,
on_error => $error,
on_success => sub {
my $result = shift;
$self->save_session( $session,
or_error => $error,
on_success => sub { $done->($result); }
);
}
);
}
);
};
正確には美しくありません。私はそれを「無限のはしご」と呼んでいます。
次に思いついたのは、highlevel() が _highlevel_stage1()、_highlevel_stage2() などに分割されたアドホック ステート マシンでした。ステージXXの代わりに名前を付けると頭痛がします)。
私たちはすでにアプリ全体を駆動する本格的なステート マシンを検討していますが、すべてのインタラクションにトランジションを追加する必要があるのは、私には少し寛大すぎるように思えます。
質問は、AnyEvent アプリ (図 3) 内で実行するビジネス ロジック (図 1) を実装するモジュールを作成するためのベスト プラクティスは何ですか?