How to automatically bind implementations in PHP? - php

So I am a laravel developer and even though I have worked with it for a while now, and I love how the magic happens beneath the surface, how it automatically binds implementations when instantiating classes via the IoC container, right now I am trying to go to the basics of design patters and learn how things actually work.
So I started with the Animal example:
abstract class Animal
{
abstract function makeSound();
}
class Dog extends Animal
{
public function makeSound()
{
echo "Bark!\n";
}
}
class Cat extends Animal
{
public function makeSound()
{
echo "Bark!\n";
}
}
So I am reading Head First Design Patterns and I am trying to make the most of the book. At this point every time I create a new Animal, I will have to implement the make sound method which will differ in most cases.
So the book tells me that I should code a Soundable interface and then have implementations of that interface in the Animal extended classes.
I finally came up with something like this:
interface Soundable
{
function sound();
}
class Bark implements Soundable
{
public function sound()
{
return "Bark!\n";
}
}
class Meow implements Soundable
{
public function sound()
{
return "Meow!\n";
}
}
class Animal
{
public $soundable;
public function __construct(Soundable $soundable)
{
$this->soundable = $soundable;
}
public function makeSound()
{
echo $this->soundable->sound();
}
}
class Dog extends Animal
{
}
class Cat extends Animal
{
}
function makeAnimal(Animal $animal){
return $animal;
}
// Making a dog
$animal = makeAnimal(new Dog(new Bark()));
$animal->makeSound();
// Making a cat
$animal = makeAnimal(new Cat(new Meow()));
$animal->makeSound();
So now when I have another animal that barks or meows, I can simple instantiate that implementation while making an animal.
Now my question is how do I tell PHP to automatically pass the new Bark() while instantiating the Dog class since it will bark and I don't want to write it every time I instantiate a new Dog object.
So how do I use a similar magic that Laravel uses to pass the Bark object automatically while instantiating Dog.
PS: I am still learning so I might be going in the wrong direction altogether while understanding these principles. Please guide me if you know better.

First of all, a small note: the book is wrong. The interface should be called Audible or Vocal. "Soundable" is not a real word an the author should be embarrassed. Also, calling a variable in the same name as an interface is kinda bad.
Another thing is: the Laravel's IoC is actually just a glorified service locator, so it wouldn't really help you here.
Usually, you would have two options:
use a factory (which in this particular case would painful and/or tricky)
use a dependency injection container - preferably a reflection-base one
I tend to recommend Auryn in these case. Though, if you are willing to jump few additional hoops and suffer through limited configuration, you can also use Symfony's DIC.
If you were using Auryn, initialization of your dog and cat would be just:
$injector = new Auryn\Injector;
$dog = $injector->make('Dog');
$cat = $injector->make('Cat');
The library would on its own look up the reflection of the constructor for Dog and detect that it will also need to create a new Bark instance.

You can create simply animal factory (sounds strange) with factory methods.
Factories
Factory classes are often implemented because they allow the project to follow the SOLID principles more closely. In particular, the interface segregation and dependency inversion principles.
For more information look here https://www.sitepoint.com/understanding-the-factory-method-design-pattern/
Just remember if you want to write down some unit test don't use static methods, just instantiate factory, there may be need in future to create factory with some dependencies.
<?php
class AnimalFactory
{
public function createDog() : Dog
{
return new Dog(new Bark());
}
}
$factory = new AnimalFactory();
$dog = $factory->createDog();

I think using IoC here would be good solution.
From Laravel Docs (Contextual binding)
Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class. For example, when our system receives a new Order, we may want to send an event via PubNub rather than Pusher. Laravel provides a simple, fluent interface for defining this behavior:
$this->app->when('App\Handlers\Commands\CreateOrderHandler')
->needs('App\Contracts\EventPusher')
->give('App\Services\PubNubEventPusher');
So your service provider in laravel could look like
public function register()
{
$this->app->when(Dog::class)->needs(Soundable::class)->give(Bark::class);
$this->app->when(Cat::class)->needs(Soundable::class)->give(Meow::class);
}
And then you could instantiate your class using Laravel's dependency injection containter
$dog = app()->make(Dog::class);
$dog->sound(); // Bark!
$cat = app()->make(Cat::class);
$cat->sound(); // Meow!
So summing it up, and relating to your question:
So how do I use a similar magic that Laravel uses to pass the Bark
object automatically while instantiating Dog.
Dependency Injection Container will suit your needs

I don't know laravel, but in my opinion your code should have been:
interface Soundable
{
function sound();
}
class Animal
{
protected name;
public function __construct($name) {
$this->name=name;
}
public function get_name() { return $this->name; }
}
class Dog extends Animal implements Soundable
{
public function sound()
{
return "Bark!\n";
}
}
class Cat extends Animal implements Soundable
{
public function sound()
{
return "Meow!\n";
}
}
// Making a dog
$animal = new Dog("Fido");
$animal->sound();
// Making a cat
$animal = new Cat("Fuffi");
$animal->sound();
echo $animal->get_name(); // print "Fuffi"
So, you can see that if you want only to implement the interface, you don't even need the Animal class. In fact, I have mantained it only to shot that it can still be useful in order to implement some method that can be useful to all descending classes (for example, get_name, that return the protected attribute "name").

Related

php use classes in specific environment [duplicate]

I want to implement next fragment of diagram, using PHP.
See composition example diagram below:
We can implement composition in Java using inner classes.
But there is no analog of "inner class" in PHP.
Of course, there are traits. But we can use it in more than one class.
I've implemented composition like this:
class Head {
private static $instance = NULL;
private function __construct(){}
public static function getInstance() {
$traces = debug_backtrace();
if (strcmp($traces[1]['class'], 'Human')) {
echo "<br>Only human has head"; // Exception can be thrown here
return NULL;
}
if (!static::$instance) static::$instance = new self();
return static::$instance;
}
public function __toString() {
return 'Head';
}
}
class Human {
private $head;
public function __construct() {
$this->head = Head::getInstance();
}
public function __toString() {
return 'I have ' . $this->head;
}
}
class Plant {
private $head;
public function __construct() {
$this->head = Head::getInstance();
}
}
$human = new Human();
echo $human;
$superman = new Plant();
Is it right to do so?
Is there better way to implement composition relationship in PHP?
It looks like you are really confused about what "composition" is in OOP.
Composition is an association between two classes, where , for an instance of first class to be instantiated, it is mandatory to provide it with second class. In you particular diagram for Human to exists, it requires a Head. In code it would be:
class Head {
}
class Human {
private $head;
public function __construct(Head $head) {
$this->head = $head;
}
}
$bob = new Human(new Head);
And that's it. No debug_backtrace() and no singleton anti-pattern required. And, btw, this would look almost exactly the same in Java too, even with the option to have inner classes.
As for your posted code. This would be wrong:
if (strcmp($traces[1]['class'], 'Human')) {
echo "<br>Only human has head"; // Exception can be thrown here
return NULL;
}
The diagram did not say that only humans have a head. Only that human must have a head to be instantiated. You can also have $skipper = new Dog(new Head);, which would be perfectly fine.
Composition over inheritance.
Basically composition is a stronger form of aggregation. We could say that relationship between body and head is composition because we can not live without head but relationship between body and a hand is aggregation because we could lose our hand but we can stay alive. There are also weaker relations like direct association and temporary association.
Dependency injection however is just a pattern in which we create those associations (by injecting one class in to another).
In most cases you could recognized composition relationship by constructor which inject another object and assign it to its property and life cycle of object ends and start in the same moment.
Other than that from technical point of view there is not much difference between implementation of each association. It is mostly matter of relation definition rather than implementation.
Composition relation is often used to overwrite/change or enhance injected object class behavior. Don't get too excited or worried about composition. In most cases, the advantages versus inheritance are small, and are most enjoyed by third-party library creators, who use composition to add extra flexibility to their libraries.
Inheriting from parent class and overloading/adding methods gives us similar functionality, but with composition we get more flexibility. For example if our constructor accept object that inherit from Head interface we can use HumanHead class if it extends Head interface but we could also use our class to enhance other creatures which extends from same interface like DogHead or DuckHead...
This is perhaps not the best example but it shows the basic concept.
Be sure to check this [Aggregation vs Composition vs Association vs Direct Association] and this [Association-Aggregation-Composition-Dependency].

Difference between extend a class and create instance in another class in php

First file:
class Class_one {
public function __construct() {
}
public function show_name() {
echo "My Name is Siam";
}
public function show_class() {
echo "I read in class 7";
}
}
Second file:
<?php
require_once './Class_one.php';
class Class_two {
public $class_one;
public function __construct() {
$aa = new Class_one();
$this->class_one = $aa;
}
public function history() {
$this->class_one->show_name();
}
}
$ab = new Class_two();
$ab->history();
What will happen if i don't instantiate class_one in class_two and extend class_one into class_two? Is there any difference?
There's only one potential gotcha here: Class_two won't have direct access to Class_one private/protected methods and variables. That can be a good thing (encapsulation is where a class does some specific task and you don't want children to interfere with it), but it can also mean you can't get to the data you need.
I would suggest you do Class_two as a dependency injection (as shown in your example), however
class Class_two {
public $class_one;
public function __construct(Class_one $class) {
$this->class_one = $class;
}
}
It should be a semantic difference:
You use inheritance when relationship between two classes can be expressed with to be verb. For example: My Ford is a Car
You use association/composition when relationship between two classes can be expressed with to have verb. For example: My car has an engine.
Above rules should be the first consideration when choosing inheritance or association in object-oriented programming. There've been always discussion about avoiding inheritance, and some will argue that you should choose composition over inheritance. See this other Q&A: Prefer composition over inheritance?
In terms of pure coding, as #Machavity on his answer has already said, there could be accessibility limitations when using composition instead of inheritance, but I wouldn't decide which approach to use based on member accessibility.

unit tests and object-inheritance

I have a question concerning "unit tests" and object-inheritance. For example:
I have a class A which extends class B. Let's assume the only difference of the two classes is the add method . In class B this add method is slightly extended. Now I want to write a unit test for the add function of class B but because of the parent::add call I have a dependency to the parent class A. In this case I can't mock the add method of the parent class so the resulting test will be a integration test but if I want it to be a unit test? I don't want the the test for method add in class B fails because of the parent method in class A. In this case only the unit-test of the parent method should fail.
class B exends A
{
public function add($item)
{
parent::add($item);
//do some additional stuff
}
....
}
class A
{
protected $items = [];
public function add($item)
{
$this->items[] = $item;
}
....
}
Surely I could use object-aggregation and pass my parent object to the child contructor and therefore I would be able to mock the parent method add, but is this the best approach? I would rarely use object-inheritance anymore.
class B
{
protected $a;
public function __contruct(A $a)
{
$this->a = $a;
}
public function add($item)
{
$this->a->add($item);
//do some additional stuff
}
....
}
class A
{
protected $items = [];
public function add($item)
{
$this->items[] = $item;
}
....
}
I would be very grateful for your opinions. Thanks!
Ask yourself, what kind of inheritance do you want to achieve? If B is a kind of A, then you're wanting interface inheritance. If B shares a lot of code with A, then you're wanting implementation inheritance. Sometimes you want both.
Interface inheritance classifies semantic meaning into a strict hierarchy, with that meaning organized from generalized to specialized. Think taxonomy. The interface (method signatures) represent the behaviors: both the set of messages to which the class responds, as well as the set of messages that the class sends. When inheriting from a class, you implicitly accept responsibility for all messages the superclass sends on your behalf, not just the messages that it can receive. For this reason, the coupling between super- and sub-class is tight and each must strictly substitute for the other (see Liskov Substitution Principle).
Implementation inheritance encapsulates the mechanics of data representation and behavior (properties and methods) into a convenient package for reuse and enhancement by sub-classes. By definition, a sub-class inherits the interface of the parent even if it only wants the implementation.
That last part is crucial. Read it again: Sub-classes inherit the interface even if they only want the implementation.
Does B strictly require the interface of A? Can B substitute for A, in all cases matching co-variance and contra-varience?
If the answer is yes, then you have true sub-typing. Congratulations. Now you must test the same behaviors twice, because in B you are responsible for maintaining the behaviors of A: for every thing A can do, B must be able to do.
If the answer is no, then you merely need to share the implementation, test that the implementation works, then test that B and A separately dispatch into the implementation.
In practical terms, I avoid extends. When I want implementation inheritance, I use trait to define static behaviors † in one place, then use to incorporate it where needed. When I want interface inheritance, I define many narrow interface then combine with implements in all the concrete types, possibly using trait to leverage behavior.
For your example, I'd do this:
trait Container {
public function add($item) { $this->items[] = $item; }
public function getItems() { return $this->items; }
private $items = [];
}
interface Containable { public function add($item); }
class A implements Containable { use Container; }
class B implements Containable {
use Container { Container::add as c_add; }
public function add($item) {
$this->c_add($item);
$this->mutate($item);
}
public function mutate($item) { /* custom stuff */ }
}
Container::add and B::mutate would have unit tests, while B::add would have an integration test.
In summary, favor composition over inheritance because extends is evil. Read the ThoughtWorks primer Composition vs. Inheritance: How To Choose to gain a deeper understanding of the design trade-offs.
† "static behaviors", you ask? Yes. Low-coupling is a goal and this goes for traits. As much as possible, a trait should reference only variables it defines. The safest way to enforce that is with static methods that take all their input as formal arguments. The easiest way is to define member variables in the trait. (But, please, avoid having traits use member variables that are not clearly defined in the trait -- otherwise, that's blind coupling!) The problem, I find, with trait member variables is that when mixing in multiple traits you increase the chance of collision. This is, admittedly, small, but it is a practical consider for library authors.

Use of interface empty method and multiple inheritance to single normal class

As in interface only a method is specified without codes like
interface eat {
public function ways_of_eating_food($givingsomefood);
}
//and remaining class does is only access the method whats the use of it as they could manually create it in the class to
class human implements eat {
public function ways_of_eating_food($foodtoeat){
This is how people eat the food//
}
}
class animal implements eat {
public function ways_of_eating_food($foodtoeat){
//this is how animal eat the food
}
}
As animal and human are two difference class the core part are part are same that is they do eat food given but the style is different so what actually is this useful and how can interface supports multiple inheritance
Interfaces are useful for data hiding. Let's say you want to provide a class to some client code, but don't want to give them full access. One way to restrict access without limiting the functionality of your class is to implement an interface and require the client code to get objects through a factory.
Another benefit of interfaces is team development. If you have a dozen programmers working on different pieces of code that need to connect, it's best to define interfaces for the connections. As long as the programmers write according to the interfaces, everything will link together nicely regardless of personal choices and style.
Yet another benefit is that with interfaces you can use a class without having defined it first. For example, if you have a class that does a lot of intricate work and won't be finished before the rest of the project, the rest of the project can use an interface to it and avoid being stalled by the development of that one class.
Imagine you don`t really know what are the different ways living being can eat but you do not want other classes to not function before you discover all the possible eating methods. Just declare an interface eat and let other classes implement it.
source
 they do eat food given but the style is different so what actually is this useful
You should read about type-hints. Interfaces are useful to manage objects that share behaviors, but you don't know before runtime which object you will have to use.
Consider a function that makes beings eat. Since you make an interface, you can type hint the interface in the function so it can manage any kind of eating beings:
function makeEat(eat $obj) { $obj->ways_of_eating_food( getFood() ); }
function getFood() { return $food; }
If you had not defined an interface however, you would have to make a function to make humans eat, another one to make cats eat, another one to make dogs eat, etc. This is really impractical. By using an interface and type-hinting it to the function, you can use the same function to do the same job.
how can interface supports multiple inheritance
As commented by Vincent:
PHP does support Multi-level inheritance, not multiple inheritance.
This means you can implement multiple different interfaces, but not extend multiple classes.
interface living { public function eat(food $food); }
interface food { public function getEnergyValue(); }
interface animal { public function breath(); }
class cow implements living, animal
{
private $energy = 0;
private $secondsRemaining = 10;
public function eat(food $food) { $this->energy += $food->getEnergyValue(); }
public function breath() { $this->secondsRemaining += 10; }
}
class salad implements food
{
private $value = 50;
public function getEnergyValue() { return $this->value; }
}
$bob = new cow();
$bob->eat(new salad());

Can we create an object of a class inside another class in php?

Can we create an object of a class inside another class in php?I hav made a small application in php,now I am trying to convert the entire code in a class-methods-object fashion.I m now Confused.
You you can do that, but whether you should depends on the lifetime of the two classes and their relation to each other. Basically, you have the choice between Composition and Aggregation.
Composition
You use Composition when the created object has a lifetime equal or less than the object that will use it, e.g.
class A
{
private $belongsToAOnly;
public function __construct()
{
$this->belongsToAOnly = new IBelongToA;
}
}
In this case A "owns" IBelongToA. When A is destroyed, IBelongToA is destroyed too. It cannot live on it's own and is likely just an implementation detail of A. It could be a ValueObject like Money or some other Data Type.
From Craig Larman's "Applying UML and Patterns":
the composite is responsible for creation and deletion of it's parts - either by itself creating/deleting the parts, or by collaborating with other objects. Related to this constraint is that if the composite is destroyed, its parts must be destroyed, or attached to another composite"
Aggregation
You use Aggregation when the lifetime of the created object is longer:
class A
{
private $dbAdapter;
public function __construct(DbAdapter $dbAdapter)
{
$this->dbAdapter = $dbAdapter;
}
}
Unlike with Composition, there is no implication of ownership here. A uses DbAdapter but when A is destroyed DBAdapter lives on. It's a "uses" relationship instead of an "owns" relationship.
Creator Pattern (GRASP)
A good heuristic to decide when an object may create another object at runtime can be found in the Creator Pattern in GRASP which states that objects may create other objects when
Instances of B contains or compositely aggregates instances of A
Instances of B record instances of A
Instances of B closely use instances of A
Instances of B have the initializing information for instances of A and pass it on creation.
Alternatively, you can create Factories whenever you need to create instances of something and aggregate the factory instances, which will give you a cleaner separation of collaborators and creators.
Testability
An issue stemming from creating objects within objects is that they are difficult to test. When you do unit-testing, you usually do not want to recreate and bootstrap the entire system environment but concentrate on testing just that particular class in isolation. To do that, you swap out dependencies of that class with Mock Objects. You cannot do that when you use Composition.
So depending on what the collaborators of a class do, you might want to decide to always use Aggregation, because then you are effectively doing Dependency Injection all the way, which will allow you to swap out collaborators of a class easily, for instance to replace them with Mocks.
Yes you can, but that increases code coupling and makes testing harder.
I'd suggest creating it outside the class and pass it as an argument (it is called Dependency Injection).
class Foo
{
}
class Bar
{
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
}
$foo = new Foo();
$bar = new Bar($foo);
yes you can do it ..
here is one example..
a.php
<?php
class a{
public function function_1(){
echo "b";
}
}
?>
b.php
<?php
include_once ("a.php");
class b{
public function function_b(){
$a = new a;
$a->function_1();
}
}
$b= new b;
$b->function_b();
?>
Yes, you can create an object from a specific class from inside another class.
class SomeClass{
}
class SomeOtherClass {
function hello(){
$o = new SomeClass;
}
}
Yes, you can also define a function in a class. You can do everything in a class in php, please post your code where you confused.
Examples:
Object in a class.
class Foo
{
public $bar; // another object!
public __construct()
{
$this->bar = new Bar();
}
}
(global)Function in a class
<?php
class Foo
{
public function __construct()
{
function __construct()
{
echo "Yes, I'm a global function!";
}
}
}
new Foo();
__construct();
?>

Categories