gpt4 book ai didi

perl - 在 AnyEvent 下编写良好的面向对象代码

转载 作者:行者123 更新时间:2023-12-01 21:43:58 24 4
gpt4 key购买 nike

我们正在构建一个具有复杂逻辑的大型应用程序,它由模块组成。我曾经用更简单的方法构建更大规模的方法,例如,

# 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() 等。但这也不能让我满意(它是不可维护的,而且想到好名字而不是 stageXX 让我头疼)。

我们已经在研究一个成熟的状态机来驱动整个应用程序,但必须为每个交互添加转换对我来说有点过于慷慨。

所以问题是:编写实现业务逻辑(图 1)以在 AnyEvent 应用程序(图 3)中运行的模块的最佳实践是什么?

最佳答案

执行摘要:您要么需要控制反转(Coro 阻塞的线程),要么需要状态机。

您可以使用 Coro,它可以将无限梯形图转换为线性代码(通过控制反转),例如使用 Coro::rouse_cb/rouse_wait 或某些 Coro::AnyEvent 函数:

   do_sth cb => sub { ...

变为(如果回调仅调用一次):

   do_sth cb => Coro::rouse_cb;
my @res = Coro::rouse_wait;

您唯一的其他选择是使用状态机,例如使用对象(有很多方法可以实现状态机,特别是在 Perl 中):

my $state = new MyObject;

do_something callback => sub { $state->first_step_done };

在first_step完成中,您为$self->next_state_done等注册回调。

您还可以查看一些 cpan 模块,例如 AnyEvent::Blackboard 或 AnyEvent::Tools - 我自己没有使用过它们,但也许它们可以帮助您。

对于 condvars,我个人不太热衷于将它们用作 API 的唯一手段 - 我更喜欢回调(因为 condvars 是有效的回调,这允许两者),但 condvars 确实允许您在消费者中引发异常(通过croak方法)。

关于perl - 在 AnyEvent 下编写良好的面向对象代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11046361/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com