ОО Дизайн: использовать свойства или перегруженные методы? - PullRequest
0 голосов
/ 05 января 2011

Вопрос о дизайне ОО.

Предположим, у меня есть базовый объект.И два потомка: грузовик и автомобиль.

Далее, предположим, что у базового объекта есть базовый метод:

Procedure FixFlatTire(); abstract;

Когда грузовик и автомобиль переопределяют базовый объект, им требуется другая информация отвызывающий.

Мне лучше перегрузить FixFlatTire, как это в двух объектах-потомках:

Procedure Truck.FixFlatTire( OfficePhoneNumber: String;
                             NumberOfAxles: Integer): Override; Overload;

Procedure Automobile.FixFlatTire( WifesPhoneNumber: String;
                                  AAAMembershipID: String): Override; Overload;

Или ввести новые свойства в каждом из потомков, а затем установить их перед вызовом FixFlatTire, как это:

Truck.OfficePhoneNumber := '555-555-1212';
Truck.NumberOfAxles := 18;
Truck.FixFlatTire();

Automobile.WifesPhoneNumber := '555-555-2323';
Automobile.AAAMembershipID  := 'ABC';
Automobile.FixFlatTire();

Ответы [ 4 ]

5 голосов
/ 05 января 2011

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

Если они применяются строго кМетод FixFlatTire, имеет больше смысла указывать их в качестве аргументов этой функции.

Если вы предоставляете другую сигнатуру метода в классе-потомке, это не является (насколько мне известно) случаем перегрузки.Вы просто переопределяете исходную функцию новой функцией с другими аргументами.Перегрузка - это когда доступны две функции с одинаковыми именами, различающиеся разными сигнатурами.

[Редактировать]

Если взглянуть на ваши аргументы чуть ближе, вот еще несколько мыслей:

  • NumberOfAxles, очевидно, является собственностью TTruck.

  • PhoneNumber и AAAMembershipID кажутся мне свойствами класса, которого у вас еще нет, TOwner (с возможными классами-потомками TCorporateOwner и TIndividualOwner).Тогда ссылка TOwner может стать свойством TVehicle или аргументом FixFlatTire () (хотя я полагаю, что она лучше будет принадлежать свойству TVehicle).

3 голосов
/ 05 января 2011

Настоящая ошибка:

FixFlatTire(); abstract;

Для включения полиморфного поведения она, безусловно, должна быть

FixFlatTire(); virtual; abstract;

.

Не следует перегружать виртуальные методы, нужно только переопределить сохранениеАргументы метода.


Обновление

Вы не должны и не можете перегружать виртуальные методы.Следующий код даже не компилируется:

type
  TVehicle = class
    procedure FixFlatTire(); virtual; abstract;
  end;

  TTruck = class(TVehicle)
    Procedure FixFlatTire( OfficePhoneNumber: String;
                             NumberOfAxles: Integer); Override; Overload;
  end;

  TAutomobile = class(TVehicle)
    Procedure FixFlatTire( WifesPhoneNumber: String;
                               AAAMembershipID: String); Override; Overload;
  end;

Вы должны сохранить аргументы виртуального метода при переопределении виртуального метода.

Таким образом, ответы таковы: первый вариант (перегрузка) просто невозможен.

2 голосов
/ 05 января 2011

Я бы не стал использовать последнее, так как кто-то может легко установить некоторые свойства и забыть позже вызвать метод. Хотя и первая проблема, потому что у вас нет подходящей сигнатуры для каждого метода в базовом классе.

Большинство проблем в ООП можно решить с помощью другого уровня абстракции. У вас может быть что-то вроде этого в базовом классе, совместно используемом и Автомобилем, и Грузовиком.

procedure FixFlatTire(TireProvider: ITireProvider); abstract; virtual;

ITireProvider может быть разделен на подклассы с помощью OfficeTireProvider и AAATireProvider, которые содержат соответствующие свойства, которые необходимо установить для каждого из них, и они могут переопределять любые элементы ITireProvider, необходимые для фактического ремонта шин.

0 голосов
/ 05 января 2011

Подход со свойствами бессмыслен. Вы не можете использовать полиморфизм должным образом, так как функции принимают разные параметры. Вы должны просто иметь различные методы в подклассах с соответствующими параметрами.

Теперь, если вы вернетесь с более сложной версией, в которой у вас будет только ссылка на базовый класс, тогда потребуется другой дизайн, но он не будет ни одним из тех, которые вы предлагали до сих пор.

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