Как написать элегантный Perl-код без ссылки - PullRequest
1 голос
/ 16 ноября 2010

Помогите мне лучше написать этот сценарий. Допустим, у меня есть базовый класс с именем "автомобиль", и два производных классы под названием "Ferrari" и "Chevrolet". Теперь у меня есть новый класс с именем «ParkingLot», который должен знать, на какой машине он работает, чтобы настроить размер партии и другие атрибуты.

Теперь вернемся к проблеме. Текущая кодовая база, над которой я работаю, очень зрелая, и она полностью написана на Perl OOPS. Конструктор "ParkingLot" всегда будет передаваться с объектом car (созданным за много лет до этого) в качестве аргумента. Код (Parking Lot) использует этот аргумент, делает ссылку на указатель объекта, чтобы определить, является ли класс "Ferrari" / "Chevrolet", и выполняет некоторые очень специфические операции в зависимости от типа автомобиля. Этот пример, я бы сказал, является «верхушкой айсберга», и такого рода код замусорен повсюду по всему коду, делая его более неуправляемым.

Завтра, если я захочу добавить новую машину, которую должна поддерживать моя стоянка, тогда станет кошмаром проверять ссылки по всему коду и вносить изменения вручную. Что бы вы сделали, чтобы переработать код, чтобы сделать его более элегантным и обслуживаемым?

Ответы [ 2 ]

6 голосов
/ 16 ноября 2010

Предположительно ParkingLot различает типы автомобилей по какой-то причине - например, вероятность кражи может отличаться между двумя.Для каждого различия, которое делает ParkingLot, постарайтесь выяснить, на каком свойстве автомобиля (или его отсутствии) это различие основано, и придать автомобилю или его подклассам эти свойства вместо того, чтобы выбирать на основании класса.измерьте, передайте Chevrolet свойство «Я - Шеви», а Ferrari - свойство «Я - Феррари» и протестируйте его.

4 голосов
/ 16 ноября 2010

В качестве первого комментария к вопросу, о котором вы говорите, вам нужен полиморфизм. Пусть автомобиль решает, как должен вести себя автомобиль, а не заставляет парковку отслеживать поведение каждого типа автомобиля. например, вместо этого:

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. Многие детали были намеренно опущены.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...