Как изменить существующий класс, чтобы он стал полиморфным? - PullRequest
3 голосов
/ 29 июня 2010

У меня есть класс, который используется в качестве члена во многих местах в моем проекте.Теперь вместо этого класса я хочу иметь полиморфизм, и фактический объект будет создан какой-то фабрикой.

Мне нужно выбирать между:

  1. Необходимость изменитьвсе места, где я использую класс - для вызова фабрики и непосредственного использования указателя вместо объекта.
  2. Изменение класса на обычную обертку, которая будет вызывать функции нового полиморфного класса, который я создам.

Какую стратегию мне лучше выбрать?

Ответы [ 3 ]

4 голосов
/ 29 июня 2010

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

Это лучше.Поначалу это кажется болезненным, но это чисто и более расширяемо, чем реализация обертки, потому что вам не хотелось выполнять поиск new MyClass(.

Как только вы перечислите все места с помощью new, выувидим, что это не так уж и плохо.

2 голосов
/ 29 июня 2010

Скорее всего, даже если вы пойдете с # 2 и внедрите обертку базового класса, вам все равно придется изменить код клиента (различные методы построения на фабрике, например, для полиморфной обертки базы).

Я бы пошел с # 1, но не с обычным указателем, а с чем-то вроде boost :: shared_ptr или boost :: scoped_ptr (в зависимости от того, что вам нужно).

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

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

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

1 голос
/ 29 июня 2010

У вашей идеи использования обертки даже есть имя.Это буква / конверт идиома , как описано Коплиеном (до того, как они начали называть эти идиомы "шаблонами").
Google находит вам больше объяснений для этого.

В отличие от других, я не вижу в этом ничего плохого.Для пользователей класса гораздо проще иметь дело с чем-то, что ведет себя так же просто, как тип значения.Нет необходимости использовать фабрику или фабричный метод для создания объектов, так как конструкторы класса - это фабрики - для чего изначально были изобретены конструкторы.
Что может быть не так с этим?

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