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 Exp class, 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 instantiating Exp and is the part that can be mocked if necessary.
class Exp {
protected $adapter;
public function __construct(ExpAdapter $adapter) {
$this->adapter = $adapter;
}
public function foo() {
return $this->adapter->doFoo();
}
}
abstract class ExpAdapter {
abstract public function doFoo();
}
You can then create a real ExpAdapter and a mocked one:
class LiveExpAdapter extends ExpAdapter {
public function doFoo() {
// contact the actual service
}
}
class MockExpAdapter extends ExpAdapter {
public function doFoo() {
return true;
}
}
Instead of extending an abstract class, you can also use an interface specification.
To the developer, this will look like:
$exp = new Exp(new LiveExpAdapter);
// if service is down, use instead:
// $exp = new Exp(new MockExpAdapter);
$exp->foo();
depends on your php version, but I would use traits, in that case
trait Exp {
}
trait ExpFake {
}
class Experia {
use Exp;
}
alternative with drivers is fine as well e.g. define interface and separate drivers or implementations (as with db, when you have different driver classes e.g. mysql, psql etc)
Related
This is just a general question around a solution I'm trying to find.
I have potentially many providers of the same type of service and I need a way to be able to have a default, but then also manually call a switcher method to change them.
Currently, I've bound an Interface to an Implementation via configuration settings and this works well - but it means I can only support one active provider per type of service.
I noticed the Cache::disk() method is really what I'm looking for, but I'm not sure where this type of switch method should be defined.
Current:
interface IProvider {
public function getServiceInfo($args);
public function setServiceInfo($args);
}
class GoldService implements IProvider {
// implementation of the two interface methods
}
class SilverService implements IProvider {
}
// ProviderServiceProvider
public function register()
{
$this->app->bind(
App/IProvider,
App/GoldService
);
}
// Controller
public function getServiceInfo(Service $serviceId)
{
$provider = $app->make('App/IProvider');
$provider->getServiceInfo($serviceId);
}
Want to have.
// What I want to be able to do
public function getServiceInfo(Service $serviceId)
{
// Using a facade
if ($serviceId > 100)
{
Provider::getServiceInfo($serviceId);
}
else
{
Provider::switch('SilverService')
->getServiceInfo($serviceId);
}
}
I know I've thrown in an additional requirement there of the Facade - not sure if I've confused Contracts/Facades here - but essentially I want the interface to enforce the instance methods, but Facade for easy access to the instances.
Not really looking for code here - that'll be the easy part. I'm just not sure I've really grok'd this and looking for a nudge in the right direction..
Using an interface to ensure a service implements the methods you require makes sense.
But with regard to using a different service based on the properties of an object instance; that sounds more like the Factory pattern to me.
http://www.phptherightway.com/pages/Design-Patterns.html
I'm just learning about PHP's interfaces as I have never really used them before, but as I understand it they are only a interface, as they are called, to kind of uphold how classes that implement them are structured?
So for example, if you wanted to make two different classes for two different databases you could do:
class mysql {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
...and that would technically be the same as:
interface database {
public function connect() {
}
public function getData() {
}
}
class mysql implements database {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB implements database {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
...am I right? It's just that using an interface it makes sure you don't go doing something like the below and hence not being able to change databases easily?
class mysql {
public function connect_mysql() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB {
public function connect_mongo() {
// code here
}
public function getData() {
// code here
}
}
Is that pretty much the reasoning behind them?
What the interface does is it standardises what your code can rely on, and at the same time decouples that from a specific implementation. Wow, that sounds complicated. It's easier to illustrate it from the perspective of a user of interfaces:
function (MyDatabaseInterface $db) {
$db->connect();
$db->getData();
}
Type hints are a big part of using interfaces. This function declares that its argument must be an instance of MyDatabaseInterface, in other words, any object that implements MyDatabaseInterface. It is entirely up to you what specific object that is, as long as it implements MyDatabaseInterface. And since in MyDatabaseInterface you have specified the methods connect() and getData(), you can be sure that any object being passed in has these methods and that you can call them.
The other way around, have a look at this function:
/**
* #return MyDatabaseInterface
*/
function foo() {
...
}
It is irrelevant what this function does internally, but it declares that it will return an object of type MyDatabaseInterface, in other words some object that implements MyDatabaseInterface. When you call it, you know what you can rely on:
$bar = foo();
$bar->connect();
$bar->getData();
This function may return an instance of mysql or of mongoDB, it is none of your concern. You simply stick to what was declared in the interface and your code will work regardless of what specific object you get.
An interface literally defines the interface between code. It defines what methods code can safely call on other code, without tying down the specifics to specific classes. Your specific objects could define a ton more methods than are defined in the interface; an interface does not declare a class structure. A class could implement several interfaces at once, meaning it implements all the methods of all the interfaces; each individual interface would then just represent a subset of all the possible methods that could be called on an object.
You should describe specific "tasks" or "abilities" which can be accomplished in an interface, not "classes". It's a good sign if your interface names end with "-able", like Iterable. A class can then implement several interfaces and thereby describe all the things it "can do". You can then require function arguments with a certain "ability" at specific points, as shown in the example code above. This isolates and decouples parts of code from one another, which makes your code more flexible, reusable and adaptable to change.
For a useful real world scenario, imagine a larger development team which is working on a large project. There are several sub-teams, each responsible for a different part of the application. They all sit down together and come up with a general plan. At some point, the code of these separate teams needs to interact with each other. They can define these interfaces upfront:
"I'll need to call some method on your code that gives me the user credentials."
"OK, then you'll need to give me some object from which I can get the foobar."
"Then over here we'll have to talk to Joe's component to send the baz data."
...
They can define the different methods they will need to talk to each other in an interface before any code has been written, then go off and do their own thing. They can rely on code which hasn't even been written yet, because they already decided on what the interface will look like. They can even substitute the real code with mock objects for the time being while Joe is still hammering out his real code, then simply switch it in later with whatever Joe comes up with. And all those techniques are useful even if you're just working by yourself.
I am trying to develop an object oriented PHP application in which whole php application will be extending from MyApplicationBase base class. But the problems is I want to create only single instance of MyApplicationBase. Below is the code which explains what I mean
class MyApplicationBase{
static $called=0;
public var $db;
function __construct()
{
self::$called++;
echo "<pre>MyApplicationBase Created ".self::$called." times</pre>";
$this->db=new DatabaseWrapper();
}
}
class ApplicationSecurity extends MyApplicationBase{
function is_logged_in()
{
$res=$this->db->query("user check db query goes here");
return ($res)?true:false;
}
//..... other methods related to ApplicationSecurity class
}
class ApplicationBusinessLogic extends MyApplicationBase{
// business logic methods here which may use base class vars like $db
// this may also use instance of ApplicationSecurity class
}
class ApplicationTemplating extends MyApplicationBase{
protected function outputHeader()
{
require_once('path/to/themes/header.php');
}
protected function outputSidebar()
{
require_once('path/to/themes/siderbar.php');
}
protected function outputMainbody()
{
require_once('path/to/themes/mainbody.php');
$app=new ApplicationBusinessLogic();
$app->initiate();
}
protected function outputFooter()
{
require_once('path/to/themes/footer.php');
}
public function outputTemplate()
{
$this->outputHeader();
$this->outputSidebar();
$this->outputMainbody();
$this->outputFooter();
}
}
//index.php file code starts here--------
$myPhpApplication = new ApplicationTemplating();
$myPhpApplication->outputTemplate();
My goal is when I create instance of my application then It only call the single instance of "MyApplicationBase" class instead of calling it multiple times. Please do tell me how can I achieve this. I am google for 5 hours but unable to find any solution yet.
I am trying to develop an object oriented PHP application in which whole php application will be extending from MyApplicationBase base class.
As PHP has single inheritance, this is by far the most worst idea to do object oriented PHP programming.
But the problems is I want to create only single instance of MyApplicationBase.
As every class is a MyApplicationBase you actually don't want that because it would mean you could instantiate exactly one class in your whole application.
What you're probably looking for is some kind of ApplicationClass which you pass along and of which just a single instance exists.
This would at least allow you in the future to throw such a "block in road" away more easily then if you would have got extended from there.
In any case you should program against an ApplicationInterface instead of an ApplicationClass to make this throwing away - as it will be necessary - easier.
The best thing for sure would be to not do anything in that direction and only write code you need in the first place.
To only write code you need, you need to develop test-driven. Why not start with that if you want to do object oriented programming?
Well I suppose that you want to avoid multiple connections to the database in this case. Solution is simple with Dependency injection, just initialize your database connection outside of MyApplicationBase class and then pass it as a constructor parameter (beware of constuctor hell though). Like this:
class MyApplicationBase{
static $called=0;
public $db;
function __construct($db)
{
self::$called++;
echo "<pre>MyApplicationBase Created ".self::$called." times</pre>";
$this->db= $d;
}
}
$db = new DatabaseWrapper();
$templating = new ApplicationTemplating($db);
$security = new ApplicationSecurity($db);
You could also take a look at some framework, they usually come with some dependency injection capabilities.
I was wondering what is a good method to implement two similair API's into one PHP framework?
My thought was something like this:
/vendors/wrapperA.php - extends Parent, implements API (A)
/vendors/wrapperB.php - extends Parent, implements API (B)
Parent.php - the only script referenced directly to use the API wrapper
$config[] array for configuration in Parent.php
index.php - A website that implements and only references Parent.php
Let's say the API's have many methods, but we only implement two simple API calls:
connect() - creates a connection to the service.
put() - returns a "putID" if successful.
Since API (A) and API (B) differ, this is how the wrapper implements its utility, by abstracting these two methods.
Now, to my point:
What would be a good way to implement this in PHP?
the connect() statement would need to validate there is a valid connection.
the put() statement would need to return an ID
we don't want to expose the differences in the put methods, it just needs to work based on if we configured our API authentication correctly (whatever the case may be - via secret key or otherwise)
i.e.
Something like
<?php $parent = new Parent();
$parent->connect(); //connect to one or both API's.
$parent->put('foo'); //push foo to the API
?>
Currently, I have all of my code in Parent.php.
Issues with having all of the code in Parent.php
Code sprawl
Lack of modular plugins in case I add a 3rd API.
Code confusion - which API is which?
EDIT: Solution devised based on Marin's answer
<?php
/*** Interface ***/
interface API_Wrapper {
function connect();
function put($file);
}
/*** API Wrappers ***/
class API_A_Wrapper implements API_Wrapper {
function connect() {}
function put($file) { print 'putting to API A.'; }
}
class API_B_Wrapper implements API_Wrapper {
function connect() {}
function put($file) { print 'putting to API B.'; }
}
/*** Factory ***/
class Factory {
public static function create($type){
switch ($type) {
case "API_A" :
$obj = new API_A_Wrapper();
break;
case "API_B" :
$obj = new API_B_Wrapper();
break;
}
return $obj;
}
}
/*** Usage ***/
$wrapperA = Factory::create("API_A");
$wrapperA->put('foo');
$wrapperB = Factory::create("API_B");
$wrapperB->put('foo');
Use interface with relation and call it separately when you need it:
interface Interface {
function somefunction();
}
class Wrapper1 implements Relation {
public function connect() {
return;
}
}
class Wrapper2 {
public function action(Interface $s) {
$textData = $s->query();
return;
}
}
$p = new Wrapper1();
$i = new Wrapper2();
$i->action($p);
Using factory as relation:
function __autoload($class)
{
include_once($class . '.php');
}
class DBfactory
{
public static $pDB;
public static function factory($szType = "")
{
if(!is_object(self::$pDB))
{
switch($szType)
{
case 'mysql':
self::$pDB = new DBmysql;
break;
case 'mssql':
self::$pDB = new DBmssql;
break;
default:
self::$pDB = new DBmysql;
break;
}
}
return self::$pDB;
}
}
What you need is denpendency injection. You have 2 classes - you call them wrappers - which each covers a different API, but must conform to the same interface. In your web site, you wish to use either classes interchangeably, in effect using any underlying API without impacting the rest of the codebase, hence the common Parent interface.
However, at some point, your code will have to decide which wrapper will be used, and if you want to include new Parent implementations, you are afraid of having to manually include these new wrappers in your code base.
This problem is solved by dependency injection. The idea is to have a dedicated object - a Factory - encapsulate all the details of which wrappers are available, and any bit of code which require the wrapper of the moment may ask it to that factory. Clearly, your code will only have to deal with the factory and instance of the Parent interface.
For as to how the Factory decides which wrapper to instantiate is your choice to make. Many use a configuration file containing which class must be used with which part of the code. That can be implemented by using ids associated with wrapper clients (ie code using them) and clients would give the factory this id when requesting the wrapper. The factory then just look the id up and provide an ad-hoc instance.
I'm trying to understand how using interfaces gives me multiple inheritance as I've been googling.
class A
{
function do1(){}
function do2(){}
function do3(){}
}
class B extends A
{
function do4(){}
function do5(){}
function do6(){}
}
class C extends B
{
}
In the above example, class C has all the methods from class A and B. However, class B also has all the methods of class A, which is not necessary desired.
My searches have come up to use interfaces to solve this issue by moving methods to a class and creating interfaces, as below.
interface A
{
function do1();
function do2();
function do3();
}
interface B
{
function do4();
function do5();
function do6();
}
class C implements A, B
{
function do1(){}
function do2(){}
function do3(){}
function do4(){}
function do5(){}
function do6(){}
}
I don't really see how this solves the issue because all the code is in the new class. If I just wanted to use class A as originally, I would have to create a new class that implement interface A and copy the same code to the new class.
Is there something I'm missing?
PHP doesn't have multiple inheritance. If you have PHP 5.4, though, you can use traits to at least avoid every class having to copy code.
interface A {
public function do1();
public function do2();
public function do3();
}
trait Alike {
public function do1() { }
public function do2() { }
public function do3() { }
}
interface B {
public function do4();
public function do5();
public function do6();
}
trait Blike {
public function do4() { }
public function do5() { }
public function do6() { }
}
class C implements A, B {
use Alike, Blike;
}
class D implements A {
use Alike;
// You can even "override" methods defined in a trait
public function do2() { }
}
Note, though, you have to both implement the interface and use the trait (or, of course, provide your own implementation). And C and D are not related at all, except in both implementing the A interface. Traits are basically just interpreter-level copy and paste, and do not affect inheritance.
The first thing to understand about interfaces is that they are NOT used for inheritance. That is a very important thing to understand. If you're trying to make several classes share the same concrete code, that is not what an interface is for.
The second thing to understand is the difference between client code, and service code.
Client code is essentially the "last step" in a sequence of requests for data. A controller or a view in MVC can be considered client code. The model, meanwhile can be considered service code.
Interfaces are intended for client code to enforce consistency in the types of data it gets from services. Or another way to think about it - interfaces are a way for services to make sure they will be compatible with a request from client code. That is ALL they do. They quite literally provide an interface by which data is accessed, not an implementation that multiple classes can share.
So to give you a concrete example:
Client Code - a ProfileViewController class for a user's forum profile
class ProfileViewController
{
public function showProfile(User $user)
{
$user->getProfile();
}
}
Service Code - a User model that retrieves data and passes it on to the client code that is requesting it
class User
{
public function getProfile()
{
$profile = Do some SQL query here or something
return $profile;
}
}
Now suppose later on you decide to break up Users into Members, Administrators, Referees, Moderators, Writers, Editors etc, and that each has their own unique type of profile. (e.g. its own custom query, or data, or what have you)
There are now two problems present here:
You need to guarantee that whatever you pass in there will contain a getProfile() method.
showProfile() will fail if you pass in anything other than a User object.
1 is easy to solve through abstract classes and methods (or through Interfaces). 2 at first sounds easy as well, because you can just make Moderators, Admins, and Members all subclasses of a User base class.
But then what happens when down the road, in addition to USER profiles, you want to have generic profiles for things. Perhaps you want to show profiles of sports players, or even profiles of celebrities. They're not users, but they still have profiles/details pages.
Because they're not users, it may not make any sense to consider them subclasses of User.
So now you're a bit stuck. showProfile() needs to be able to accept more than just a User object. In fact, you don't know what type of object you will ultimately want to pass in there. But at the same time, since you always want to be able to grab $user->getProfile(), anything you pass in there must be generic enough to be passed in, AND implement a concrete getProfile() method.
Solution? Interfaces!!!!!
First some service code
// First define an interface for ANY service object that will have a profile
interface IHasProfile
{
public function getProfile();
}
// Next, define the class for an object that should have a profile. I'll do a bunch for the sake of an example...
class User implements IHasProfile
{
public function getProfile()
{
$profile = Your unique user profile query here
return $profile;
}
}
class Celebrity implements IHasProfile
{
public function getProfile()
{
$profile = Your unique celebrity profile query here
return $profile;
}
}
class Car implements IHasProfile
{
public function getProfile()
{
$profile = Your unique vehicle profile query goes here
return $profile;
}
}
Next, the client code that will use it
class ProfileViewController
{
public function showProfile(IHasProfile $obj)
{
$obj->getProfile();
}
}
And there you have it. showProfile() has now been abstracted enough that it doesn't care what object it gets, it only cares that the object has a public getProfile() method. So now you can create new types of objects to your heart's content, and if they are intended to have profiles, you can just give them "implements IHasProfile" and they will automatically just work with showProfile().
Kind of a contrived example, but it should illustrate at least the concept of interfaces.
Of course, you could just be "lazy" and not typecast the object at all, and thus allowing ANY object to be passed in. But that's a separate topic entirely ;)
Multiple inheritance is possible only for Interfaces!
such as my output for it:
php > interface A{};
php > interface B{};
php > interface C extends A,B{};
php > class D implements C{};
php > $d = new D();
php > echo ($d instanceof A);
1
I created A and B interfaces and C interface extends them.
After we have D class which implements C interface
Finally, I ask if $d object is instanceof A interface, yeah it's true
For the lulz, I try to create E class which extends D and stdclass classes and get error!
php > class E extends D, stdclass{};
PHP Parse error: syntax error, unexpected ',', expecting '{' in php shell code on line 1
Parse error: syntax error, unexpected ',', expecting '{' in php shell code on line 1
Multiple inheritance is not possible in PHP like in many OOP supported languages
See similar topic here. The topic is in AS3 but gives you answer.
To answer particularly about solving using interfaces is answered in the same post here
As told here by #tonicospinelli, it seems that indeed, PHP allows multiple inheritance of interfaces, but it isn't clearly explained, just given an example
The way multiple inheritance works, PHP passes these using Traits that implement Interfaces.
Once you declare a Class implementing a "multi-interface" (1), you may use already defined Traits to assure inheritance is well-performed.
(1): Saying "multi-interface" I mean a class implementing an interface what extends from multiple other interfaces