Patterns

Patterns are ways to describe best practices and good designs. They show a flexible solution to common programming problems.

Factory

The Factory pattern allows for the instantiation of objects at runtime. It is called a Factory Pattern since it is responsible for "manufacturing" an object.

例子 19-23. Factory Method

<?php
class Example
{
    
// The factory method
    
public static function factory ( $type )
    {
        if (include_once
'Drivers/' . $type . '.php' ) {
            
$classname = 'Driver_' . $type ;
            return new
$classname ;
        } else {
            
throw new Exception ( 'Driver not found' );
        }
    }
}
?>

Defining this method in a class allows drivers to be loaded on the fly. If the Example class was a database abstraction class, loading a MySQL and SQLite driver could be done as follows:

<?php
// Load a MySQL Driver
$mysql = Example :: factory ( 'MySQL' );

// Load a SQLite Driver
$sqlite = Example :: factory ( 'SQLite' );
?>

Singleton

The Singleton pattern applies to situations in which there needs to be a single instance of a class. The most common example of this is a database connection. Implementing this pattern allows a programmer to make this single instance easily accessible by many other objects.

例子 19-24. Singleton Function

<?php
class Example
{
    
// Hold an instance of the class
    
private static $instance ;
    
    
// A private constructor; prevents direct creation of object
    
private function __construct ()
    {
        echo
'I am constructed' ;
    }

    
// The singleton method
    
public static function singleton ()
    {
        if (!isset(
self :: $instance )) {
            
$c = __CLASS__ ;
            
self :: $instance = new $c ;
        }

        return
self :: $instance ;
    }
    
    
// Example method
    
public function bark ()
    {
        echo
'Woof!' ;
    }

    
// Prevent users to clone the instance
    
public function __clone ()
    {
        
trigger_error ( 'Clone is not allowed.' , E_USER_ERROR );
    }

}

?>

This allows a single instance of the Example class to be retrieved.

<?php
// This would fail because the constructor is private
$test = new Example ;

// This will always retrieve a single instance of the class
$test = Example :: singleton ();
$test -> bark ();

// This will issue an E_USER_ERROR.
$test_clone = clone ( $test );

?>