代码之家  ›  专栏  ›  技术社区  ›  rajachan

如何从Perl中的具体类继承?

  •  2
  • rajachan  · 技术社区  · 16 年前

    我们的软件将每个设备表示为一个具体的类。假设我有一个班级叫 Cpu-Version-1 ,它派生自一个名为 Device . 现在,CPU供应商想发布这个CPU的经济版本( Cpu-Version-2 Cpu版本1 Cpu版本2 与的相同 Cpu版本1 ,但剩余的10%代码不再相同。i、 e.这些是在中删除的特性 Cpu版本2 所以我不应该再代表它了。

    那么设计这个类的最佳方法是什么呢?我可以继承 从 Cpu版本1 (即使继承是不完美的,因为这两个设备是对等的)。这将迫使我重写cpu-version-1的许多方法而不做任何事情(这看起来很难看,而且感觉不太对劲)。而且我不认为我可以改变基类( Cpu版本1 或者它的基础),因为代码已经在生产中,需要大量的批准和论证。如果你是我,你会怎么做这个设计决定?

    我们怎么做 Cpu版本2 Cpu版本1

    4 回复  |  直到 16 年前
        1
  •  4
  •   friedo    16 年前

    我认为阻碍面向对象编程项目进展的一个主要绊脚石是一个常见的误解,即继承是关键 只有

    与 Moose roles 用它们“做”的事情的组合来组合类,而不必创建复杂的(在本例中是不合适的)继承层次结构。

    如果你不想要像驼鹿这样笨重的东西,还有更简单的选择,比如 mixin .

    你可能感兴趣的另一个选择是基于原型的合成,比如 Class::Prototyped

        2
  •  3
  •   daotoad    16 年前

    和 .

    CPU1 is a CPU
    CPU1 has a Frobnicator
    CPU1 has a Thingummy
    CPU1 has a Poddlewhick
    CPU1 has a Fridgemagnet
    

    其中Frobnicator、thingumy和Poddlewhick都是在CPU对象上操作的类。

    CPU2 is a CPU
    CPU2 has a Frobnicator
    CPU2 has a Thingummy
    CPU2 has a Poddlewhick
    

    CPU2和CPU1一样,但没有冰箱。

    package CPU;
    
    sub delegate {
        my $self     = shift;
        my $accessor = shift;
        my $method   = shift;
    
        return $self->$accessor->$method( $self, @_ );
    }
    
    package CPU1;
    
    use Frobnicator;
    use Thingummy;
    use Poddlewhick;
    use Fridgemagnet;
    
    
    package CPU2;
    
    use Frobnicator;    
    use Thingummy;
    use Poddlewhick;
    
    
    package Frobnicator;
    
    use Exporter;
    our @ISA = /Exporter/;
    
    our @EXPORT_OK = qw( frobnicate );
    our @EXPORT = @EXPORT_OK;
    
    sub frobnicate {
        my $delegator = shift;
    
        return $delegator->delegate( frobnicator => frob => @_ );
    }
    

    这种方法会导致大量重复的代码。您可以通过以下方式创建一些伪角色类型代码注入 import 使用 use 声明。但是如果你需要这么做,就用Moose而不是重新实现它。

    只有当你不能仅仅用驼鹿来扮演角色的时候,你才能这么做。他们工作得更好,少了麻烦和陈词滥调。

        3
  •  2
  •   Madison Caldwell    16 年前

    你有几个选择。不过,我不认为让CPU-Version-2从CPU-Version-1派生出来就是答案。

    然而,更好的方法可能是使用组合。在CPU-Version-2对象中保留一个CPU-Version-1实例。对于任何常见方法,您的CPU-Version-2对象都可以简单地委托给CPU-Version-1中的等效方法。您可以使用CPU-Version-2自己的方法来增强这种行为,以满足需求。

    例如(伪代码):

    class CPU-Version-2:
       CPU-Version-1 cpu;
    
       int commonMethod1():
          return cpu.method1();
    
       void commonMethod2():
          cpu.doSomething();
    
       int newMethod():
          x = cpu.getSomeValue();
          y = x + 42;
          return y;
    

        4
  •  1
  •   brian d foy    16 年前

    或者,既然你说你不能改变基类(所以,走不可重用和不可维护的路线),你就可以把这些东西混进去 Cpu-Version-2 . 如果你继承了 Cpu-Version-1

     package CPU::V2;
     use parent qw( CPU::V1 );
    
     sub dont_need_this_feature { return }
    

    没有看到实际的课程和你做了什么,我只能给你一个很好的猜测。