Factory method design patten in PHP
An creational design pattern, which represents an solution for generation objects without specifying the class name. Virtually all methods that generate objects are particular implementations of the Factory Method pattern.
Motivation:
A motivation for this choice is that the creation of the object is delegated to the factory method.
Diagram:
Implementation:
The classes that generates the objects, the common class to extend and the class with the factory method:
1// the common class to be extended
2abstract class OutputBase {
3 // output the necessary headers
4 abstract public function header();
5
6 // resulting body
7 abstract public function body($data);
8
9}
10
11// class for XML ouput
12class XMLOutput extends OutputBase {
13
14 // output XML header
15 public function header() {
16 header('content-type: text/xml');
17 }
18
19 // xml document
20 public function body($data) {
21 $res = '';
22
23 $res .= '';
24
25 foreach ($data as $root => $item) {
26
27 $res .= '';
28
29 foreach ($item as $key => $val) {
30 $res .= '<'.$key.'>'.$val.'';
31 }
32
33 $res .= '';
34 }
35
36 $res .= '';
37
38 return $res;
39
40 }
41
42}
43
44// class for CSV output
45class CSVOutput extends OutputBase {
46
47 // output CSV header
48 public function header() {
49 header("Content-type: text/plain");
50 }
51
52 // CSV body
53 public function body($data) {
54 $res = '';
55
56 $keys = array_keys($data[0]);
57
58 foreach ($keys as $key) {
59 $res .= '"'.$key.'";';
60 }
61 $res .= "\r\n";
62
63 foreach ($data as $item) {
64 foreach ($item as $val) {
65 $res .= '"'.$val.'";';
66 }
67
68 $res .= "\r\n";
69 }
70
71 return $res;
72 }
73}
74
75// the factory method class
76// is abstract so it wont be instantiated
77abstract class OutputFactory {
78
79 // constant for XML type
80 const XML = 1;
81
82 // constant for CSV type
83 const CSV = 2;
84
85 // static factory method
86 public static function getInstance($type) {
87 // depending which constant was received as a parameter
88 // one of the objects will be returned
89 switch ($type) {
90 case self::XML :
91 return new XMLOutput();
92 break;
93
94 case self::CSV :
95 return new CSVOutput();
96 break;
97 }
98
99 // if the value received as a parameter is not one of the constants
100 // an exception will be thrown
101 throw new Exception('Invalid class type!');
102 }
103
104}
Example:
1// the data
2$data = array(
3 array(
4 'a' => 1,
5 'b' => 2,
6 'c' => 3
7 ),
8 array(
9 'a' => 4,
10 'b' => 5,
11 'c' => 6
12 )
13 );
14
15// try-catch block in case of an exception
16try {
17 // generation the object
18 $obj = OutputFactory::getInstance(OutputFactory::XML);
19
20 // output headers
21 $obj->header();
22
23 // display body
24 echo $obj->body($data);
25
26} catch (Exception $e) {
27
28 $e->getMessage();
29
30}