Является ли полиморфизм с помощью классов и методов плохим? (2) - PullRequest
0 голосов
/ 02 марта 2010

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

Я знаю, что это несколько субъективный вопрос, но это законный вопрос, который возникает с точки зрения функционального программирования, например: http://blog.thinkrelevance.com/2009/7/8/triadic-programming

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

Ответы [ 5 ]

4 голосов
/ 02 марта 2010

Полиморфизм (или наследование) может привести к проблемам, если ваша иерархия станет слишком большой.

Например, может быть логично иметь следующие классы:

class Animal;
class Mammal : public Animal;
class Dog : public Mammal;
class Cat : public Mammal;
class Fish : public Animal;

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

class Animal;
class SwimmingAnimal: public Animal;
class Dog : public SwimmingAnimal;
class Fish: public SwimmingAnimal;
class NonSwimmingAnimal: public Animal;
class Cat : public NonSwimmingAnimal;

Вы можете попытаться реализовать обе иерархии, используя виртуальное наследование, но это быстро приводит к множеству проблем (одна из них также называется «проблема алмазов»).

Использование интерфейсов может решить многие из этих проблем, но с затратами.

class Animal;
class Dog : public Animal, public IMammal, public SwimmingAnimal;
class Cat : public Animal, public IMammal;
class Fish: public Animal, public SwimmingAnimal;

Поскольку классы наследуются только от интерфейсов, они не могут легко использовать одни и те же функции. Таким образом, функциональность совместного использования должна быть реализована посредством локализации. Если Dog и Fish хотят предложить обе функции «плавания», они должны предоставить метод плавания и реализовать его, перенаправив вызов в отдельный класс Swim, что-то вроде этого (это весь псевдокод):

class Dog : public Animal, public IMammal, public SwimmingAnimal
{
public:
   void swim(double speed) {m_swim->swim(speed);}
private:
   Swim m_swim;
}
3 голосов
/ 02 марта 2010

В программировании действительно нет серебряной пули. Сказать, что X лучше, чем Y для всех ситуаций, просто неправильно. При написании программного обеспечения я склонен следовать следующим рекомендациям.

  1. Используйте наследование, когда у меня есть четко определенная объектная модель.
  2. Использовать композицию при совместном использовании функций между несвязанными объектами.
  3. Заполните пропуски функциональными методами, обеспечивающими безопасность резьбы.
3 голосов
/ 02 марта 2010

Лично я не чувствую, что полиморфизм через классы "плох", однако есть и другие варианты ...

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

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

2 голосов
/ 02 марта 2010

Это зависит.

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

Но наследование, полиморфизм и объектная ориентация не являются изначально «плохими» и не исчезают в ближайшее время.

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

1 голос
/ 02 марта 2010

указанная вами ссылка не говорит "полиморфизм через классы и методы плох" это просто говорит «Вы можете бороться с диадами, избегая так называемых« лучших практик » Я не знаю, о ком он говорит

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