gpt4 book ai didi

Perl 面向对象编程 : Is it a good idea to outsource methods in your own modules

转载 作者:行者123 更新时间:2023-12-02 02:07:02 24 4
gpt4 key购买 nike

我正在考虑将模块的各个方法移动到单独的模块中,以获得更易于管理的文件。我为此写了一个小测试:

a.pl:

#!/usr/bin/perl

use 5.028;
use warnings;
use utf8;
use open ':std', ':encoding(UTF-8)';
use Readonly;
use English qw(-no_match_vars);
use Benchmark qw(:all);
use A;


our $VERSION = 1;

Readonly::Scalar my $COUNT => 10_000_000;

warn $A::VERSION;
warn $A::Login2::VERSION;
my $a = A->new;
warn $a;
$a->login(1);
$a->login2(1);

cmpthese($COUNT, {
login => sub{$a->login},
login2 => sub{$a->login2}
});

下午:

package A;
use 5.028;
use warnings;
use utf8;
use open ':std', ':encoding(UTF-8)';
use Readonly;
use English qw(-no_match_vars);
use A::Login2 'login2';


our $VERSION = 1;

sub new {
my ($class, $p) = @_;
my $this = {};
bless $this, $class;
return $this;
}

sub login {
my ($this, $dump) = @_;

if ($dump) {
warn "$this: login";
$this->test;
}

return;
}

sub test {
my ($this) = @_;
warn "$this: test";
return;
}

1;

A/Login2.pm:

package A::Login2;
use 5.028;
use warnings;
use utf8;
use open ':std', ':encoding(UTF-8)';
use Readonly;
use English qw(-no_match_vars);
use base 'Exporter';
our @EXPORT_OK = qw(login2);


our $VERSION = 1.1;

sub login2 {
my ($this, $dump) = @_;

if ($dump) {
warn "$this: login2";
$this->test;
}

return;
}

1;

./a.pl 的输出是:

1 at ./a.pl line 18.
1.1 at ./a.pl line 19.
A=HASH(0x5581d48f3470) at ./a.pl line 21.
A=HASH(0x5581d48f3470): login at A.pm line 25.
A=HASH(0x5581d48f3470): test at A.pm line 34.
A=HASH(0x5581d48f3470): login2 at A/Login2.pm line 18.
A=HASH(0x5581d48f3470): test at A.pm line 34.
Rate login login2
login 5847953/s -- -6%
login2 6250000/s 7% --

我本以为登录比登录2更快。

  1. 为什么login2比login更快?
  2. 将每个方法放在自己的模块中是一个好主意吗?
    1. 有更好的方法吗?

我期待您的评论。

最佳答案

这是一个关于设计的开放式问题,但我会提供一些具体的评论。

首先,为了便于管理和提高可读性而分割笨重的文件是一个值得称赞的想法,这通常是一个好主意。我们在编写的任何大型代码中使用库——因此,整个代码被分割在不同的单元中。

但这种划分是基于功能的,行为(功能)自然地分组到包中。根据大小进行分割可能会导致代码库变得尴尬;组合起来可能很重要,更新可能会变得棘手(有错误?)等等。这实际上会阻碍整体的可管理性。

如果一个模块感觉太大,很可能是捆绑在一起的功能太多,并且代码库应该位于多个不同模块中。没有简单的规则来评估这一点;设计库并不容易。思考一下拆分一组函数以便它们拥有自己的功能是否有意义可能会有所帮助 namespace

但是,发布的示例有另一个问题:它是一个类,但面向对象的机制与基本包导入混合在一起。这是很复杂的(一个对象如何/为什么传递给一个不是类的文件中定义的函数?),我不建议这样做。

设计良好的类是否会太大而无法很好地放入文件中?大概是我猜的吧,虽然我没见过这样的案例。通常,当一个代码库最终在 Perl 中的多个编译单元中崩溃时,这是因为功能性——拥有多个类更合适。

但是,如果不知何故,仅仅是大小问题最终成为问题,那么合理的方法可能是让多个文件各自为同一个,并清楚地记录下来。

A.pm

package A;

use warnings;
use strict;
use feature 'say';

# =======================================================
# NOTE: Class definition is given in multiple parts/files
# =======================================================

use A_part1;
use A_part2;

sub new { ... }

# perhaps more methods in this file
1;

A_part1.pm

package A;

# warnings, strict, pragmas, etc

sub func1 { my ($self, @args) = @_; ... };

...

1;

对于A_part2.pm等也类似。然后照常使用

use A;

my $obj = A->new( ... );

$obj->func1(...);

请注意,这打破了有关文件名和包名称之间关系的规则(约定)(A_part1.pm vs package A;);首先,PerlCritic 会提示。但是,这里是故意这样做的,我不会担心这一点。

但我认为实际上很少需要这样做。我宁愿期望,如果一个库看起来太大,它可能承担了太多的任务,应该重新设计为多个类。


但是,如果确实有太多属于同一个库的函数,一旦文件被分解,请考虑使用 require 将这些文件放在一起.

Perl::Critic::Policy::Modules::RequireFilenameMatchesPackage

关于Perl 面向对象编程 : Is it a good idea to outsource methods in your own modules,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68297780/

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