Вопрос о реализации / наследовании интерфейса - PullRequest
2 голосов
/ 21 апреля 2010

Мне бы хотелось узнать мнение сообщества stackoverflow о следующих трех шаблонах проектирования.Первый - это наследование реализации;второй - наследование интерфейса;третье - это золотая середина.Мой конкретный вопрос: что лучше?

наследование реализации:

class Base {
  X x() const = 0;
  void UpdateX(A a) { y_ = g(a); }
  Y y_;
}

class Derived: Base {
  X x() const { return f(y_); }
}

наследование интерфейса:

class Base {
  X x() const = 0;
  void UpdateX(A a) = 0;
}

class Derived: Base {
  X x() const { return x_; }
  void UpdateX(A a) { x_ = f(g(a)); }
  X x_;
}

средний уровень:

class Base {
  X x() const { return x_; }
  void UpdateX(A a) = 0;
  X x_;
}

class Derived: Base {
  void UpdateX(A a) { x_ = f(g(a)); }
}

Я знаю, что многие люди предпочитают наследование интерфейса реализации наследования.Однако преимущество последнего состоит в том, что с указателем на Base можно встроить x (), а адрес x_ можно вычислить статически.

Ответы [ 2 ]

0 голосов
/ 06 мая 2010

Я бы сказал, что ни один метод не является лучше , чем другие. Все они полезны в различных сценариях в зависимости от контекста, в котором они используются.

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

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

Я вижу, что ваш средний пример полезен, если вы наследуете проект, который не был разработан с использованием объектно-ориентированных методов. Может быть, вам нужно реорганизовать его при добавлении новых функций, и вы можете использовать его как способ заставить устаревший код взаимодействовать с новым кодом, который использует объектно-ориентированный дизайн. Это скорее компромисс, чем фактическая «лучшая практика», но мы все должны сделать так, чтобы они доставляли продукты ... Если я смогу придумать лучший / более конкретный пример, я опубликую его.

0 голосов
/ 21 апреля 2010

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

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