Perl是多态的值得吗?

时间:2014-06-27 20:18:14

标签: perl oop polymorphism

在Perl中似乎有很多方法可以做多态,但是他们都觉得" hacky"对我来说。我对Perl有点新意,所以我可能只是错误地解释它,但我发现大多数例子都会让你的代码难以理解并且引起争议。

假设您有一个窗口小部件类,其中包含所有窗口小部件所需的一些数据和方法。还有一些小部件类型(即日历,日程安排等)。他们需要彼此沟通(通过父容器类)。

使用命名空间并使小部件成为原型值得吗? 我应该在实例化时为每个小部件提供对象(其中一种类型)的引用吗? 只是忘记作为对象的类型,并使widget成为一个大类,其中每个实例只根据设置的类型使用几个方法。 还有别的吗?

我来自C / C ++背景,我发现很难决定使用Perl编程模型。

另外,我没有强大的类型安全或私人会员要求。该项目是一个中等规模的网络应用程序,有几个开发人员和其他项目的可移植性不是一个优先事项。不需要破译Perl黑客就可以轻松扩展,但是很有用。

1 个答案:

答案 0 :(得分:5)

“现代Perl”方法可能将Widget定义为角色。可以认为角色类似于mixin,接口或抽象基类。使用Moose::Role或其中一个更轻量级的选项(Moo::RoleRole::Tiny)执行此操作。

{
   package Widget;
   use Moo::Role;

   sub some_common_method {
      my $self = shift;
      ...;
   }

   sub another_common_method {
      my $self = shift;
      ...;
   }

   # Here we're indicating that all Widgets must
   # have a method called yet_another_common_method,
   # but we're not defining how that method should
   # be implemented.
   requires "yet_another_common_method";
}

现在您可以创建一个组成该角色的类:

{
   package Calendar;
   use Moo;
   with "Widget";

   # Here's a member variable.
   has year => (is => "ro", required => 1);

   # Widget requires us to implement this.
   sub yet_another_common_method {
      my $self = shift;
      ...;
   }

   # We can override Widget's implementation
   # of this method.
   sub some_common_method {
      my $self = shift;
      ...;
   }

   # We can install hooks ("method modifiers")
   # to Widget's methods.
   before another_common_method => sub {
      my $self = shift;
      print STDERR "Calendar ", $self->year, ": another_common_method() was called.\n";
   };
}

另一个:

{
   package Schedule;
   use Moo;
   with "Widget", "Editable";

   sub yet_another_common_method {
      my $self = shift;
      ...;
   }
}

并使用类:

my $calendar = Calendar->new( year => 2014 );
my $schedule = Schedule->new;

my @widgets = ($calendar, $schedule);

for (@widgets) {
   $_->some_common_method if $_->does('Widget');
}