帮助我更好地编写此方案。假设我有一个名为“car”的基类,并且派生了两个 名为“法拉利”和“雪佛兰”的班级。现在我有一个名为“ParkingLot”的新类,它应该知道它正在操作的汽车,自定义批量和其他属性。
现在回到问题所在。我正在开发的当前代码库非常成熟,它完全用Perl OOPS编写。 “ParkingLot”构造函数将始终与car对象(在此之前实例化)作为参数传递。代码(Parking Lot)使用这个参数,在对象指针上做一个ref来查找该类是否是“法拉利”/“雪佛兰”,并根据汽车类型进行一些非常具体的操作。这个例子,我想说的是一个“冰山一角”,这些代码在整个代码中遍布各处,使其更难以维护。
Tommorow,如果我想要添加一辆新车,我的停车场应该支持,那么通过代码检查参考并手动进行更改将成为一场噩梦。你会做些什么来重新编写代码以使其更优雅和可维护?
答案 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代码。故意省略了许多细节。)