4. Design pattern in PHP
What is a design pattern?
“Each pattern describes a problem which occurs over and
over again in our environment, and then describes the core
of the solution to that problem, in such a way that you can
use this solution a million times over, without ever doing it
the same way twice”
Christopher Alexander
5. Design pattern in PHP
What is a design pattern?
“A pattern is a [general] solution to a problem in a context”
Gang of four
6. Design pattern in PHP
Elements of a design pattern
Name
Used to describe a design problem, its solution and its
consequences in a word or two
7. Design pattern in PHP
Elements of a design pattern
Problem
Describes when to apply a pattern
8. Design pattern in PHP
Elements of a design pattern
Solution
Describes the elements that make up the design, their
relationships, responsibilities, and collaborations
9. Design pattern in PHP
Elements of a design pattern
Consequences
The results and trade-offs of applying the pattern
11. Design pattern in PHP
Singleton
Ensures that a class has one instance only
Provides a global point of access to it
12. Design pattern in PHP
Singleton
Access control
Only one instance
YES!
13. Design pattern in PHP
Singleton
Used to replace global variables
[changing the name does not change the problem]
Violates the Single Responsibility Principle
[creation + singleton class functionality]
NO!
16. Design pattern in PHP
Singleton
public static function getInstance() {
if (false == self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
17. Design pattern in PHP
Singleton
class Singleton {
private static $instance = false;
private function __construct() {}
public static function getInstance() {
if (false == self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
}
$instance = Singleton::getInstance();
24. Design pattern in PHP
Factory method
class Factory {
/* @return Document */
public function build($condition) {...}
}
25. Design pattern in PHP
Factory method
class DocumentReaderFactory {
public function build($type) {
switch ($type) {
case 'txt':
return new TxtReader();
case 'doc':
return new DocReader();
//...
}
}
}
foreach ($documents as $document) {
$factory = new DocumentReaderFactory();
$reader = $factory->build($document->getType());
$reader->read($document);
}
30. Design pattern in PHP
Adapter
by class inheritance
Adapter exteds Adaptee implements AdapterInterface {
...
}
31. Design pattern in PHP
Adapter
by objects composition
Adapter implements AdapterInterface {
public function __construct(Adaptee $adaptee){
$this->adaptee = $adaptee;
}
...
}
32. Design pattern in PHP
Adapter
interface FileOperationsInterface {
public function getContent($filename);
public function putContent($filename, $data);
public function removeFile($filename);
}
33. Design pattern in PHP
Adapter
by class inheritance
class FTPFileAdapter extends FTPFileRepository
implements FileOperationsInterface {
public function getContent($filename) {
…
}
public function putContent($local_file, $data) {
…
}
public function removeFile($filename) {
…
}
}
34. Design pattern in PHP
Adapter
class FTPFileAdapter implements FileOperationsInterface {
by objects composition
public function __construct(FTPFileRepository $repository) {
$this->repository = $repository;
}
public function getContent($filename) {
$this->repository->download($local_file, $filename);
return file_get_content($local_file);
}
public function putContent($local_file, $data) {
file_put_contents($local_file, $data);
$this->repository->upload($remote_file, $local_file);
}
public function removeFile($filename){
$this->repository->remove($filename);
}
}
36. Design pattern in PHP
Template method
Defines the skeleton of an algorithm in an operation,
deferring some steps to subclasses
37. Design pattern in PHP
Template method
Implements the invariant parts of an algorithm once
Leaves it up to subclasses the behavior that can vary
Common behavior localized in a common class
To control subclasses extensions
38. Design pattern in PHP
Template method
Classes implementing a template method should:
specify hooks (may be overridden)
specify abstract operations (must be overridden)
39. Design pattern in PHP
Template method
abstract operations (must be overridden)
ie: use prefix “DO”
DoRead()
DoWrite()
DoSomething()
40. Design pattern in PHP
Template method
abstract class Reader {
abstract protected function openFile($filename);
abstract protected function readFile();
abstract protected function closeFile();
public function readFileAlgorithm($filename) {
$this->openFile($filename);
$content = $this->readFile();
$this->closeFile();
return $content
}
41. Design pattern in PHPmethod
Template
class XMLReader extends Reader {
protected function openFile($filename) {
$this->xml = simplexml_load_file($filename);
}
protected function readFile() {
return $this->xml->description;
}
public function closeFile(){}
}
42. Design pattern in PHPmethod
Template
class CSVReader extends Reader {
protected function openFile($filename) {
$this->handle = fopen($filename, "r");
}
protected function closeFile() {
fclose($this->handle);
}
protected function readFile() {
$data = fgetcsv($this->handle);
return $data[3]; //description
}
}
43. Design pattern in PHPmethod
Template
Hooks
class Parent {
protected function hook() {}
public function doSomething() {
//...
$this->hook();
}
}
44. Design pattern in PHPmethod
Template
Hooks
class Child extends Parent {
protected function hook() {
//My logic to add into the doSomething method
}
}
46. Design pattern in PHP
Dependency Injection
Components are given their dependencies through
their constructors, methods, or directly into fields
47. Design pattern in PHP
Dependency Injection
Those components do not get their dependencies
themselves, or instantiate them directly
48. Design pattern in PHP
Dependency
Injection
class A {
public function doSomething() {
$b = new B();
//...
}
}
NO!
49. Design pattern in PHP
Dependency
Injection
class A {
public function construct(B $b) {
$this->b = $b;
}
//...
}
YES!
50. Design pattern in PHP
Dependency
Injection
class A {
public function setB(B $b) {
$this->b = $b;
}
//...
}
YES!
51. Design pattern in PHP
Dependency
Injection
class A {
public $b;
//...
}
$a = new A();
$a->b = new B();
YES!
52. Design pattern in PHP
Dependency
Injection
class A implements DiInterface{
}
interface DiInterface {
public function setB(B $b);
}
YES!
53. Design pattern in PHP
Dependency Injection Container
Dependency &
Injection Inversion of control
54. References
Design Patterns: Elements of Reusable Object-Oriented Software
E. Gamma, R. Helm, R. Johnson, J.Vlissides
Addison-Wesley 1974
Martin Fowler - http://martinfowler.com/bliki/InversionOfControl.html
PicoContainer Documentation: http://picocontainer.org/injection.html
SourceMaking - Design Patterns: http://sourcemaking.com/design_patterns
PHP best practices - Pattern in PHP: http://www.phpbestpractices.it