1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision: 1.8 $ -->
<sect1 id="language.oop5.patterns">
<title>Patterns</title>
<para>
Patterns are ways to describe best practices and good designs.
They show a flexible solution to common programming problems.
</para>
<sect2 id="language.oop5.patterns.factory">
<title>Factory</title>
<para>
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. A Parameterized Factory receives
the name of the class to instantiate as argument.
</para>
<example>
<title>Parameterized Factory Method</title>
<programlisting role="php">
<![CDATA[
<?php
class Example
{
// The parameterized 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');
}
}
}
?>
]]>
</programlisting>
<para>
Defining this method in a class allows drivers to be loaded on the
fly. If the <literal>Example</literal> class was a database
abstraction class, loading a <literal>MySQL</literal> and
<literal>SQLite</literal> driver could be done as follows:
</para>
<programlisting role="php">
<![CDATA[
<?php
// Load a MySQL Driver
$mysql = Example::factory('MySQL');
// Load a SQLite Driver
$sqlite = Example::factory('SQLite');
?>
]]>
</programlisting>
</example>
</sect2>
<sect2 id="language.oop5.patterns.singleton">
<title>Singleton</title>
<para>
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.
</para>
<example>
<title>Singleton Function</title>
<programlisting role="php">
<![CDATA[
<?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);
}
}
?>
]]>
</programlisting>
<para>
This allows a single instance of the <literal>Example</literal>
class to be retrieved.
</para>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
|