Kamafeather
Kamafeather

Reputation: 9845

Make a library to use a custom implementation of its class

There is a library with these classes:

Where

namespace ExternalLibrary;

class DefaultObject {}

class ObjectConsumer {

    protected $object;

    // the oter Object<...> classes have all the same constructor
    public function __construct()
    {
        $this->object = new DefaultObject;
    }

    public function compareWith(DefaultObject $comparand)
    {
        // just a method in order to have another dependency in the type-hinting
    }
}

And there is my library that wants to extend the concepts and functionalities of the external library:

Where

namespace ExternalLibrary;

use ExternalLibrary\DefaultObject as BaseDefaultObject;

class DefaultObject extends BaseDefaultObject {
    // marvelous additional concepts on top of the base concepts
}

Given that I don't want to wrap/extend/override/redefine all the classes that potentially use DefaultObject:

(e.g. ObjectEater relying on MyLibrary/DefaultObject)

Upvotes: 1

Views: 108

Answers (2)

MikO
MikO

Reputation: 18741

Just to complement the other correct answers/comments.

What options do I have, in PHP, in order to have my custom object to be used everywhere in my library when relying on the external-library?

You have no decent options - anything you might do is so hacky that you shouldn't even consider it for a second.

And what about other languages? Would that be easier?

I'm not an expert in many languages, but I can't think how this could be easier in other languages. The consumer classes are instantiating a particular class in their constructors, and by doing that they intentionally leave you no choice to override that behaviour. They want to use an instance of that class, and that's it...

And what in the case I were the owner of the external library and could change its code?

You'd use the well-known Dependency Injection approach, with bonus points for using interfaces instead of implementations, and also making the constructor argument optional in order to keep backwards-compatibility with any other code using those classes - something like:

class ObjectConsumer {

    protected $object;

    public function __construct(DefaultObjectInterface $object = null)
    {
        $this->object = $object !== null ? $object : new DefaultObject();
    }

    public function compareWith(DefaultObjectInterface $comparand)
    {
    }
}

Upvotes: 0

tereško
tereško

Reputation: 58444

The source of the problem is that the code of that library is shit. It is tightly coupled to the DefaultObject classes name (because it initiates it in the constructor, instead of expecting it as a dependency).

The only way to bypass it would be to actually mess with the autoloader (assuming that this magical library is not defining multiple classes in the same file), if it's even using it.

But in any case, I would recommend to start looking into ways of removing the dependency on that library from your project. It constitutes a huge development risk.

Upvotes: 1

Related Questions