Два разных объекта реализуют один и тот же интерфейс одинаково - как остаться DRY - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть интерфейс:

IColored, который гарантирует функцию getColor.

Теперь у меня есть два объекта:
1. Ferrari
2. RedApple

что оба реализуют этот интерфейс / функцию одинаково.
(Но не могут наследовать от одного и того же объекта - не допускается мульти-наследование).

Как бы вы избежали дублирования кода?

Ответы [ 3 ]

4 голосов
/ 19 февраля 2020

Полагаю, вы ищете агрегацию объектов.

Проверьте TAggregatedObject. Идея состоит в том, чтобы иметь объект, который реализует поведение, и как свойство он делегирует функции интерфейса этому внутреннему объекту.

1 голос
/ 19 февраля 2020

DRY - это принцип. Как правило, его цель - показать вам лучшие практики. Но, поскольку это «просто» принцип, а не какой-то нерушимый закон, нужно знать, когда его применять, а когда предпочтительнее - нет.

Мой подход к принципу DRY заключается в том, что он не поскольку 2 функции реализованы точно так же, как они не заслуживают того, чтобы существовать, по тем же причинам, по которым вы можете иметь несколько констант с одинаковыми значениями (ERROR_SUCCESS = NO_ERROR = SW_HIDE = et c ...). Семантика и контексты имеют значение.

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

Но само собой разумеется, все это немного субъективно.

0 голосов
/ 19 февраля 2020

Если я вас правильно понимаю, вы не сможете - не совсем. Но вы можете подобраться так:

TYPE
  IColored = INTERFACE('GUID')
               FUNCTION getColor : TColor;
             END;

  TFerrari = CLASS(IColored)
               FUNCTION getColor: TColor;
             END;

  TRedApple = CLASS(IColored)
               FUNCTION getColor: TColor;
             END;

FUNCTION CommonFunction : TColor;
  BEGIN
    // Lots of code that ends with Result:=clRed
  END;

FUNCTION TFerrari.getColor : TColor;
  BEGIN
    Result:=CommonFunction
  END;

FUNCTION TRedApple.getColor : TColor;
  BEGIN
    Result:=CommonFunction
  END;

ie. делегировать реальный код в функцию вне вашей иерархии объектов, чтобы вы могли вызывать его независимо от ваших реализаций INTERFACE.

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

...