gpt4 book ai didi

perl - 指示一个类是否在 Perl 中实现了一个接口(interface)有多重要?

转载 作者:行者123 更新时间:2023-12-04 16:21:06 25 4
gpt4 key购买 nike

我一直在和 friend 讨论代码风格问题。我们有一系列通过命名子例程返回特定类型的值来实现接口(interface)的包。例如:

package Foo::Type::Bar;
sub generate_foo {
# about 5-100 lines of code
return stuff here;
}

所以你可以去:
my $bar_foo = Foo::Type::Bar->generate_foo;
my $baz_foo = Foo::Type::Baz->generate_foo;

我们有很多这些,都在同一个 Foo::Type::* 下等级制度。

我认为这些软件包应该清楚地表明它们实现了 foo_generate接口(interface),例如:
package Foo::Type::Bar;
use base 'Foo::Type';
sub generate_foo {
...
return stuff here;
}

我认为这是很好的代码风格,对于其他探索代码的编码人员来说更加清晰和干净。它还可以让您检查 Foo::Type::Bar->isa('Foo::Type')看它是否实现了接口(interface)(子系统的其他部分完全是OO)。

我 friend 不同意。他提出的一些论点是:
  • Foo::Type::*包被明确命名,并且只在内部项目中使用,因此毫无疑问给定包是否实现了接口(interface)
  • 这些包通常很小并且是独立子系统的一部分,在他看来它们就像批处理文件或 conf 文件,而不是繁重的 Perl OO 代码
  • Perl 通过继承表达实现,这可能很复杂或有问题,特别是当一个人得到多重继承时
  • 添加 Foo::Type父类(super class)不添加任何值,因为它实际上是一个空包,仅用于启用 ->isa查找
  • 以编程方式指示接口(interface)实现是个人代码风格的问题

  • 我们中的一个或另一个“正确”吗?你会怎么办?

    编辑:在示例中,将 Foo::Generator 重命名为 Foo::Type

    最佳答案

    好吧,还有其他动态语言使用的“鸭子打字”。 UNIVERSAL::can达到了其他语言倾向于使用它的程度。

    $unknown->doodle() if $unknown->can( 'doodle' );

    “鸭子”打字的名称来自“如果它像鸭子一样走路,像鸭子一样说话......它就是鸭子”的想法。然而,我们并没有看到它是否“像鸭子一样”走路,我们只是在看它是否会做一些有人称之为“走路”的事情,因为这也是我们所说的鸭子所做的事情。例如,Tree Walker 对象不会像鸭子一样“行走”!

    您不想传递错误的对象某些东西。
    $path_or_OS_I_dont_know_which->format( "c:", 'y' );

    所以鸭式打字的效果取决于你对另一边的期望。另外,如果契约(Contract)更复杂,它往往会变得困惑。你只是增加了不确定性——尽管通过绝对不可能的引擎盖来缩小对象,两个类会意外地有 23 个类似命名的方法。
    if ( $duck->can( 'talk' ) && $duck->can( 'walk' )) { 
    $duck->walk();
    $duck->talk();
    }

    没关系,但是
    if ( $cand->can( 'walk' ) && $cand->can( 'talk' ) && ... && $cand->can( 'gargle' )) {
    ...
    }

    有点傻。另外,其中一些方法可能真的是可选的,所以你必须穿插它:
    $cand->snicker() if $cand->can( 'snicker' );

    (当然,路口会稍微清理一下。)

    而且它可能会变得非常复杂,因为您必须将方法的中间产品传递给也可能存在的其他方法。

    兼容的

    我有一个轻量级的模式,我称之为“兼容”。没有实际的包叫做这个,但是如果一个类实现了 Date然后它把它放在 @ISA ;
    our @ISA = qw<... Date::Compatible ...>;

    因此只有两个 isa需要调用的 s——我将它封装在 is_one 中子,无论如何:
    sub UNIVERSAL::is_one { 
    my ( $self, @args ) = @_;
    foreach my $pkg ( @args ) {
    return 1 if $self->isa( $pkg );
    }
    return 0;
    }

    sub UNIVERSAL::is_compatible_with {
    my ( $self, $class ) = @_;
    return $self->is_one( $class, "${class}::Compatible" );
    }

    它至少为事物提供了一个要履行的契约(Contract),并为查询代码提供了测试依据。如果不挑剔,实现仍然可以决定履行契约(Contract)的特定方法的重要性。

    关于perl - 指示一个类是否在 Perl 中实现了一个接口(interface)有多重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/310105/

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