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

如何编写不带引用的优雅Perl代码

  •  1
  • rajachan  · 技术社区  · 15 年前

    帮助我更好地编写这个场景。假设我有一个名为“car”的基类,并且有两个派生的 名为“法拉利”和“雪佛兰”的课程。现在我有了一个名为“parkingglot”的新类,它应该知道它在操作什么样的汽车,来定制批量大小和其他属性。

    现在回到问题上来。IAM正在研究的当前代码库非常成熟,它完全是用PerlOOPS编写的。“parkingglot”构造函数将始终以car对象(在此之前已实例化)作为参数传递。代码(停车场)使用这个参数,在对象指针上做一个ref来查找类是否是“farrari”/“chevrolet”,并根据汽车类型做一些非常具体的操作。这个例子,我会说是一个“冰山一角”,这种代码在整个代码中到处都是,使得它更不可维护。

    Tommorow,如果我想添加一辆我的停车场应该支持的新车,那么通过代码检查所有引用并手动进行更改就变成了一场噩梦。为了使代码更优雅、更可维护,您会怎么做呢?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Dave Sherohman    15 年前

    正如对这个问题的第一条评论所暗示的,您在这里想要的是多态性。让汽车决定汽车的行为方式,而不是让停车场跟踪外面各种汽车的行为。例如,代替这个:

    package Car;
    
    package Ferrari;
    use base 'Car';
    
    package Chevrolet;
    use base 'Car';
    
    package ParkingLot;
    
    sub add_car {
      if (ref $car = 'Ferrari') {
        $self->park_ferrari;
      } elsif (ref $car = 'Chevrolet') {
        $self->park_chevrolet;
      } else {
        die "Unknown car model!";
      }
    }
    

    这样做:

    package Car;
    
    sub park {
      # park a generic Car
    }
    
    package Ferrari;
    use base 'Car';
    sub park {
      # take the Ferrari for a spin before parking it
      $self->drive_fast;
      $self->SUPER::park;
    }
    
    package Chevrolet;
    use base 'Car';
    # No sub park defined, so it just parks like a generic Car
    
    package ParkingLot;
    
    sub add_car {
      $car->park;
    }
    

    现在,停车场只需要知道它有一辆车,而且车知道它应该怎么做。 park 因此,您可以添加任意多的新车子类,而不必修改Parkinglot。

    (请注意,上面的代码是类似Perl的伪代码,不是真正的、可运行的Perl代码。许多细节被故意省略。)

        2
  •  6
  •   ysth    15 年前

    据推测,停车场区分不同类型的汽车是有原因的——例如,被盗的可能性可能在两者之间有所不同。对于Parkinglot所做的每一个区别,试着找出区别基于的汽车属性(或缺乏这种属性),并赋予汽车或其子类这些属性,而不是基于类来决定。

    作为一个临时措施,给雪佛兰一辆雪佛兰和法拉利一辆法拉利,并测试这些。