perl - OOP/程序设计问题

标签 perl oop inheritance

我们有一些第三方 Perl 库用于传输文件到/从,以及使用 PGP 加密/解密文件等等。目前,这些库使用冗余代码,并使用 system() 执行上述方法。和命令行二进制文件。

我希望重写这些库,在必要时使用更多模块和 OOP。我目前正在绞尽脑汁想如何设置主库,Perl 脚本将包括使用 Net::SFTP放置/获取文件和Crypt::PGPSimple加密/解密文件。

库模块应该用 OOP 编写吗?那有意义吗?或者是否应该根据需要导入(并按程序设计)方法,并创建 Net::SFTPCrypt::PGPSimple必要的对象?我只是不确定我想创建一个 Lib 对象,并在 new 中初始化 SFTP、PGP、常量等。子。我想我认为这种类型的类更像是一个带有静态方法的 Java 类,但应该只有一个 SFTP 对象/连接(不确定 Net::SFTP 是否已经处理了这个?)和一个 Crypt::PGPSimple , ETC。

此外,回到冗余,这个库还应该有一个父库,它定义了许多第三方库(FTP、PGP 等)使用的函数。

我不是在寻找一个明确的答案,因为可能没有一个,但也许其他人如何处理这样的设计,以及什么是最“有意义”的。

谢谢

更新:添加了我的 OOP 库模块的示例代码,该模块还利用了其他对象(PGPSimple、SFTP)。如果您能想到更好的设计/实现,请告诉我。再次感谢。

库文件

use Crypt::PGPSimple;
use Net::SFTP;
use File::Copy;
use Log::Log4perl qw(get_logger :levels);
use File::Basename;

my %CONS = (
    RECIPIENT => "ClientName";
    URL       => 'ftp.host.com';
    USER      => 'user';
    PASS      => ''; # use subroutine to obfuscate the password
    PORT      => '22'
    HOME_DIR  => '/Home';
    IN_DIR    => '/Incoming';
    OUT_DIR   => '/Outgoing';
);
my %VARS;

# private member variables
my ($logger);

BEGIN {
    %VARS = (
        IS_PROD     => $L_is_prod ? 1 : 0;
        APPS        => $ENV{'APPS'};
        OUTDIR      => $ENV{'OUTDIR'};
        TIME_ZONE   => $ENV{"TZ"};
    );

    $logger = get_logger("Lib");
}

sub new {
    my ($class, $self) = @_;

    $self = {
        pgp     => _setup_pgp();
        sftp    => undef; # Don't create SFTP connection until we need it
    };

    return bless($self, $class);
}

sub _setup_pgp {
    my $pgp = Crypt::PGPSimple->new();

    $pgp->PgpVersion(6.5.8);
    $pgp->PgpExePath("/path/to/pgp-6.5.8");
    $pgp->PgpKeyPath("/home/username/.pgp"); # Set this based on environment
    $pgp->PublicKey("pubring.pkr");
    $pgp->PrivateKey("secring.skr");
    $pgp->Password(pp());
    $pgp->UserId();
    $pgp->PgpTempDir("/tmp/");
    $pgp->PgpTimeZone();
    $pgp->PgpVerbose(2);

    return $pgp;
}

sub _setup_sftp {
    # Create SFTP connection 
    my $sftp;
    my ($host, $user, $pass);

    $host = $CONS{URL};
    $user = $CONS{USER};
    $pass = $CONS{PASS};

    $sftp = _connect_sftp($host, (user => $user, password => $pass));
    return $sftp;
}

sub encrypt {

    my ($self, $plain_file) = @_;
    my $pgp = $self->{pgp};

    $logger->info("Setting \$pgp->PlainTextFile to $plain_file");
    $pgp->PlainTextFile($plain_file);
    $pgp->PgpFlags("e");

    my $result = $pgp->EncryptFile;
    if($result != 0) {
        $logger->info("Failed to successfully encrypt $plain_file. Error code: " . $pgp->ErrCode() . ", Result: " . $pgp->Result());
    }

    return $result;
}

sub put {

    my $self = shift;
    $self->{sftp} = _setup_sftp() if(!defined $self->{sftp});
    my $local = $self->{pgp}->EncryptedTextFile();
    my $remote = basename($local);
    ...
    $sftp->put($local, $remote)
    ...

}

最佳答案

如果每个实例都需要某种状态,我倾向于使用 OO。但我认为程序方法没什么不好,不需要“状态”。

关于单一连接问题:我们(我的公司)使用“服务类”(程序),它返回一个合适的连接 - 如果使用线程/ fork 或可能有多个连接(例如使用不同的选项),这很有用.

更新:如果您决定使用 OO,我强烈建议您尽可能使用 Moose。它将为您节省大量时间、工作和错误……看看有福的引用是如何工作的,但在您的代码中使用 Moose 或 Mouse。

关于perl - OOP/程序设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7179689/

相关文章:

java - 如何从父类访问子变量?

c++11继承模板构造函数

javascript - 如何使用 Javascript 值作为 Perl 变量

multithreading - 可以使用多线程并行运行 100 个 perl 脚本吗?

java - 在Java中: How do I create a class that can be initialized and call its methods in one statement?

C#:将子类实例分配给抽象类实现的接口(interface)

perl - For 循环和词法范围的变量

perl - 为什么我不应该在 UNIVERSAL 包中创建 AUTOLOAD 子例程?

c++ - 在forever循环或void循环中执行一次(once)吗?

c++ - 为什么我的基类构造函数之一被删除? (C++11)