Object-oriented programming: Understanding Interfaces

In the various php projects that I have already been involved in and those that I am still involved in, I realize that the Interfaces, which is something very important in the Object Orientation Paradigm, are very little used and / or most of the time, NOT used. Several programmers don’t give a damn about the interfaces. Some deem it unnecessary, others unimportant but in general I believe that this underutilization is due to the lack of knowledge of its characteristics and its conception.

That’s why I’m here writing this post. To try to explain to you readers what an Interface is, what it is for, how to implement / use it and what are the advantages it brings.

Before going into the subject Interface itself, let’s contextualize a fictitious use case and try to fix two important concepts present in Object Orientation. They are: strong / weak coupling and inversion of control (this is a very important pattern design ) .

The OOP good development manual states that the classes should be loosely coupled together. For example, imagine that in a system it has a restricted area that is accessed by filling in a username / password that will be validated in the “user” table in a database. Thus, we could have a class “ConnectionMysql”, responsible for connecting the application with the bank (MySQL) and a class “User” to receive and validate a user’s data.

The implementations of these classes could be as follows (NOTE: The focus here is not security and standards in connection with the database. Therefore, the implementations are done in a “basic” way, with mysql_connect and mysql_select_db).

1
2
3
4
5
6
7
8
class ConnectionMysql 
{    
    public function connect()
    {
        mysql_connect('host', 'userDB', 'passwordDB');
        mysql_select_db('schema');
    }
}
1
2
3
4
5
6
7
8
9
10
class User
{
    private $con;
 
    public function __construct() 
    {
        $this->con = new ConnectionMysql();
        $this->con->connect();
    }
}

Note that, as a user’s authentication will be based on a database table, we need to consume the “ConnectionMysql” class in the “User” class. In our example, this is done through the “$con” attribute that is instantiated in the constructor method. This would not be a good practice, as we have created a dependency of the “User” class on the “ConnectionMysql” class. This may mean that future implementations in the “ConnectionMysql” class will result in changes in the “User” class. If we have a project with 10 classes that use the class “ConnectionMysql”, a change in this can force us to edit codes in 10 different classes.

To solve this, instead of creating a connection “object” within the class that consumes it, it will be passed (injected) to the class that consumes it. Thus, the “User” class would look like this:

1
2
3
4
5
6
7
8
9
10
class User
{
    private $con;
 
    public function __construct(ConnectionMysql $con) 
    {
        $this->con = $con;
        $this->con->connect();
    }
}

Note that now the class “ConnectionMysql” is not instantiated in “User”. It is already created and set as a parameter in the constructor method (It could be through a setCon method ($con) too!).

To use the “User” class.

1
2
$conMysql = new ConnectionMysql();
$user = new User($conMysql);

We can say that the classes of our project are now loosely coupled due to the inversion of control. That is, we no longer have dependency between classes.

Beauty. Understand. But…. When do Interfaces enter?

Calm down, we’ll get there!

Still in this project, imagine that the need arose to implement a new connection class, with Postgre now. So, let’s create the “ConnectionPg” class.

1
2
3
4
5
6
7
class ConnectionPg 
{    
    public function connect()
    {
        pg_connect("host=host dbname=schema user=UserDB password=PasswordDB port=5432");
    }
}

In some cases, the “User” class will consume the “ConnectionMysql” class and in others the “ConnectionPg” class.

Currently it is not possible because the “User” constructor method receives an object of type “ConnectionMysql” as a parameter. Therefore, there is no way to consume the “ConnectionPg” class.

So, let’s create an interface called “IConnection”. An interface has no implementations. It has only the method header declaration. And so, all classes that implement a certain interface, must have the methods declared in it.

“IConnection” interface.

1
2
3
4
interface IConnection
{
    public function connect();
}

Note that all classes that implement the “IConnection” interface must have the “connect ()” method. Our “ConnectionMysql” and “ConnectionPg” classes will implement this interface. This is informed through the “implements” command, as follows:

1
2
3
4
5
6
7
8
class ConnectionMysql implements IConnection
{    
    public function connect()
    {
        mysql_connect('host', 'userDB', 'passwordDB');
        mysql_select_db('schema');
    }
}
1
2
3
4
5
6
7
class ConnectionPg implements IConnection
{    
    public function connect()
    {
        pg_connect("host=host dbname=schema user=UserDB password=PasswordDB port=5432");
    }
}

Now, in the “User” class, the constructor method, instead of receiving a “concrete / physical object”, will receive an instance of any class that implements the “IConnection” interface. Like this:

1
2
3
4
5
6
7
8
9
10
class User
{
    private $con;
 
    public function __construct(IConnection $con) 
    {
        $this->con = $con;
        $this->con->connect();
    }
}

Thus, the class receives both an object of the type “ConnectionMysql” and “ConnectionPg” because both classes implement IConnection.

1
2
3
4
5
$conMysql = new ConnectionMysql();
$user = new User($conMysql);
 
$conPg = new ConnectionPg();
$user = new User($conPg);

If in the future there is a need for connections with Oracle and SQL Server banks, it is enough that the respective classes implement the “IConnection” interface and they can automatically be consumed in the “User” class.

Important informations:

  • A class can have other particular methods that have not been declared in the Interface.
  • A single class can implement several different interfaces.

Well, we’re done here.

Any questions leave a comment.

Hugs!

Holds a university degree in Information Systems, a postgraduate degree in Database Systems and a master's degree in Education with a focus on Sociocommunity Technologies. He works as a professor of technical and technological education at the Federal Institute of Education, Science and Technology of São Paulo, teaching subjects in the areas of programming, database, project development and software engineering.

Posts relacionados

Leave a Reply

Your email address will not be published. Required fields are marked *