1

I'm using a library which have an interface for a certain functionality, and a few implementation of the functionality. The library also provides a Factory object that instantiates the correct functionality's implementation.

I need to extend a functionality in question by adding new methods to the object, and I wanted to do this by creating a new interface which inherits from the library's interface and roll my own implementations.

For example :

class IFromLibrary
{
  virtual void LibraryMethod(void) = 0;
}

class IMyInterface : public IFromLibrary
{
  virtual void MyMethod(void) = 0;
  int SomeValue;
}

class TMyImplementation : public IMyInterface
{
  void LibraryMethod(void) { ... }
  void MyMethod(void) { ... }
}

The problem I'm facing is with the creation of an instance of TMyImplementation. Like I said, the library hides the constructors of the implementations as private members and uses Factory static methods to construct the objects.

Example :

static IFromLibrary * createFromLibrary(int whatever) { ... }

Since it's the paradigm of the library, I'm trying to do it as well by creating my own create in my implementation class :

static IMyInterface * createMyImplementation(int whatever) { ... }

The problem I have is that I'd wish that my newly instantiated object would be constructed using the values provided by the library's Factory :

static IMyInterface * createMyImplementation(int whatever)
{
  IMyInterface * newObject = createFromLibrary(whatever); // this doesn't compile, evidently.
  newObject->SomeValue = SomeOtherValue; // init the parts of the object that belong to my interface
}

I'm trying to avoid the adapter pattern (i.e. wrapping a IFromLibrary pointer inside my TMyImplementation class and forward all the method calls that are inherited from IFromLibrary­). That would indeed work, but from my point of view, I find it strange, architecturally speaking, that I simultaneously inherit from and wrap a class. I also want to avoid all that forwarding boiler plate code, if at all possible.

Can this be done in any way?

EDIT :

  • Added the fact that the private constructors are for the implementations only (sorry @NirFriedman for the confusion).
  • Specified why I want (if possible) to avoid the Adapter pattern (thanks @immibis for the pattern name).
MartinVeronneau
  • 1,296
  • 7
  • 24
  • 2
    Can you register new stuff with the factory in the library? – Nir Friedman Mar 30 '17 at 20:58
  • Also, as a point of information: making a constructor for an abstract class private is dumb. – Nir Friedman Mar 30 '17 at 21:01
  • "wrap[ping] a IFromLibrary pointer inside my TMyImplementation class and then having to forward all the method calls that are inherited from IFromLibrary­." is called the adapter pattern and is probably what you want to do. – user253751 Mar 30 '17 at 21:10
  • @immibis I don't see how this will work. There's no way to construct anything that inherits from `IFromLibrary` without going through the factory, which gives you some other implementation. – Nir Friedman Mar 30 '17 at 21:24
  • 1
    @NirFriedman ... so you use the factory to get an instance of `IFromLibrary`, store a pointer to it inside your TMyImplementation object, and forward all the method calls that are inherited from IFromLibrary to that object. This is called the adapter pattern - you can Google 'oop adapter pattern' for more information. – user253751 Mar 30 '17 at 21:43
  • @immibis Pretty sure the OP wants to use his own implementation of `LibraryMethod`, which your suggestion does not allow. Even aside from that, TMyImplementation still cannot inherit from IFromLibrary, so you cannot pass a TMyImplementation object where an IFromLibrary reference is expected (e.g. in library methods). – Nir Friedman Mar 30 '17 at 22:07
  • @NirFriedman ??? If you don't want to use the library's implementation then there is no problem - you simply override LibraryMethod normally! (I'm assuming MyMethod and LibraryMethod are actually public) Nothing in the question suggests TMyImplementation can't inherit from IFromLibrary - in fact in the code in the question **it does**! – user253751 Mar 30 '17 at 22:15
  • @immibis OP said the library hides all constructors as private members. If IFromLibrary has a private constructor, then you can't inherit from it normally. I'm no longer sure if that's what he meant though, it's pretty unclear. – Nir Friedman Mar 30 '17 at 22:28
  • @NirFriedman I read it as all constructors of the implementation of IFromLibrary, not all constructors of IFromLibrary. – user253751 Mar 30 '17 at 23:29
  • I'll add details to try to answer the questions. – MartinVeronneau Mar 31 '17 at 13:03
  • @NirFriedman I can't register new stuff with the library, unfortunately. – MartinVeronneau Mar 31 '17 at 13:26
  • @MartinVéronneau The only way to avoid forwarding the method calls, is to inherit from an implementation, unfortunately that's all there is to it. And there's no way to inherit from a class with a private constructor without changing that class in some way. So I think... you're screwed. Sorry! – Nir Friedman Mar 31 '17 at 14:34
  • Argh, you're right. That makes sense, now that you explain it like that. Post that as answer, and I'll accept it. – MartinVeronneau Mar 31 '17 at 14:56
  • @immibis, if you wish to post an example of the Adapter pattern, I'd accept that too. – MartinVeronneau Apr 03 '17 at 20:59

2 Answers2

1

You can use the decorator pattern (I said "adapter pattern" before incorrectly - they are quite similar though) - have your TMyImplementation object delegate LibraryMethod to an IFromLibrary object that you got from the library:

class TMyImplementation : public IMyInterface
{
    IFromLibrary *base;
public:
    TMyImplementation(IFromLibrary *base) : base(base) {}
    ~TMyImplementation() {delete base;} // ideally you would use a unique_ptr instead

   void LibraryMethod() {base->LibraryMethod();}
   void MyMethod() {...}
};

Then to create a TMyImplementation you might use new TMyImplementation(createFromLibrary(whatever)).

(Note that patterns are merely starting points for designs, not rules to be strictly followed! For example depending on your design you could move the createFromLibrary call inside the constructor)

Community
  • 1
  • 1
user253751
  • 57,427
  • 7
  • 48
  • 90
0

It would be great if you could find implementation of "createFromLibrary" and use it in your "createMyImplementation", if it's not possible:

static IMyInterface * createMyImplementation(int whatever)
{
    IFromLibrary* newLibraryObject = createFromLibrary(whatever);
    IMyInterface* newObject = (IMyInterface*)malloc(sizeof(IMyInterface));
    memcpy(newObject, newLibraryObject, sizeof(IFromLibrary));
    newObject->SomeValue = SomeOtherValue;
    return newObject;
}

It is not guaranteed to work, if the library keeps the trace of it's objects, this way it will loose connection with "newObject" that can lead to undefined behavior.

If your library has something like "ReleaseFromLibrary(IFromLibrary* pObj)" try to call it when you finished with "newObject" or "newLibraryObject" or both! (any of them can lead to undefined behavior).

Anyway I don't like this kind of solutions, but nothing better came to my mind!

Ali Asadpoor
  • 327
  • 1
  • 13
  • I have, in fact, access to the library's createFromLibrary() implementation. I could reproduce that code inside createMyImplementation(), but the library is still in development, and I'm afraid I'd have to maintain my method as the library evolves, and I wish to avoid that. Your solution is a bit hackish, but I can't really downvote, as it could work in some situation (if I had control on the library, for instance). – MartinVeronneau Mar 31 '17 at 13:35