0

I found in a book (Learning PHP Design Patterns, Chapter 2, page 25) a text explaining the importance of interfaces in OOP design. The author ended up by giving this example:

<?php
interface IConnectInfo
{
    const HOST ="localhost";
    const UNAME ="phpWorker";
    const DBNAME = "dpPatt";
    const PW ="easyWay";
    function testConnection();
}
?>

Then he implements the above interface:

<?php
include_once('IConnectInfoMethod.php');
class ConSQL implements IConnectInfo
{
    //Passing values using scope resolution operator
    private $server=IConnectInfo::HOST;
    private $currentDB= IConnectInfo::DBNAME;
    private $user= IConnectInfo::UNAME;
    private $pass= IConnectInfo::PW;
    public function testConnection()
    {
        $hookup=new mysqli($this->server, $this->user, $this->pass, $this->currentDB);
        if (mysqli_connect_error())
        {
            die('bad mojo');
        }
        print "You're hooked up Ace! <br />" . $hookup->host_info;
        $hookup->close();
   }
}

$useConstant = new ConSQL();
$useConstant->testConnection();
?>

Question:

In this case (connecting to DB ...) would you really do this in practice? I mean does it even make sens to design an interface (IConnectInfo) for this purpose?
Conceptually speaking, I think this interface does not make a sens as the purpose of an interface is to share code among several unrelated classes; and on the other hand, we could perfectly design a simple class instead to save typing all that unnecessary code.

If I am mistaken, please tell me the benefits of the interface in this scenario.

1

Oh, hooray, more bad advice that made it into print. Having bought many of O'Reilly's earliest titles, that's disappointing.

...I think this interface does not make a sens as the purpose of an interface is to share code among several unrelated classes...

Classes that implement the same interface aren't entirely unrelated; they share a standard for how they interact with their consumers. The real-world equivalent would be saying that cars made by Ferrari and Tesla implement the same basic driver interface (steering wheel, accelerator and brake pedals) even if the cars' inner workings are vastly different (gasoline vs. electric propulsion).

In this case, there's a failure to separate concerns and misuse of interfaces in general by including a partial implementation (the hard-wired constants).

The first concern is a structure to hold connection information (written in generic pseudocode because PHP isn't my bailiwick):

class ConnectInfo {
    public host
    public uname
    public dbname
    public pw
}

That's a compact-enough purpose to merit a class which can be instantiated and tested on its own. A ConnectInfo might be the output of a class that reads a configuration file or is instantiated with hard-wired values during development.

...and on the other hand, we could perfectly design a simple class instead to save typing all that unnecessary code.

You could, but don't use the amount of typing involved as a metric for deciding whether or not something should be done, especially if it only has to be done once.

A simple class would work just fine if you're guaranteed that the only database your program will ever need to access is MySQL. Those guarantees are rarely future-proof, and the small amount of additional effort required to abstract the concept isn't much at all:

interface DatabaseConnection {
    public construct(ConnectInfo info)
    public testConnection()
    public runQuery(...)
      ...etc...
    public destroy()
}

// First implementation
class MySQLConnection implements DatabaseConnection { ... }

Again, notice that the interface services exactly one concern, which is connection to an interaction with the database.

The abstraction might pay off during development when you need to stub out an implementation to test something when the real database isn't ready yet or when you're confronted with having to support querying MySQL and something else at the same time. Those additional implementations will work with your code if they testably conform to the interface:

// Later implementations
class StubbedFakeConnection implements DatabaseConnection { ... }
class PostgreSQLConnection implements DatabaseConnection { ... }

Note that this could just as easily have been an abstract class, but in languages that don't support those or multiple inheritance, interfaces often serve as a substitute.

If you'd like to see real-world implementations of what the example in the book might be trying to convey, browse the documentation for any of the existing PHP database abstraction packages, specifically PDO.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.