PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 9 ■ GENERATING OBJECTS


to installation. The object may also be used as a notice board, a central location for messages that could
be set or retrieved by otherwise unrelated objects in a system.
Passing a Preferences object around from object to object may not always be a good idea. Many
classes that do not otherwise use the object could be forced to accept it simply so that they could pass it
on to the objects that they work with. This is just another kind of coupling.
You also need to be sure that all objects in your system are working with the same Preferences object.
You do not want objects setting values on one object, while others read from an entirely different one.
Let’s distill the forces in this problem:



  • A Preferences object should be available to any object in your system.

  • A Preferences object should not be stored in a global variable, which can be
    overwritten.

  • There should be no more than one Preferences object in play in the system. This
    means that object Y can set a property in the Preferences object, and object Z can
    retrieve the same property, without either one talking to the other directly
    (assuming both have access to the Preferences object).


Implementation


To address this problem, I can start by asserting control over object instantiation. Here, I create a class
that cannot be instantiated from outside of itself. That may sound difficult, but it’s simply a matter of
defining a private constructor:


class Preferences {
private $props = array();


private function __construct() { }


public function setProperty( $key, $val ) {
$this->props[$key] = $val;
}


public function getProperty( $key ) {
return $this->props[$key];
}
}


Of course, at this point, the Preferences class is entirely unusable. I have taken access restriction to
an absurd level. Because the constructor is declared private, no client code can instantiate an object
from it. The setProperty() and getProperty() methods are therefore redundant.
I can use a static method and a static property to mediate object instantiation:


class Preferences {
private $props = array();
private static $instance;


private function __construct() { }


public static function getInstance() {
if ( empty( self::$instance ) ) {
self::$instance = new Preferences();
}

Free download pdf