Advice regarding object oriented design and wrapper methods - php

I have a State class that includes configuration as well as some state-specific methods. I also have a Factory class that I inhertit my MVC classes from that also has a reference to this State object. This makes sure that all of my MVC objects have specific State-related functionality. For example, my State class includes methods for setting and reading cache or sessions.
My Factory class has a number of methods that are simply wrappers, like this:
public function myFunction($data){
$this->State->myFunction($data);
}
The idea is that these methods are defined in Factory, but are actually executed by State object. This allows me to call:
$this->myFunction(); rather than the longer one that includes State in it, when writing code.
I don't know enough about how PHP works internally, but is this efficient? My thought process has been that since I usually only have one instance of State object, then having method wrappers in my Factory class is better, because otherwise those methods would include a lot of code that is not used most of the time. But I am not sure how PHP works internally.
At times I can have dozen objects that have the parent Factory class and all of them reference the same State object. Is it efficient to have wrapper methods defined in Factory that simply call methods of State, rather than deal with State directly? Or am I just adding additional overhead to the whole system?
My idea was that if Factory is simply a class that is inherited and includes wrappers for a lot of functionality, then I can streamline development more efficiently. Does it save memory if the class that you inherit from has wrappers as opposed to fully defined code in methods?

No, such wrapper has not performance benefit. Actually, what you get this was is an extremely minor loss of performance.
What's more important, this way you are hiding dependencies, which might make it harder to maintain the code.
Few thoughts on your topic
I get the impression, that you are doing it all wrong tm. Here are the issues, that I have with what you wrote in the question:
Is the State class responsible for configuration OR "state specific methods"?
There is such thing as SRP, which states, that every class should have a single responsibility. You could also say, that every class should have only one season to change.
Why do your "MVC classes" inherit from Factory class?
In object oriented code, the keyword extends represents an is-a relationship between classes. It's OK to have class Oak extends Tree, but when you write class User extends Table, it is complete insanity .. and kinda insulting. This is covered by LSP (for a simplified explanation: look here).
You have misunderstood the purpose of Factory pattern.
Factory is a creational pattern. This means, that the purpose of factories is to return object instances. Instead of inheriting some methods, which provide access to State instance, you should inject it in each of created structure.
class Factory
{
protected $state = null;
public function __construct( $state )
{
$this->state = $state;
}
public function create( $name )
{
$instance = new $name( $this->state );
return $instance;
}
}
This will have the added benefit that all the structures, which Factory instance created, share the same State instance.
Seems like you are trying to have global state thought-out your codebase
If every in your application need access to instance of State, then something is deeply wrong with the whole architecture. You end up with situation where a single object exists in all layers, thus causing a major leak in abstractions. You basically are just hiding a global variable.

Related

Why doesn't Eloquent\Builder inherit from Query\Builder in laravel?

In laravel, the Eloquent\Builder class sends every call to methods which it doesn't have to an internal Query\Builder. To me this sounds like inheritance. Somebody knows why they didn't implement it so that the Eloquent\Builder extends Query\Builder? The reason I first noticed it was that I got "Call to undefined method" errors in IDEs, despite the code working fine which is the curse of magic methods I suppose.
For reference, here is relevant source from Eloquent\Builder.
/**
* The base query builder instance.
*
* #var \Illuminate\Database\Query\Builder
*/
protected $query;
protected $passthru = array(
'toSql', 'lists', 'insert', 'insertGetId', 'pluck', 'count',
'min', 'max', 'avg', 'sum', 'exists', 'getBindings',
);
public function __call($method, $parameters)
{
if (method_exists($this->model, $scope = 'scope'.ucfirst($method)))
{
return $this->callScope($scope, $parameters);
}
else
{
$result = call_user_func_array(array($this->query, $method), $parameters);
}
return in_array($method, $this->passthru) ? $result : $this;
}
I'll start off with my conclusion. I think it was just poorly engineered.
Let me do a few explanations, and also reply to the accepted answer by #Simon Bengtsson
I'm by no means trying to offend anyone, but I'm just trying to word out my thoughts.
Actually the whole point of inheritance is that they have similar characteristics, but you would like to add an extra layer to put some extended features. Obviously, the extended "child" class will know more than the "parent" class (such as knowing about the Eloquent Model)
To me, a "Builder" is a Builder. Afterall, both are actually building a query, regardless of what conditions its checking or observing. That's the purpose of a Builder (from what I see at least). So it's in the same layer (except Eloquent\Builder has some extra features).
The current implementation is overriding the nature of a few methods such as where() (which are basically those in Query\Builder, same name, same arguments). It's also adding a few methods, which eventually calls methods like where(). This is all about inheritance. If I call where(), and it exists in child class, the child class method gets called. If not, it will call the method in parent class.
Later down the line it becomes more difficult to then decouple the low level and ORM level components if you hypothetically wanted to use some new NoSQL DB instead
and simply write a Query\Builder signature compliant drop-in class.
#Simon Bengtsson
I don't see how it gets difficult to decouple. All you have to do, is to write a new class Query\MongoDBBuilder, which has the same interface as Query\Builder. If you're worried, you can always make the classes "implements" an Interface. If you ask me, actually the current way is harder to decouple, because it's quite messy right now as to "which features are overridden and which are not".
I do encourage class decoupling in some cases, but if I were to decouple this one (which I don't think is necessary here), I would do it this way:
Eloquent\Model
Eloquent\Adapter (This is some sort of intermediate layer, where you could put connection settings etc.)
Eloquent\Builder extends Query\Builder (This is a "wrapper" for Query\Builder so that it could do slightly more, but achieving the same goals)
Child classes also have access to protected properties on parent classes so that Eloquent\ChildOfQueryBuilder would have the freedom to rely on the low level implementation
of Query\Builder and could be coupled to it.
#Simon Bengtsson
This is the whole point about inheritance. You would to be able to access protected properties to override a feature given by the parent. Let's look at it from another point of view, what if you NEED to access these variables in order to modify the feature? In fact, the author declaring these members "protected" already implies that he is ready for another class to extend it. That's the only purpose of making it "protected", correct?
That's why you would have to know exactly what a parent class is doing before inheriting it, because it could be dangerous.
The reason why I'm giving this huge explanation is because I'm trying to modify some features for Eloquent. I've been looking at the implementation of days (the 3 god classes: Eloquent\Model, Eloquent\Builder, and Query\Builder). The layering and aliasing was really messed up. Extending the Model class requires me to redeclare almost equivalent functions due to its poor implementation. But that's off topic.
In conclusion, if you ask "why", I would actually say (now I know people will kick me) that it was just poorly engineered and implemented.
I think delmadord was sort of heading towards the right answer but I think bringing the IoC into it blurs the issue. The basic answer is that the two classes represent abstractions of the database at different levels. Query\Builder is the lower level abstraction and Eloquent\Builder is a higher level abstraction which is why, as you pointed out it makes use of Query\Builder for its core functionality.
You can tell this from the properties that are defined for each class. One has properties surrounding things such as:
connection settings,
database grammars and,
various things relating to the query that will be assembled
The other is more an ORM and is concerned with higher level concerns such as whether eager relationship loading should be used and which model the query is currently bound to. Arguably, you could use inheritance here and might have pretty much the same functionality but from an architectural standpoint there are issues with this.
One is that, strictly speaking, I should always be able to use a child class as a drop in replacement for a parent class. This is simpler to see if you adopt the "is a" reading of inheritance. This means that if you used inheritance for this pair of classes, strictly speaking, any developer down the line is able to make use of Eloquent\Builder just as easily as Query\Builder and in fact might be encouraged to do so throughout the code in order to have one less class to track in their minds. This will mean code may call $builder->getRelation() and rely on the consequences on (for argument's sake) $builder->wheres all in the same block of code.
Later down the line it becomes more difficult to then decouple the low level and ORM level components if you hypothetically wanted to use some new NoSQL DB instead and simply write a Query\Builder signature compliant drop-in class.
Child classes also have access to protected properties on parent classes so that Eloquent\ChildOfQueryBuilder would have the freedom to rely on the low level implementation of Query\Builder and could be coupled to it. You could argue that you could just make it private but then you can longer write a thin low-level extension to Query\Builder (adding some clustering, sharding or security logic maybe) that may (rightfully) need access to the implementation details that could have been a drop-in replacement for the low-level functionality.
Another is that the size of the class grows quite rapidly if you pile everything related into one "God object". Both of the Builder classes have a large amount of abstraction layer specific logic within them. If you inherit, then Eloquent\Builder would effectively be the union of the two and you would have almost twice as much code to scan for issues and your IDE would give you a much broader range of autocompletion options, with a significant fraction being unrelated to the abstraction depth you're working at.
The same pattern is used sometimes in other places where two classes are very related to each other, but inheritance would cause perception issues which would encourage their use in ways the developer does not want. With Java for example, immutable classes typically have mutable counterparts but neither inherits the other and they might not even have common ancestry.
This happens because the immutable class can't have any mutator methods. Inheriting from the mutable version would require overriding and disabling each mutator method and forever ensuring this happens correctly. Forget this once and your immutable class may be mutable for a few revisions. And you can't allow inheritance the other way around because doing so means a method expecting an immutable class might get a mutable child and add grey hairs to people.
This is another instance of related things playing distinct roles and thus being conceptually separated. Its not that you can't do things a particular way but more that certain architecture choices discourage behaviours you don't want and leave room to do things that you do think you'll want to do down the line. Sometimes with very large code-bases, decoupling things along an interface like that really helps to make it easier to reason about and work with.
If you look at the source of Illuminate/Database/Eloquent/Builder
<?php namespace Illuminate\Database\Eloquent;
use Closure;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Builder as QueryBuilder;
class Builder {
/**
* The base query builder instance.
*
* #var \Illuminate\Database\Query\Builder
*/
protected $query;
You can see, that it is using the instance of the Illuminate\Database\Query\Builder. It is not extending the class, probably for make use of the IoC in Laravel. Inject the instance and it get pulled everything needed.

Understanding IoC Containers and Dependency Injection

My understanding:
A dependency is when an instance of ClassA requires an instance of ClassB to instantiate a new instance of ClassA.
A dependency injection is when ClassA is passed an instance of ClassB, either through a parameter in ClassA's constructor or through a set~DependencyNameHere~(~DependencyNameHere~ $param) function. (This is one of the areas I'm not completely certain on).
An IoC container is a singleton Class(can only have 1 instance instantiated at any given time) where the specific way of instantiating objects of those class for this project can be registered. Here's a link to an example of what I'm trying to describe along with the class definition for the IoC container I've been using
So at this point is where I start trying use the IoC container for more complicated scenarios. As of now it seems in order to use the IoC container, I am limited to a has-a relationship for pretty much any class I want to create that has dependencies it wants to define in the IoC container. What if I want to create a class that inherits a class, but only if the parent class has been created in a specific way it was registered in the IoC container.
So for example: I want to create a child class of mysqli, but I want to register this class in the IoC container to only instantiate with the parent class constructed in a way I've previously registered in the IoC container. I cannot think of a way to do this without duplicating code (and since this is a learning project I'm trying to keep it as 'pure' as possible). Here are some more examples of what I am trying to describe.
So here are some of my questions:
Is what I'm trying to do above possible without breaking some principle of OOP? I know in c++ I could use dynamic memory and a copy constructor to accomplish it, but I haven't been able to find that sort of functionality in php. (I will admit that I have very little experience using any of the other magic methods besides __construct, but from reading and __clone if I understood correctly, I couldn't use in the constructor it to make the child class being instantiated a clone of an instance of the parent class).
Where should all my dependency class definitions go in relation to the IoC? (Should my IoC.php just have a bunch of require_once('dependencyClassDefinition.php') at the top? My gut reaction is that there is a better way, but I haven't come up with one yet)
What file should I be registering my objects in? Currently doing all the calls to IoC::register() in the IoC.php file after the class definition.
Do I need to register a dependency in the IoC before I register a class that needs that dependency? Since I'm not invoking the anonymous function until I actually instantiate an object registered in the IoC, I'm guessing not, but its still a concern.
Is there anything else I'm overlooking that I should be doing or using? I'm trying to take it one step at a time, but I also don't want to know that my code will be reusable and, most importantly, that somebody who knows nothing about my project can read it and understand it.
Put simply (because it's not a problem limited to OOP world only), a dependency is a situation where component A needs (depends on) component B to do the stuff it's supposed to do. The word is also used to describe the depended-on component in this scenario. To put this in OOP/PHP terms, consider the following example with the obligatory car analogy:
class Car {
public function start() {
$engine = new Engine();
$engine->vroom();
}
}
Car depends on Engine. Engine is Car's dependency. This piece of code is pretty bad though, because:
the dependency is implicit; you don't know it's there until you inspect the Car's code
the classes are tightly coupled; you can't substitute the Engine with MockEngine for testing purposes or TurboEngine that extends the original one without modifying the Car.
It looks kind of silly for a car to be able to build an engine for itself, doesn't it?
Dependency injection is a way of solving all these problems by making the fact that Car needs Engine explicit and explicitly providing it with one:
class Car {
protected $engine;
public function __construct(Engine $engine) {
$this->engine = $engine;
}
public function start() {
$this->engine->vroom();
}
}
$engine = new SuperDuperTurboEnginePlus(); // a subclass of Engine
$car = new Car($engine);
The above is an example of constructor injection, in which the dependency (the depended-on object) is provided to the dependent (consumer) through the class constructor. Another way would be exposing a setEngine method in the Car class and using it to inject an instance of Engine. This is known as setter injection and is useful mostly for dependencies that are supposed to be swapped at run-time.
Any non-trivial project consists of a bunch of interdependent components and it gets easy to lose track on what gets injected where pretty quickly. A dependency injection container is an object that knows how to instantiate and configure other objects, knows what their relationship with other objects in the project are and does the dependency injection for you. This lets you centralize the management of all your project's (inter)dependencies and, more importantly, makes it possible to change/mock one or more of them without having to edit a bunch of places in your code.
Let's ditch the car analogy and look at what OP's trying to achieve as an example. Let's say we have a Database object depending on mysqli object. Let's say we want to use a really primitive dependency indection container class DIC that exposes two methods: register($name, $callback) to register a way of creating an object under the given name and resolve($name) to get the object from that name. Our container setup would look something like this:
$dic = new DIC();
$dic->register('mysqli', function() {
return new mysqli('somehost','username','password');
});
$dic->register('database', function() use($dic) {
return new Database($dic->resolve('mysqli'));
});
Notice we're telling our container to grab an instance of mysqli from itself to assemble an instance of Database. Then to get a Database instance with its dependency automatically injected, we would simply:
$database = $dic->resolve('database');
That's the gist of it. A somewhat more sophisticated but still relatively simple and easy to grasp PHP DI/IoC container is Pimple. Check its documentation for more examples.
Regarding OP's code and questions:
Don't use static class or a singleton for your container (or for anything else for that matter); they're both evil. Check out Pimple instead.
Decide whether you want your mysqliWrapper class extend mysql or depend on it.
By calling IoC from within mysqliWrapper you're swapping one dependency for another. Your objects shouldn't be aware of or use the container; otherwise it's not DIC anymore it's Service Locator (anti)pattern.
You don't need to require a class file before registering it in the container since you don't know if you're going to use an object of that class at all. Do all your container setup in one place. If you don't use an autoloader, you can require inside the anonymous function you register with the container.
Additional resources:
Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler
Don't look for things -- a Clean Code Talk about IoC/DI

Common object shared across many other classes

I am currently refactoring an application into multiple classes in an attempt to fulfill Single Responsibility Principle; however, many methods in the original mammoth classes use one common "metadata" object (bound as a class property) for their business logic.
For example:
if($this->metadata->applyTracking) {
// perform tracking logic
}
When I am separating these classes out, I am considering two options:
Passing this object to particular methods of the class, on case by case basis (Can be many occurences).
Adding this object as class properties (Many classes will have this property injected).
Making the object as a Singleton (I am wary of this approach since it may share the same fallbacks as globals)
Any advice on which path to take?
Method #2 seems to be best. I would inject an object repository, in which each member of the repository would be a different object that provides a different service. An example class can be found here: https://github.com/kenaniah/insight/blob/master/classes/registry.php
If you have inheritance in your code you may consider assigning it as a member in base classes and exposing the instance as a protected variable.
The Singleton really is more about whether or not the class is supposed to have only one instance in memory at a time, or if you will be instantiating the class many times.
It's hard to say for sure without knowing more about the how the object is being used, but I would probably suggest having a base class which defines the needed properties and then just inheriting that base class in any subsequent classes which need access to those properties.
quickshiftin just beat me to the punch though, haha.

Why people use singletons in their PHP framework

Ok guys I am struggling to understand why there is a need of singleton.
Let's make a real example: I have a framework for a my CMS
I need to have a class that logs some information (let's stick on PHP).
Example:
class Logger{
private $logs = array();
public function add($log) {
$this->logs[]=$log;
}
}
Now of course this helper object must be unique for the entry life of a page request of my CMS.
And to solve this we would make it a singleton (declaring private the constructor etc.)
But Why in the hell a class like that isn't entirerly static? This would solve the need of the singleton pattern (that's considered bad pratice) Example:
class Logger {
private static $logs = array();
public static function add($log) {
self::$logs[]=$log;
}
}
By making this helper entirely static, when we need to add a log somewhere in our application we just need to call it statically like: Logger::add('log 1'); vs a singleton call like: Logger::getInstance()->add('log 1');
Hope someone makes it easy to understand for me why use singleton over static class in PHP.
Edit
This is a pretty nice lecture on the singleton vs static class for who is interested, thanks to #James. (Note it doesn't address my question)
Many reasons.
Static methods are basically global functions that can be called from any scope, which lends itself to hard to track bugs. You might as well not use a class at all.
Since you cannot have a __construct method, you may have to put an init static method somewhere. Now people in their code are unsure if the init method has been called previously. Do they call it again? Do they have to search the codebase for this call? What if init was somewhere, but then gets removed, or breaks? Many places in your code now rely on the place that calls the init method.
Static methods are notoriously hard to unit test with many unit testing frameworks.
There are many more reasons, but it's hard to list them all.
Singletons aren't really needed either if you are using DI.
A side note. DI allows for your classes not to rely on each other, but rather on interfaces. Since their relationships are not cemented, it is easier to change your application at a later time, and one class breaking will not break both classes.
There are some instances where single state classes are viable, for instance if none of your methods rely on other methods (basically none of the methods change the state of the class).
I use singletons, so I can tell you exactly why I do it instead of a static function.
The defining characteristic of a singleton is that it is a class that has just one instance. It is easy to see the "just one instance" clause and forget to see the "it is a class" clause. It is, after all, a normal class object with all the advantages that that brings. Principly, it has its own state and it can have private functions (methods). Static functions have to do both of these in more limited or awkward ways.
That said, the two complement each other: a static function can be leveraged to return a singleton on the same class. That's what I do in the singleton I use the most often: a database handler.
Now, many programmers are taught that "singletons are bad, mm'kay?" but overlook the rider that things like are usually only bad when overused. Just like a master carver, an experienced programmer has a lot of tools at his disposal and many will not get a lot of use. My database handler is ideal as a singleton, but it's the only one I routinely use. For a logging class, I usually use static methods.
Singletons allow you to override behavior. Logger::add('1') for example can log to different devices only if the Logger class knows how. Logger::getLogger()->add('1') can do different things depending on what subtype of Logger getLogger() returns.
Sure you can do everything within the logger class, but often you then end up implementing the singleton inside the static class.
If you have a static method that opens a file, writes out and closes it, you may end up with two calls trying to open the same file at the same time, as a static method doesn't guarantee there is one instance.
But, if you use a singleton, then all calls use the same file handler, so you are always only having one write at a time to this file.
You may end up wanting to queue up the write requests, in case there are several, if you don't want them to fail, or you have to synchronize in other ways, but all calls will use the same instance.
UPDATE:
This may be helpful, a comparison on static versus singleton, in PHP.
http://moisadoru.wordpress.com/2010/03/02/static-call-versus-singleton-call-in-php/
As leblonk mentioned, you can't override static classes, which makes unit testing very difficult. With a singleton, you can instantiate a "mock" object instead of the actual class. No code changes needed.
Static classes can have namespace conflicts. You can't load 2 static classes of the same name, but you can load 2 different versions of a singleton and instantiate them under the same name. I've done this when I needed to test new versions of classes. I instantiate a different version of the class, but don't need to change the code that references that class.
I often mix singletons and static. For example, I use a database class that ensures there is only 1 connection to each master (static) and slave (singleton). Each instance of the db class can connect to a different slave, if a connection to the same slave is requested, the singleton object is returned. The master connection is a static object instantiated inside each slave singleton, so only 1 master connection exists across all db instantiated objects.

What is the point of interfaces in PHP?

Interfaces allow you to create code which defines the methods of classes that implement it. You cannot however add any code to those methods.
Abstract classes allow you to do the same thing, along with adding code to the method.
Now if you can achieve the same goal with abstract classes, why do we even need the concept of interfaces?
I've been told that it has to do with OO theory from C++ to Java, which is what PHP's OO stuff is based on. Is the concept useful in Java but not in PHP? Is it just a way to keep from having placeholders littered in the abstract class? Am I missing something?
The entire point of interfaces is to give you the flexibility to have your class be forced to implement multiple interfaces, but still not allow multiple inheritance. The issues with inheriting from multiple classes are many and varied and the wikipedia page on it sums them up pretty well.
Interfaces are a compromise. Most of the problems with multiple inheritance don't apply to abstract base classes, so most modern languages these days disable multiple inheritance yet call abstract base classes interfaces and allows a class to "implement" as many of those as they want.
The concept is useful all around in object oriented programming. To me I think of an interface as a contract. So long my class and your class agree on this method signature contract we can "interface". As for abstract classes those I see as more of base classes that stub out some methods and I need to fill in the details.
Why would you need an interface, if there are already abstract classes?
To prevent multiple inheritance (can cause multiple known problems).
One of such problems:
The "diamond problem" (sometimes referred to as the "deadly diamond of
death") is an ambiguity that arises when two classes B and C inherit
from A and class D inherits from both B and C. If there is a method
in A that B and C have overridden, and D does not override it, then
which version of the method does D inherit: that of B, or that of C?
Source: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem
Why/When to use an interface?
An example... All cars in the world have the same interface (methods)... AccelerationPedalIsOnTheRight(), BrakePedalISOnTheLeft(). Imagine that each car brand would have these "methods" different from another brand. BMW would have The brakes on the right side, and Honda would have brakes on the left side of the wheel. People would have to learn how these "methods" work every time they would buy a different brand of car. That's why it's a good idea to have the same interface in multiple "places."
What does an interface do for you (why would someone even use one)?
An interface prevents you from making "mistakes" (it assures you that all classes which implement a specific interface, will all have the methods which are in the interface).
// Methods inside this interface must be implemented in all classes which implement this interface.
interface IPersonService
{
public function Create($personObject);
}
class MySqlPerson implements IPersonService
{
public function Create($personObject)
{
// Create a new person in MySql database.
}
}
class MongoPerson implements IPersonService
{
public function Create($personObject)
{
// Mongo database creates a new person differently then MySQL does. But the code outside of this method doesn't care how a person will be added to the database, all it has to know is that the method Create() has 1 parameter (the person object).
}
}
This way, the Create() method will always be used the same way. It doesn't matter if we are using the MySqlPerson class or the MongoPerson class. The way how we are using a method stays the same (the interface stays the same).
For example, it will be used like this (everywhere in our code):
new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);
This way, something like this can't happen:
new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);
It's much easier to remember one interface and use the same one everywhere, than multiple different ones.
This way, the inside of the Create() method can be different for different classes, without affecting the "outside" code, which calls this method. All the outside code has to know is that the method Create() has 1 parameter ($personObject), because that's how the outside code will use/call the method. The outside code doesn't care what's happening inside the method; it only has to know how to use/call it.
You can do this without an interface as well, but if you use an interface, it's "safer" (because it prevents you to make mistakes). The interface assures you that the method Create() will have the same signature (same types and a same number of parameters) in all classes that implement the interface. This way you can be sure that ANY class which implements the IPersonService interface, will have the method Create() (in this example) and will need only 1 parameter ($personObject) to get called/used.
A class that implements an interface must implement all methods, which the interface does/has.
I hope that I didn't repeat myself too much.
The difference between using an interface and an abstract class has more to do with code organization for me, than enforcement by the language itself. I use them a lot when preparing code for other developers to work with so that they stay within the intended design patterns. Interfaces are a kind of "design by contract" whereby your code is agreeing to respond to a prescribed set of API calls that may be coming from code you do not have aceess to.
While inheritance from abstract class is a "is a" relation, that isn't always what you want, and implementing an interface is more of a "acts like a" relation. This difference can be quite significant in certain contexts.
For example, let us say you have an abstract class Account from which many other classes extend (types of accounts and so forth). It has a particular set of methods that are only applicable to that type group. However, some of these account subclasses implement Versionable, or Listable, or Editable so that they can be thrown into controllers that expect to use those APIs. The controller does not care what type of object it is
By contrast, I can also create an object that does not extend from Account, say a User abstract class, and still implement Listable and Editable, but not Versionable, which doesn't make sense here.
In this way, I am saying that FooUser subclass is NOT an account, but DOES act like an Editable object. Likewise BarAccount extends from Account, but is not a User subclass, but implements Editable, Listable and also Versionable.
Adding all of these APIs for Editable, Listable and Versionable into the abstract classes itself would not only be cluttered and ugly, but would either duplicate the common interfaces in Account and User, or force my User object to implement Versionable, probably just to throw an exception.
Interfaces are essentially a blueprint for what you can create. They define what methods a class must have, but you can create extra methods outside of those limitations.
I'm not sure what you mean by not being able to add code to methods - because you can. Are you applying the interface to an abstract class or the class that extends it?
A method in the interface applied to the abstract class will need to be implemented in that abstract class. However apply that interface to the extending class and the method only needs implementing in the extending class. I could be wrong here - I don't use interfaces as often as I could/should.
I've always thought of interfaces as a pattern for external developers or an extra ruleset to ensure things are correct.
You will use interfaces in PHP:
To hide implementation - establish an access protocol to a class of objects an change the underlying implementation without refactoring in all the places you've used that objects
To check type - as in making sure that a parameter has a specific type $object instanceof MyInterface
To enforce parameter checking at runtime
To implement multiple behaviours into a single class (build complex types)
class Car implements EngineInterface, BodyInterface, SteeringInterface {
so that a Car object ca now start(), stop() (EngineInterface) or goRight(),goLeft() (Steering interface)
and other things I cannot think of right now
Number 4 it's probably the most obvious use case that you cannot address with abstract classes.
From Thinking in Java:
An interface says, “This is what all classes that implement this particular interface will look like.” Thus, any code that uses a particular interface knows what methods can be called for that interface, and that’s all. So the interface is used to establish a “protocol” between classes.
Interfaces exist not as a base on which classes can extend but as a map of required functions.
The following is an example of using an interface where an abstract class does not fit:
Lets say I have a calendar application that allows users to import calendar data from external sources. I would write classes to handle importing each type of data source (ical, rss, atom, json) Each of those classes would implement a common interface that would ensure they all have the common public methods that my application needs to get the data.
<?php
interface ImportableFeed
{
public function getEvents();
}
Then when a user adds a new feed I can identify the type of feed it is and use the class developed for that type to import the data. Each class written to import data for a specific feed would have completely different code, there may otherwise be very few similarities between the classes outside of the fact that they are required to implement the interface that allows my application to consume them. If I were to use an abstract class, I could very easily ignore the fact that I have not overridden the getEvents() method which would then break my application in this instance whereas using an interface would not let my app run if ANY of the methods defined in the interface do not exist in the class that implemented it. My app doesn't have to care what class it uses to get data from a feed, only that the methods it needs to get that data are present.
To take this a step further, the interface proves to be extremely useful when I come back to my calendar app with the intent of adding another feed type. Using the ImportableFeed interface means I can continue adding more classes that import different feed types by simply adding new classes that implement this interface. This allows me to add tons of functionality without having to add unnecessarily bulk to my core application since my core application only relies on there being the public methods available that the interface requires so as long as my new feed import classes implement the ImportableFeed interface then I know I can just drop it in place and keep moving.
This is just a very simple start. I can then create another interface that all my calendar classes can be required to implement that offers more functionality specific to the feed type the class handles. Another good example would be a method to verify the feed type, etc.
This goes beyond the question but since I used the example above:
Interfaces come with their own set of issues if used in this manner. I find myself needing to ensure the output that is returned from the methods implemented to match the interface and to achieve this I use an IDE that reads PHPDoc blocks and add the return type as a type hint in a PHPDoc block of the interface which will then translate to the concrete class that implements it. My classes that consume the data output from the classes that implement this interface will then at the very least know it's expecting an array returned in this example:
<?php
interface ImportableFeed
{
/**
* #return array
*/
public function getEvents();
}
There isn't much room in which to compare abstract classes and interfaces. Interfaces are simply maps that when implemented require the class to have a set of public interfaces.
Interfaces aren't just for making sure developers implement certain methods. The idea is that because these classes are guaranteed to have certain methods, you can use these methods even if you don't know the class's actual type. Example:
interface Readable {
String read();
}
List<Readable> readables; // dunno what these actually are, but we know they have read();
for(Readable reader : readables)
System.out.println(reader.read());
In many cases, it doesn't make sense to provide a base class, abstract or not, because the implementations vary wildly and don't share anything in common besides a few methods.
Dynamically typed languages have the notion of "duck-typing" where you don't need interfaces; you are free to assume that the object has the method that you're calling on it. This works around the problem in statically typed languages where your object has some method (in my example, read()), but doesn't implement the interface.
In my opinion, interfaces should be preferred over non-functional abstract classes. I wouldn't be surprised if there would be even a performance hit there, as there is only one object instantiated, instead of parsing two, combining them (although, I can't be sure, I'm not familiar with the inner workings of OOP PHP).
It is true that interfaces are less useful/meaningful than compared to, say, Java. On the other hand, PHP6 will introduce even more type hinting, including type hinting for return values. This should add some value to PHP interfaces.
tl;dr: interfaces defines a list of methods that need to be followed (think API), while an abstract class gives some basic/common functionality, which the subclasses refine to specific needs.
I can't remember if PHP is different in this respect, but in Java, you can implement multiple Interfaces, but you can't inherit multiple abstract classes. I'd assume PHP works the same way.
In PHP you can apply multiple interfaces by seperating them with a comma (I think, I don't find that a clean soloution).
As for multiple abstract classes you could have multiple abstracts extending each other (again, I'm not totally sure about that but I think I've seen that somewhere before). The only thing you can't extend is a final class.
Interfaces will not give your code any performance boosts or anything like that, but they can go a long way toward making it maintainable. It is true that an abstract class (or even a non-abstract class) can be used to establish an interface to your code, but proper interfaces (the ones you define with the keyword and that only contain method signatures) are just plain easier to sort through and read.
That being said, I tend to use discretion when deciding whether or not to use an interface over a class. Sometimes I want default method implementations, or variables that will be common to all subclasses.
Of course, the point about multiple-interface implementation is a sound one, too. If you have a class that implements multiple interfaces, you can use an object of that class as different types in the same application.
The fact that your question is about PHP, though, makes things a bit more interesting. Typing to interfaces is still not incredibly necessary in PHP, where you can pretty much feed anything to any method, regardless of its type. You can statically type method parameters, but some of that is broken (String, I believe, causes some hiccups). Couple this with the fact that you can't type most other references, and there isn't much value in trying to force static typing in PHP (at this point). And because of that, the value of interfaces in PHP, at this point is far less than it is in more strongly-typed languages. They have the benefit of readability, but little else. Multiple-implementation isn't even beneficial, because you still have to declare the methods and give them bodies within the implementor.
Interfaces are like your genes.
Abstract classes are like your actual parents.
Their purposes are hereditary, but in the case of abstract classes vs interfaces, what is inherited is more specific.
I don't know about other languages, what is the concept of interface there. But for PHP, I will try my best to explain it. Just be patient, and Please comment if this helped.
An interface works as a "contracts", specifying what a set of subclasses does, but not how they do it.
The Rule
An Interface can't be instantiate.
You can't implement any method in an interface,i.e. it only contains .signature of the method but not details(body).
Interfaces can contain methods and/or constants, but no attributes. Interface constants have the same restrictions as class constants. Interface methods are implicitly abstract.
Interfaces must not declare constructors or destructors, since these are implementation details on the class
level.
All the methods in an interface must have public visibility.
Now let's take an example.
Suppose we have two toys: one is a Dog, and other one is a Cat.
As we know a dog barks, and cat mews.These two have same speak method, but with different functionality or implementation.
Suppose we are giving the user a remote control that has a speak button.
When the user presses speak button, the toy have to speak it doesn't matter if it's Dog or a Cat.
This a good case to use an interface, not an abstract class because the implementations are different.
Why? Remember
If you need to support the child classes by adding some non-abstract method, you should use abstract classes. Otherwise, interfaces would be your choice.
Below are the points for PHP Interface
It is used to define required no of methods in class [if you want to load html then id and name is required so in this case interface include setID and setName].
Interface strictly force class to include all the methods define in it.
You can only define method in interface with public accessibility.
You can also extend interface like class. You can extend interface in php using extends keyword.
Extend multiple interface.
You can not implement 2 interfaces if both share function with same name. It will throw error.
Example code :
interface test{
public function A($i);
public function B($j = 20);
}
class xyz implements test{
public function A($a){
echo "CLASS A Value is ".$a;
}
public function B($b){
echo "CLASS B Value is ".$b;
}
}
$x = new xyz();
echo $x->A(11);
echo "<br/>";
echo $x->B(10);
We saw that abstract classes and interfaces are similar in that they provide abstract methods that must be implemented in the child classes. However, they still have the following differences:
1.Interfaces can include abstract methods and constants, but cannot contain concrete methods and variables.
2.All the methods in the interface must be in the public visibility
scope.
3.A class can implement more than one interface, while it can inherit
from only one abstract class.
interface abstract class
the code - abstract methods - abstract methods
- constants - constants
- concrete methods
- concrete variables
access modifiers
- public - public
- protected
- private
etc.
number of parents The same class can implement
more than 1 interface The child class can
inherit only from 1 abstract class
Hope this will helps to anyone to understand!

Categories