Куда идут новые методы? - PullRequest
       54

Куда идут новые методы?

5 голосов
/ 15 февраля 2012

Допустим, у меня есть объект, Car, и у него есть наборы методов, которые ... несопоставимы?Может быть, как Blob-like?(как в antipattern, «blob») Эти методы работают в достаточно четких наборах и на самом деле функционально не пересекаются.

Car
# methods related to suburban driving
  ->foo1
  ->foo2
# methods related city driving
  ->bar3
  ->bar4

Теперь давайте скажем, что я хотел добавить «движение по бездорожью» как единое целоеслучаев, которые может поддержать мой автомобильный объект.Если я добавлю методы к объекту Car, разве это не сделает его более похожим на шарик?

Car (augmented)
# methods related to suburban driving
  ->foo1
  ->foo2
# methods related city driving
  ->bar3
  ->bar4
# methods related off road driving
  ->blah5
  ->blah6

Должен ли я:

A: Подкласс Car .Я могу сделать OffRoadCar расширяет объект Car.Но что, если Car и OffRoadCar совместно используют одни и те же данные / состояние и различаются только методами?OffRoadCar только «действует» более конкретно, чем автомобиль, но не описывается более конкретно и не имеет уникальных полей.Таким образом, создание OffRoadCar не имеет смысла.

OffRoadCar extends Car
# methods related off road driving
  ->blah5
  ->blah6

B: Использовать автомобиль статическим методом .Нравится OffRoadAdventure-> Embark (Автомобиль).Таким образом, класс OffRoadAdventure принимает объект Car и имеет свой путь к нему.

В C # это будет называться методом расширения.

Я полагаю, если поставить другой путь, это , каково решениек Blob антипаттерну ?Это подкласс?Это методы расширения?

Кроме того, еще одна причина, по которой я хотел использовать эти методы, заключается в том, что если их реализация требует определенных затрат, например, включение других классов / пакетов?Я бы не хотел, чтобы пользователи основного класса постоянно платили за то, что они никогда не будут использовать.Я полагаю, что явная стоимость для меньшинства стоит экономии для большинства.И это делает граф зависимостей более точным (и не похожим на блоб).

PS - язык реализации - Perl.

Ответы [ 5 ]

2 голосов
/ 15 февраля 2012

С Perl вы должны внимательно изучить Moose и роли.

package Suburban;
use Moose::Role;

requires 'wheels';

sub 'foo1' {
  ...
}


sub 'foo2' {
  ...
}

package City;
use Moose::Role;

requires 'wheels';

sub 'bar3' {
  ...
}


sub 'bar4' {
  ...
}

package Offroad;
use Moose::Role;

requires 'wheels';

sub 'blah5' {
  ...
}


sub 'blah6' {
  ...
}

package UltraCar;
use Moose;

with qw/ Offroad City Suburban /;
has 'wheels' => ( is => 'rw', isa => 'Int', default => 4 );

package RentalCar;
use Moose;

with qw/ City Suburban /;
has 'wheels' => ( is => 'rw', isa => 'Int', default => 4 );

package Tricycle;
use Moose;

with qw/ Offroad /;
has 'wheels' => ( is => 'rw', isa => 'Int', default => 3 );

Вы даже можете добавлять и удалять роли во время выполнения.

0 голосов
/ 15 февраля 2012

Пригородное, городское и внедорожное вождение звучат как алгоритмы.Шаблон стратегии может помочь здесь, когда Context - это Car.

0 голосов
/ 15 февраля 2012

Не совсем ответ Марк, и я не уверен, насколько глубоко вы хотите углубиться в это, но вы могли бы изучить идею порядка разрешения методов. Вместо стандартной глубины поиска сначала методов, использование mro позволяет выполнить поиск в ширину. См. эту страницу на CPAN и статью Брайана Д Фоя Используйте порядок разрешения метода C3 в множественном наследовании для получения дополнительной информации.

0 голосов
/ 15 февраля 2012

Вместо создания подкласса класса Car, вы можете использовать некоторую форму Шаблон декоратора .

Здесь базовый класс ORM и декораторы (скажем, OffRoadDecorator) реализуют некоторый общий интерфейс, и поведение каждого декоратора можно динамически добавлять к исходному классу.

Ключевым отличием здесь является то, что в одном классе Car можно использовать несколько декораторов, и ваша реализация должна сказать, как они должны взаимодействовать. Ничто не мешает вам украшать свой класс, используя OffRoadDecorator, а также SuburbanDecorator, и вы можете точно решить, что это значит для автомобиля в декораторах.

(P.S. извините, я не предоставляю никаких примеров кода; мой Perl просто ужасен. Посмотрите на эту страницу для других примеров.)

0 голосов
/ 15 февраля 2012

Я думаю, что вы на правильном пути. Элегантное решение состоит в том, чтобы OffRoadCar наследовать от Car и переопределять его Drive() метод. Таким образом, вы можете сказать:

Car myCar = new OffRoadCar();
myCar.Drive();

Это вызовет переопределенный метод Drive() в подклассе, и вы не получите gazillion методов в одном «блобе». Вот как может выглядеть Drive() метод в OffRoadCar:

@Override
public void Drive()
{
/* code */
}
...