Сохранение модулей независимыми, при этом все еще используя друг друга - PullRequest
3 голосов
/ 23 сентября 2010

Большая часть моего приложения C ++ использует классы для описания модели данных, например что-то вроде ClassType (который фактически эмулирует отражение в простом C ++).

Я хочу добавить новый модуль в мое приложение, и ононеобходимо использовать эти ClassType, но я предпочитаю не вводить зависимости от моего нового модуля на ClassType.

Пока у меня есть следующие альтернативы:

  • Не сделать его независимым иввести зависимость от ClassType с риском создания дополнительных «спагетти-зависимостей» в моем приложении (это мое наименее предпочтительное решение)
  • Введите новый класс, например, IType, и пусть мой модуль зависит только отЯ печатаю.ClassType должен затем наследоваться от IType.
  • Использовать строки в качестве метода идентификации и заставлять пользователей нового модуля преобразовывать ClassType в строку или наоборот, где это необходимо.
  • Использовать GUID (илидаже простые целые числа) в качестве идентификации, также требующие преобразования между GUID и ClassType

Как далеко вы должны пытаться зайти, когда разъединяете модули в приложении?

  • просто представьте интерфейси пусть все остальные модули полагаются на интерфейс?(как в IType, описанном выше)
  • даже отделить его дальше, используя другие идентификаторы, такие как строки или GUID?

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

Как далеко вы должны хранить свои модулиразвязаны?

Ответы [ 3 ]

2 голосов
/ 23 сентября 2010

99% времени, если ваш дизайн основан на отражении, у вас есть серьезные проблемы с дизайном.

Вообще говоря, что-то вроде

if (x is myclass)
elseif (x is anotherclass)
else

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

Кроме того, учитывая, что в C ++ уже есть RTTI, я не понимаю, зачем вам изобретать велосипед.Вот для чего typeof и dynamic_cast.

1 голос
/ 23 сентября 2010

Я откажусь от размышлений о вашем размышлении и просто посмотрю на идеи зависимости.

Отделите то, что разумно, чтобы отделить. Сцепление подразумевает, что если одно меняется, то должно меняться и другое Таким образом, ваш NewCode использует ClassType, если некоторые его аспекты изменяются, тогда вы, безусловно, должны изменить NewCode - его нельзя полностью отделить. Что из следующего вы хотите отделить от?

  1. Семантика, что делает ClassType.
  2. Интерфейс, как вы это называете.
  3. Реализация, как это реализовано.

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

0 голосов
/ 23 сентября 2010

Это философский вопрос;это зависит от типа модуля и компромиссов.Я думаю, что лично делал все это в разное время, за исключением GUID для отображения типов, который, по моему мнению, не имеет никаких преимуществ перед отображением строк и отображений типов, и по крайней мере строки читаются.* Я бы сказал, что вам нужно посмотреть, какой уровень развязки требуется для конкретного модуля, учитывая ожидаемое внешнее использование и организацию кода, и перейти оттуда.Насколько я знаю, вы применили все концептуальные методы, и каждый из них полезен в определенных ситуациях.

В любом случае, это мое мнение.

...