Reputation: 23629
A big part of my C++ application uses classes to describe the data model, e.g. something like ClassType (which actually emulates reflection in plain C++).
I want to add a new module to my application and it needs to make use of these ClassType's, but I prefer not to introduce dependencies from my new module on ClassType.
So far I have the following alternatives:
How far should you try to go when decoupling modules in an application?
I afraid that by decoupling it too far, the code becomes more unstable and more difficult to debug. I've seen one such example in Qt: signals and slots are linked using strings and if you make a typing mistake, the functionality doesn't work, but it still compiles.
How far should you keep your modules decoupled?
Upvotes: 3
Views: 867
Reputation: 6846
It's a philosophical question; it depends on the type of module, and the trade-offs. I think I have personally done all of them at various times, except for the GUID to type mapping, which doesn't have any advantages over the string to type mapping in my opinion, and at least strings are readable.
I would say you need to look at what level of decoupling is required for the particular module, given the expected external usage and code organization, and go from there. You've hit all the conceptual methods as far as I know, and they are each useful in particular situations.
That's my opinion, anyway.
Upvotes: 0
Reputation: 55957
I'll steer away from thinkng about your reflection, and just look at the dependency ideas.
Decouple what it's reasonable to decouple. Coupling implies that if one thing changes so must another. So your NewCode is using ClassType, if some aspects of it change then yuou surely must change NewCode - it can't be completely decoupled. Which of the following do you want to decouple from?
To my eyes the first two are reasonable coupling. But surely an implementation change should not require NewCode to change. So code to Interfaces. We try to keep Interfaces fixed, we tend to extend them rather than change them, keeping them back-compatible if at all possible. Sometimes we use name/value pairs to try to make the interface extensible, and then hit the typo kind of errors you allude to. It's a trade-off between flexibility and "type-safety".
Upvotes: 1
Reputation: 106609
99% of the time, if your design is based on reflection, then you have major issues with the design.
Generally speaking, something like
if (x is myclass)
elseif (x is anotherclass)
else
is a poor design because it neglects polymorphism. If you're doing this, then the item x
is in violation of the Liskov Substitution Principle.
Also, given that C++ already has RTTI, I don't see why you'd reinvent the wheel. That's what typeof
and dynamic_cast
are for.
Upvotes: 2