Jay Bhatt
Jay Bhatt

Reputation: 5651

Real world implementation of interfaces

This question might sound obvious and might be stupid as well. But I am trying to figure out why do I need to use interfaces? I think I can handle most of the things which interfaces do using classes then what's the point of using them? It's true that I might end up in problems if I don't interfaces but I am trying to figure out what problems are caused by not using interfaces?

One use of interfaces is that they allow us to define behaviors and put restrictions on of classes which implement them.

Another use is that interface work as types and I can use interfaces for type hinting as shown below.

//Java example
public interface IPaintable{
   void Paint(System.Drawing.Color color);
}

public void Paint(IPaintable item, System.Drawing.Color color){
   item.Paint(color);
}

But are there any other use of interfaces in PHP?

I.e. What advantages do I get by using interfaces in the code below.

//Non interface implementation
    <?php
    class DBPersonProvider
    {
        public function getPerson($givenName, $familyName)
        {
            /* go to the database, get the person... */
            $person = new Person();
            $person->setPrefix("Mr.");
            $person->setGivenName("John");
            return $person;
        }
    }

    /* I need to get person data... */
    $provider = new DBPersonProvider();
    $person = $provider->getPerson("John", "Doe");

    echo($person->getPrefix());
    echo($person->getGivenName());

    ?>

    //Implementation with interface

        <?php
        interface PersonProvider
        {
            public function getPerson($givenName, $familyName);
        }

        class DBPersonProvider implements PersonProvider 
        {
            public function getPerson($givenName, $familyName)
            {
            /* pretend to go to the database, get the person... */
            $person = new Person();
            $person->setPrefix("Mr.");
            $person->setGivenName("John");
            return $person;
        }
    }


    /* I need to get person data... */
   $provider = new DBPersonProvider();
    $person = $provider->getPerson("John", "Doe");

    echo($person->getPrefix());
    echo($person->getGivenName());
    ?> 

Upvotes: 2

Views: 323

Answers (3)

CodeAngry
CodeAngry

Reputation: 12995

I write a nice library that interacts with the database. And I use MySQL. When you purchase my library, you know it's MySQL based but you roll with SQL Server. I was considerate enough to create interfaces for the Database access. And I provided an implementation for MySQL. Now you can implement your own SQL Server wrapper around my database access interface, and then use it as a __construct() argument for the classes in the library you will use to change move storage to SQL Server.

Interfaces are very useful for library / reusable code writers like me :) They are code contracts that have to be obeyed. You know that any class that implements them WILL have a set of functions exactly as the Interface declared them. And you can also statically type them in function arguments like function(MyInterface $Object) which enforces, at PHP compiler level, that $Object must be implementing MyInterface.

PS: Abstract classes are good enough for the rest of self-written code consuming developers...

UPDATE:

/**
* Database Access functionality blueprint.
*/
interface IDatabaseAccess {
    public function Connect();
    public function Query();
    public function Fetch();
}

/**
* Database Access functionality implementation for MySQL.
*/
class MySqlDatabaseAccess implements IDatabaseAccess {
    public function Query(){
        // do mysql stuff
    }
    public function Fetch(){
        // do mysql stuff
    }
}

/**
* Database Access functionality implementation for SQLServer.
*/
class SqlServerDatabaseAccess implements IDatabaseAccess {
    public function Query(){
        // do sqlserver stuff
    }
    public function Fetch(){
        // do sqlserver stuff
    }
}

/**
* Database Access consumer that's database system agnostic.
*/
class DatabaseAccessConsumer {
    protected $_Provider = null;
    public function __construct(IDatabaseAccess $Provider){
        $this->_Provider = $Provider;
        $this->_Provider->Connect();
    }
    public function Query(){
        return $this->_Provider->Query();
    }
    public function Fetch(){
        return $this->_Provider->Fetch();
    }
}

^ code that should speak for itself.

Upvotes: 1

Robert DeBoer
Robert DeBoer

Reputation: 1695

Interfaces are just blueprints of classes - they are ways of saying "If you are going to be doing something with this type of class, it must have this and do this." It allows you to control - to an extent - what another class will have/do at a minimum for a given situation. Not every situation calls for an iterface. Interfaces are best used in situations when you need to have some control over the basic code of certain classes but you may not be the one writing them. If you know that the extended classes will have x properties and y methods, then you can do basic future class support.

Upvotes: 1

RandomSeed
RandomSeed

Reputation: 29769

Interfaces actually provide less features than abstract classes (you cannot implement anything).

But they resolve the problem of multiple inheritance. Most modern language do not allow a class to derive more than one class. By using an interface, which does not implement any method, you are sure there is no ambiguity when you invoke a method from the interface (because there is no implementation).

Example (syntactically not valid):

class A {
    public foo() {
        echo 'I am A and I foo';
    };
    public 
}

class B {
    public foo() {
        echo 'I am B and I foo';
    }
}

class C extends A, B { // invalid
    public bar() {
        foo(); // which one? A's or B's?
    }
}

Second example:

class A {
    public foo() {
        echo 'I am A and I foo';
    };
}

interface iB {
    public foo();
    public bar();
}

interface iC {
    public foo();
    public qux();
}

class D extends A implements iB, iC {

    public bar() {
         foo(); // no ambiguity, this is A::foo(), even if the method is also declared in the interfaces
    }

    public qux() {}
}

Upvotes: 1

Related Questions