Abstracting class hierarchy

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Abstracting class hierarchy

      While writing the code I stumbled upon one weird architecture problem.

      Let's presume we need some functionality in the form of a class hierarchy. We want this functionality to replaceable. For example due to platform change. The question is what is the proper way to organize this?

      So far, this is what I came to:

      Source Code

      1. // Define hierarchy of interfaces/abstract classes
      2. class Base
      3. { ... };
      4. class Derived1 : public Base
      5. { ... };
      6. class Derived2 : public Base
      7. { ... };
      8. // Hierachy could be a little deeper though


      This hierarchy is what client uses (at least should) no matter what platfrom is underneath.

      Then presume two cases:
      • We already have the implementation of the functionality for the given platform
      • We will implement this functionality ourselves


      In both cases implementation should easily be switched.

      And on this point my confusion begins. How to achieve this? I though of the Bridge and Adapter patterns. Bridge is the closer thing what maybe can work. However classic bridge only contains pointer to implementation base class and we have hierarchy wich adds new methods/data, so we can't just use base interface of the implementation. (although we can try to substitute implementation in the derived class, but it's no longer a classic bridge).

      Adapter also seems does not work with hierarhies.

      If all the above doesn't make sence, consider two examples.


      1. We have texture hierarchy:
      -----------Texture2d
      /
      BaseTexture-----------Texture3d
      \
      ----------CubeTexture

      We want this to be implemented in OpenGL or DirectX. We don't have an implementation and will provide it ourselves.

      2. We have XML hierarchy
      -------XmlDocument
      /
      XmlNodeBase-------XmlElement

      Now we have the library which implements the functionality for us and we just want to abstract away the libarary hierarchy in a sebsible way. (i.e. these 3 classes are our iterfaces and we have similar hierarchy in the library and we need to 'put' lib classes into our hierarchy preserving relationships in a cross-platform way)



      Remember derived classes extend the interface! So we can just throw in the abstract factory and be happy, because it only works if the interface is the same and implementation differs.

      Again, the only thing I came to is to modify bridge pattern. Any ideas or comments that you have? This seems like usual taks for the cross-platform game engine, because there are many modules which should be relpaced for different platforms.
      Looking for a job!
      My LinkedIn Profile

      The post was edited 2 times, last by devast3d ().

    • Hello!

      I'll be honest with you - I don't fully understand what your problem is.
      But I have a few comments:

      we have hierarchy which adds new methods/data

      This is a bad practice. In terms of contract-based programming interface of your class-hierarchy is a "contract".
      If you add new public methods to few derived classes you breaking the "contract" - this is the first sing, that your approach is bad.

      Keep hierarchy flat, encapsulate 3rd party libs (if they not cross platrofrm), and prefer composition instead of inheritance.

      And maybe you could get more clear example? Maybe your concrete case.
    • The example is wrapping tinyxml library. It has XMLNode, XMLElement, XMLDocument, XMLAttribute and so on... Document and element are derived from the node. Both derived classes extend interface of the base class of course and it could not be other way. Now I don't really want to use the library directly. So the idea is to wrap this hierarchy so I can theoretically swap the tinyxml for the other lib or write my own. Hope this makes sence.
      Looking for a job!
      My LinkedIn Profile
    • Yes it makes.

      TinyXML hierarchy reminds me Decorator pattern. ))

      OK. There are various solutions:

      1. Simple solution: just don't wrap TinyXML. TinyXML is cross-platform himself. But this solution breaks idea of swaping the tinyxml later.

      2. Wrap TinyXML using the same hierarchy - Node->Element and so on. It seems to you reasonable now, but imagine that you will decide to change tinyxml, and new lib will have completely different interface, or even not xml-based but json or RDBMS whatever... Uh?

      3. Wrap TinyXML by your own way/ Look at wrapping of BulletPhysics in GCC code. There is custom wrapper with custom interface.
    • Also offtopic:

      As tinyxml works with utf8 strings using std::string and we usually need std::wstring the conversion is required. GCC engine uses windows specific functions to do the conversion.

      Modern approach is to use std localizations facility. Maybe someone will find it helpful.

      C Source Code

      1. // C++11 way to convert strings
      2. #include "tinyxml2.h"
      3. #include <string>
      4. #include <codecvt>
      5. ...
      6. tinyxml2::XMLDocument doc;
      7. doc.LoadFile("utf8test.xml");
      8. tinyxml2::XMLElement* root = doc.RootElement();
      9. tinyxml2::XMLElement* elem = root->FirstChildElement("Russian");
      10. const char* text = elem->Attribute("value");
      11. // Here is the 'magic'
      12. std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
      13. std::wstring str = convert.from_bytes(text);
      14. // Prints unicode text (utf16 to be precise)
      15. OutputDebugStringW(str.c_str());
      16. ...
      Display All


      BTW the really modern approach is to use u16string, but visual studio still does not support this, considering that gcc and clang already has full support of the new standard.. what a shame!
      Looking for a job!
      My LinkedIn Profile

      The post was edited 1 time, last by devast3d ().

    • So is English the only language that uses ASCII? In order for you guys to make your programs in Russian you have to use Unicode with wide strings?
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz