3

I'm reading Pro PHP and jQuery and want to rebuild the example. The author is creating a database connection class:

class DB_Connect {

protected $db;

protected function __construct($dbo = NULL){
     if (is_object($db)) {
          $this->db = $db;
     }
     else {
          // Constants are defined in /sys/config/db-cred.inc.php
          $dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME;
          try {
              $this->db = new PDO($dsn, DB_USER, DB_PASS);
          }
          catch (Exception $e) {
              die ($e->getMessage());
          }
     }
} 

This class is then extended by the application's main class, in order to get access to the database object.

Why is this done that way? Couldn't we rather create an instance of DB_Connect in the main class? What are the benefits of that approach?

  • Do you mean $dbo instead of $db? – Arseni Mourzenko Jun 10 '13 at 11:54
  • Has the book explained why you would extend any class? Don't focus on the example too much. – JeffO Jun 10 '13 at 12:04
  • The only explanation was, as mentioned, to give the class access to the database object. – Wottensprels Jun 10 '13 at 12:42
9

What you see there is a classic rookie mistake, establishing an is-a relationship (creating a subclass) between two classes when the actual relationship is has-a (instantiating a class as a member). It's unfortunate that this mistake made it into print.

If the as-stated purpose of Main holds true, its purpose is to be a central module for an application. It is not, in and of itself, something that establishes a database connection and you wouldn't instantiate a Main to do that. The easy test for this is to say the two alternatives aloud and see which rings true. For example:

  • "A Car is a Wheel" (subclassing) doesn't make sense, because cars aren't wheels. If you had to model four- and three-wheeled cars, you'd draw a complete blank on how to do that with subclassing.

  • "A Car has a Wheel" (instantiation) works because cars are composed of (among other things) one or more wheels. Envisioning a FourWheeledCar and a ThreeWheeledCar containing multiple instances of Wheel would be easy: one class has four instances of Wheel and the other has three.

  • Thank you very much for this great answer. Pretty disappointing to see such a mistake in this book, which i believed was one of the better ones on this topic. – Wottensprels Jun 10 '13 at 12:45
4

I wouldn't say that it's a good design to extend the Main application class from DB_Connect for the following reasons:

  1. Inheritance should only be used, if the subclass can be used behaviorally equal to the Superclass, which is not the case in your example (See Liskov substitution principle)
  2. Since LSP is violated and a DB is from a behavioral point of view used by the Main class, it's a classical use case for Composition, i.e. creating an instance of DB_Connect in the Main class as you suggested.

Your problem is a common design issue and is dealed with in the design principle "Composition over Inheritance".

  • Thank you too, gonna read through those links and throwing my book away :) – Wottensprels Jun 10 '13 at 12:45

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.