如何在没有ref的情况下编写优雅的perl代码

时间:2010-11-16 04:41:09

标签: perl oop refactoring

帮助我更好地编写此方案。假设我有一个名为“car”的基类,并且派生了两个 名为“法拉利”和“雪佛兰”的班级。现在我有一个名为“ParkingLot”的新类,它应该知道它正在操作的汽车,自定义批量和其他属性。

现在回到问题所在。我正在开发的当前代码库非常成熟,它完全用Perl OOPS编写。 “ParkingLot”构造函数将始终与car对象(在此之前实例化)作为参数传递。代码(Parking Lot)使用这个参数,在对象指针上做一个ref来查找该类是否是“法拉利”/“雪佛兰”,并根据汽车类型进行一些非常具体的操作。这个例子,我想说的是一个“冰山一角”,这些代码在整个代码中遍布各处,使其更难以维护。

Tommorow,如果我想要添加一辆新车,我的停车场应该支持,那么通过代码检查参考并手动进行更改将成为一场噩梦。你会做些什么来重新编写代码以使其更优雅和可维护?

2 个答案:

答案 0 :(得分:6)

据推测,ParkingLot出于某种原因区分了各种类型的汽车 - 例如,被盗的可能性可能因两者而异。对于ParkingLot所做的每一个区别,尝试弄清楚区别所依据的汽车属性(或缺乏此类属性),并为汽车或其子类提供这些属性,而不是基于类决定。

作为一项临时措施,请给予雪佛兰一个属于雪佛兰的房产,让法拉利成为我的法拉利房产并对其进行测试。

答案 1 :(得分:4)

正如关于这个问题的第一个评论所提到的,你想要的是多态性。让汽车决定汽车应该如何表现,而不是让停车场跟踪每种汽车的行为。例如,而不是:

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;
}

现在ParkingLot只需要知道它有一辆汽车而且汽车知道它应该如何park,所以你可以添加任意数量的新汽车子类,而无需修改ParkingLot。

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