I’m currently helping build an API that I would like 3rd party developers to use. This API hooks to a service in the cloud. This service is constantly changing and not currently very reliable. Therefore, I would like to provide in my SDK both real clients and fake ones. Whenever the service is down, developers can simply use the fake client rather than the real one and continue coding.
I’ve looked at all sorts of design patterns and some addressed my problem nicely. Here is the catch though.. I want to make the code as simple as possible: So let’s say my service is called Experia. I want people to be able to just do something like this:
class Experia extends Exp
...
$ex = new Experia(/*initialization parameters*/); //init prameters like user name, password etc
$ex->story()->create($storyArgs);
currently, Experia is a class that extends another class Exp that contains a list of these resources and the files they are available in.. and it also extends a generic class called Client that defines the basic get() and post() methods etc, and basically sets up the client remote url and so on (it wraps around the pest library)
so Exp goes something like this:
class Exp extends Client
{
public function story() {
include_once('classes/User.php');
}
//other resource methods
}
I want to create another class that contains all my fake resources.. something like this:
class ExpFake extends Client
{
public function story() {
include_once('classesFake/User.php');
}
//other resource methods
}
Here is the problem I’m facing. I want Experia to be able to extend either Exp or ExpFake depending on its declaration, without any ugliness.. and by ugliness I mean any extra code that developers using my API will have to use. So for example one thing I tried to do was decouple client from Exp and basically do this
$ex = new Experia(/*... */);
$ex->client = new fakeClient(); //I could also do $ex-> client = new realClient();
but then the problem was that every time I wanted to use call a resource.. I had to specify the client:
$this->client->story()->create($args)
the client part is extra code that i cannot include in my api..
so long story short.. what is the design pattern (or direct way if possible.. in php) that achieves the same result as selectively inheriting from one class or another
so like having the option of doing this:
class Experia extends (either Exp or ExpFake depending on Experia’s initialization parameters)
A good way would be an adapter pattern. Your main client is the
Expclass, which is what developers use to interact with your service. This class depends on an adapter to connect to your service though. This adapter class is required to be injected when instantiatingExpand is the part that can be mocked if necessary.You can then create a real
ExpAdapterand a mocked one:Instead of extending an
abstractclass, you can also use aninterfacespecification.To the developer, this will look like: