Merge branch 'READMEs'

This commit is contained in:
Dominik Liebler
2013-09-24 14:23:10 +02:00
55 changed files with 365 additions and 309 deletions

View File

@@ -3,22 +3,17 @@
namespace DesignPatterns\AbstractFactory;
/**
* Abstract Factory pattern
* class AbstractFactory
*
* Sometimes also known as "Kit" in a GUI libraries.
*
* Purpose:
* to create series of related or dependant objects without specifying their concrete classes,
* usually the created classes all implement the same interface. The client of the abstract
* factory does not care about how these objects are created, he just knows they go together.
*
* Sometimes also known as "Kit" in a GUI libraries.
*
* This design pattern implements the Dependency Inversion Principle since
* it is the concrete subclass which creates concrete components.
*
*
* In this case, the abstract factory is a contract for creating some components
* for the web. There are two components : Text and Picture. There is two ways
* for the web. There are two components : Text and Picture. There is two ways
* of rendering : HTML or JSON.
*
*
* Therefore 4 concretes classes, but the client just need to know this contract
* to build a correct http response (for a html page or for an ajax request)
*/

View File

@@ -0,0 +1,6 @@
# Abstract Factory
## Purpose
To create series of related or dependant objects without specifying their concrete classes.
Usually the created classes all implement the same interface. The client of the abstract factory does not care about how these objects are created, he just knows how they go together.

View File

@@ -5,7 +5,7 @@ namespace DesignPatterns\Adapter;
/**
* EBookAdapter is an adapter to fit an e-book like a paper book
*
* This is the adapter here. Notice it implemennts PaperBookInterface,
* This is the adapter here. Notice it implements PaperBookInterface,
* therefore you don't have to change the code of the client which using paper book.
*/
class EBookAdapter implements PaperBookInterface

10
Adapter/README.md Normal file
View File

@@ -0,0 +1,10 @@
# Adapter / Wrapper
## Purpose
To translate one interface for a class into a compatible interface. An adapter allows classes to work together that normally could not because of incompatible interfaces by providing it's interface to clients while using the original interface.
## Examples
* DB Client libraries adapter
* using multiple different webservices and adapters normalize data so that the outcome is the same for all

View File

@@ -3,16 +3,7 @@
namespace DesignPatterns\Builder;
/**
* Builder is an interface that build parts of a complex object.
*
* Sometime, if the builder has a better knowledge of what it builds, this
* interface could be an abstract class with default methods (aka adapter)
*
* If you have a complex inheritance tree for vehicles, it is logical to have
* a complex inheritance tree for builders too.
*
* Note: Builders have often a fluent interface, see the mock builder of
* PHPUnit for example.
*
*/
interface BuilderInterface
{

10
Builder/Parts/README.md Normal file
View File

@@ -0,0 +1,10 @@
#
# Purpose
# Examples
*

15
Builder/README.md Normal file
View File

@@ -0,0 +1,15 @@
# Builder
## Purpose
Builder is an interface that build parts of a complex object.
Sometimes, if the builder has a better knowledge of what it builds, this interface could be an abstract class with default methods (aka adapter).
If you have a complex inheritance tree for objects, it is logical to have a complex inheritance tree for builders too.
Note: Builders have often a fluent interface, see the mock builder of PHPUnit for example.
## Examples
* PHPUnit: Mock Builder

View File

@@ -1,13 +1,12 @@
# chain of responsibilities
# Chain Of Responsibilities
## Purpose:
To build a chain of objects to handle a call. if one object cannot handle a call, it delegates the call to the next
in the chain and so forth
To build a chain of objects to handle a call. If one object cannot handle a call, it delegates the call to the next in the chain and so forth.
## Examples:
* logging framework
* spam filter
Caching: first object is an instance of e.g. a Memcached Interface, if that "misses" it delegates the call to the database interface
* Yii Framework: CFilterChain is a chain of controller action filters. the executing point is passed from one filter to the next along the chain, and only if all filters say "yes", the action can be invoked at last.
* logging framework, where each chain element decides autonomously what to do with a log message
* a Spam filter
* Caching: first object is an instance of e.g. a Memcached Interface, if that "misses" it delegates the call to the database interface
* Yii Framework: CFilterChain is a chain of controller action filters. the executing point is passed from one filter to the next along the chain, and only if all filters say "yes", the action can be invoked at last.

View File

@@ -3,14 +3,14 @@
namespace DesignPatterns\ChainOfResponsibilities;
/**
* Request is a request which goes throught the chain of responsibilities.
* Request is a request which goes through the chain of responsibilities.
*
* About the request : Sometimes, you don't need an object, just an integer or
* an array. But in this case of a full example, I've made a class to illustrate
* this important idea in the CoR (Chain of Responsibilities). In real world,
* I recommand to always use a class, even a \stdClass if you want, it proves
* to be more adaptative because a single handler doesn't know much about the
* outside world and it is more difficult if, one day, you want add some
* I recommend to always use a class, even a \stdClass if you want, it proves
* to be more adaptive because a single handler doesn't know much about the
* outside world and it is more difficult if, one day, you want to add some
* criterion in a decision process.
*/
class Request

View File

@@ -3,25 +3,7 @@
namespace DesignPatterns\Command;
/**
* Command pattern
*
* Purpose: To encapsulate invocation and decoupling
*
* We have an Invoker and a Receiver. This pattern use a "Command" to delegate the
* method call against the Receiver and presents the same method "execute".
* Therefore, the Invoker just know to call "execute" to process the Command of
* the client. The Receiver is decoupled from the Invoker
*
* The second aspect of ths pattern is the undo(), which undoes the method execute()
* Command can also be agregated to combine more complex commands with minimum
* copy-paste and relying on composition over inheritance.
*
* Examples:
* - A text editor : all events are Command which can be undone, stacked and saved.
* - Symfony2: SF2 Commands that can be run from the CLI are built with just the Command pattern in mind
* - big CLI tools use subcommands to distribute various tasks and pack them in "modules", each of these
* can be implemented with the Command pattern (e.g. vagrant)
*
* class CommandInterface
*/
interface CommandInterface
{

17
Command/README.md Normal file
View File

@@ -0,0 +1,17 @@
# Command
## Purpose
To encapsulate invocation and decoupling.
We have an Invoker and a Receiver. This pattern use a "Command" to delegate the method call against the Receiver and presents the same method "execute".
Therefore, the Invoker just knows to call "execute" to process the Command of the client. The Receiver is decoupled from the Invoker.
The second aspect of ths pattern is the undo(), which undoes the method execute().
Command can also be aggregated to combine more complex commands with minimum copy-paste and relying on composition over inheritance.
## Examples
* A text editor : all events are Command which can be undone, stacked and saved.
* Symfony2: SF2 Commands that can be run from the CLI are built with just the Command pattern in mind
* big CLI tools use subcommands to distribute various tasks and pack them in "modules", each of these can be implemented with the Command pattern (e.g. vagrant)

View File

@@ -3,18 +3,8 @@
namespace DesignPatterns\Composite;
/**
* Composite pattern
*
* Purpose:
* to treat a group of objects the same way as a single instance of the object
*
* Example:
* - a form class instance handles all its form elements like a single instance of the form, when render() is called, it
* subsequently runs trough all its child elements and calls render() on them
* - Zend_Config: a tree of configuration options, each one is a Zend_Config object
*
* The composite node MUST extend the component contract. This is mandatory for building
* a tree of component.
* a tree of components.
*/
class Form extends FormElement
{

12
Composite/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Composite
# Purpose
To treat a group of objects the same way as a single instance of the object.
# Examples
* a form class instance handles all its form elements like a single instance of the form, when `render()` is called, it
subsequently runs trough all its child elements and calls `render()` on them
* `Zend_Config`: a tree of configuration options, each one is a `Zend_Config` object itself

18
DataMapper/README.md Normal file
View File

@@ -0,0 +1,18 @@
# Data Mapper
## Purpose
A Data Mapper, is a Data Access Layer that performs bidirectional transfer of
data between a persistent data store (often a relational database) and an in
memory data representation (the domain layer). The goal of the pattern is to
keep the in memory representation and the persistent data store independent of
each other and the data mapper itself. The layer is composed of one or more
mappers (or Data Access Objects), performing the data transfer. Mapper
implementations vary in scope. Generic mappers will handle many different domain
entity types, dedicated mappers will handle one or a few.
The key point of this pattern is, unlike Active Record pattern, the data model follows Single Responsibility Principle.
## Examples
* DB Object Relational Mapper (ORM) : Doctrine2 uses DAO named as "EntityRepository"

View File

@@ -3,25 +3,7 @@
namespace DesignPatterns\DataMapper;
/**
* DataMapper pattern
*
* Purpose:
* A Data Mapper, is a Data Access Layer that performs bidirectional transfer of
* data between a persistent data store (often a relational database) and an in
* memory data representation (the domain layer). The goal of the pattern is to
* keep the in memory representation and the persistent data store independent of
* each other and the data mapper itself. The layer is composed of one or more
* mappers (or Data Access Objects), performing the data transfer. Mapper
* implementations vary in scope. Generic mappers will handle many different domain
* entity types, dedicated mappers will handle one or a few.
* (FROM http://en.wikipedia.org/wiki/Data_mapper_pattern)
*
* The key point of this pattern is, unlike Active Record pattern, the datamodel
* follows Single Responsibility Principle.
*
* Examples:
* - DB Object Relational Mapper (ORM) : Doctrine2 uses DAO named as "EntityRepository"
*
* class UserMapper
*/
class UserMapper
{

View File

@@ -2,24 +2,15 @@
namespace DesignPatterns\Decorator;
/**
* Decorator pattern
*
* Purpose:
* to dynamically add new functionality to class instances
*
* Examples:
* - Zend Framework: decorators for Zend_Form_Element instances
* - Web Service Layer: Decorators JSON and XML for a REST service (in this case, only one of these should be allowed of
* course)
*
*/
/**
* the Deoorator MUST implement the RendererInterface contract, this is the key-feature
* of this design pattern. If not, this is no longer a Decorator but just a dumb
* wrapper.
*/
/**
* class Decorator
*/
abstract class Decorator implements RendererInterface
{
/**

10
Decorator/README.md Normal file
View File

@@ -0,0 +1,10 @@
# Decorator
## Purpose
To dynamically add new functionality to class instances.
## Examples
* Zend Framework: decorators for Zend_Form_Element instances
* Web Service Layer: Decorators JSON and XML for a REST service (in this case, only one of these should be allowed of course)

View File

@@ -3,18 +3,7 @@
namespace DesignPatterns\DependencyInjection;
/**
* Dependency Injection
*
* Purpose:
* to implement a loosely coupled architecture in order to get better testable, maintainable and extendable code
*
* Examples:
* - the Doctrine2 ORM uses dependency injection e.g. for Configuration that is injected into a Connection object. for
* testing purposes, one can easily create a mock object of the configuration and inject that into the connection
* object
* - Symfony and Zend Framework 2 already have containers for DI that create objects via a configuration array and
* inject them where needed (i.e. in Controllers)
*
* class Configuration
*/
class Configuration
{

View File

@@ -0,0 +1,10 @@
# Dependency Injection
## Purpose
To implement a loosely coupled architecture in order to get better testable, maintainable and extendable code.
## Examples
* the Doctrine2 ORM uses dependency injection e.g. for Configuration that is injected into a Connection object. for testing purposes, one can easily create a mock object of the configuration and inject that into the connection object
* Symfony and Zend Framework 2 already have containers for DI that create objects via a configuration array and inject them where needed (i.e. in Controllers)

View File

@@ -3,23 +3,7 @@
namespace DesignPatterns\Facade;
/**
* The primary goal of a Facade Pattern is not to avoid you to read the manual of
* a complex API. It's only a side-effect.
*
* The first goal is to reduce coupling and follow the Law of Demeter.
*
* A Facade is meant to decouple a client and a sub-system by embedding
* many (but sometimes just one) interface, and of course to reduce complexity.
*
* 1. A facade does not forbid you the access to the sub-system
* 2. You can (you should) have multiple facades for one sub-system
*
* That's why a good facade has no "new" in it. If there are multiple creations
* for each method, it is not a Facade, it's a Builder or a
* [Abstract|Static|Simple] Factory [Method].
*
* The best facade has no new and a constructor with interface-type-hinted parameters.
* If you need creation of new instances, use Factory as argument.
*
*/
class Facade

17
Facade/README.md Normal file
View File

@@ -0,0 +1,17 @@
# Facade
## Purpose
The primary goal of a Facade Pattern is not to avoid you to read the manual of a complex API. It's only a side-effect.
The first goal is to reduce coupling and follow the Law of Demeter.
A Facade is meant to decouple a client and a sub-system by embedding many (but sometimes just one) interface, and of course to reduce complexity.
* A facade does not forbid you the access to the sub-system
* You can (you should) have multiple facades for one sub-system
That's why a good facade has no `new` in it. If there are multiple creations for each method, it is not a Facade, it's a Builder or a
[Abstract|Static|Simple] Factory [Method].
The best facade has no `new` and a constructor with interface-type-hinted parameters.
If you need creation of new instances, use a Factory as argument.

View File

@@ -3,17 +3,7 @@
namespace DesignPatterns\FactoryMethod;
/**
* FactoryMethod is a factory method. The good point over the SimpleFactory
* is you can subclass it to implement different way to create vehicle for
* each country (see subclasses)
*
* For simple case, this abstract class could be just an interface
*
* This pattern is a "real" Design Pattern because it achieves the
* "Dependency Inversion Principle" a.k.a the "D" in S.O.L.I.D principles.
*
* It means the FactoryMethod class depends on abstractions not concrete classes.
* This is the real trick compared to SImpleFactory or StaticFactory.
* class FactoryMethod
*/
abstract class FactoryMethod
{

11
FactoryMethod/README.md Normal file
View File

@@ -0,0 +1,11 @@
# Factory Method
## Purpose
The good point over the SimpleFactory is you can subclass it to implement different ways to create objects
For simple case, this abstract class could be just an interface
This pattern is a "real" Design Pattern because it achieves the "Dependency Inversion Principle" a.k.a the "D" in S.O.L.I.D principles.
It means the FactoryMethod class depends on abstractions, not concrete classes. This is the real trick compared to SimpleFactory or StaticFactory.

11
FluentInterface/README.md Normal file
View File

@@ -0,0 +1,11 @@
# Fluent Interface
## Purpose
To write code that is easy readable just like sentences in a natural language (like English).
## Examples
* Doctrine2's QueryBuilder works something like that example class below
* PHPUnit uses fluent interfaces to build mock objects
* Yii Framework: CDbCommand and CActiveRecord use this pattern, too

View File

@@ -3,15 +3,7 @@
namespace DesignPatterns\FluentInterface;
/**
* fluent interface pattern
*
* Purpose:
* to write code that is easy readable just like "real" sentences
*
* Examples:
* - Doctrine2's QueryBuilder works something like that example class below
* - PHPUnit uses fluent interfaces to build mock objects
* - Yii Framework: CDbCommand and CActiveRecord use this pattern, too
* class SQL
*/
class SQL
{

View File

@@ -3,21 +3,9 @@
namespace DesignPatterns\Iterator;
/**
* iterator pattern
*
* Purpose:
* to make an object iterable
*
* Examples:
* - to process a file line by line by just running over all lines (which have an object representation) for a file
* (which of course is an object, too)
*
* Note:
* Standard PHP Library (SPL) defines an interface Iterator which is best suited for this!
* Often you would want to implement the Countable interface too, to allow count($object) on your iterable object
* class File
*
* THIS EXAMPLE ALSO APPLIES THE COMPOSITE PATTERN
*
*/
class File
{

13
Iterator/README.md Normal file
View File

@@ -0,0 +1,13 @@
# Iterator
## Purpose
To make an object iterable and to make it appear like a collection of objects.
## Examples
* to process a file line by line by just running over all lines (which have an object representation) for a file (which of course is an object, too)
## Note
Standard PHP Library (SPL) defines an interface Iterator which is best suited for this! Often you would want to implement the Countable interface too, to allow `count($object)` on your iterable object

View File

@@ -6,16 +6,8 @@ use DesignPatterns\Mediator\Subsystem;
/**
* Mediator is the concrete Mediator for this design pattern.
*
* This pattern provides an easy to decouple many components working together.
* It is a good alternative over Observer IF you have a "central intelligence",
* like a controller (but not in the sense of the MVC).
*
* All components (called Colleague) are only coupled to the MediatorInterface and
* it is a good thing because in OOP, one good friend is better than many. This
* is the key-feature of this pattern.
*
* In this example, I have made a "Hello World" with the Mediator Pattern, have fun (^_^)
*
* In this example, I have made a "Hello World" with the Mediator Pattern.
*/
class Mediator implements MediatorInterface
{

11
Mediator/README.md Normal file
View File

@@ -0,0 +1,11 @@
# Mediator
## Purpose
This pattern provides an easy to decouple many components working together.
It is a good alternative over Observer IF you have a "central intelligence",
like a controller (but not in the sense of the MVC).
All components (called Colleague) are only coupled to the MediatorInterface and
it is a good thing because in OOP, one good friend is better than many. This
is the key-feature of this pattern.

View File

@@ -3,20 +3,7 @@
namespace DesignPatterns;
/**
* Multiton pattern
*
* --------------------------------------------------------------------------------------------------------------
* THIS IS CONSIDERED TO BE AN ANTI-PATTERN! FOR BETTER TESTABILITY AND MAINTAINABILITY USE DEPENDENCY INJECTION!
* --------------------------------------------------------------------------------------------------------------
*
* Purpose:
* to have only a list of named instances that are used, like a singleton but with n instances
*
* Examples:
* - 2 DB Connectors, e.g. one for MySQL, the other for SQLite
* - multiple Loggers (one for debug messages, one for errors)
*
*
* class Multiton
*/
class Multiton
{

12
Multiton/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Multiton
**THIS IS CONSIDERED TO BE AN ANTI-PATTERN! FOR BETTER TESTABILITY AND MAINTAINABILITY USE DEPENDENCY INJECTION!**
# Purpose
To have only a list of named instances that are used, like a singleton but with n instances.
# Examples
* 2 DB Connectors, e.g. one for MySQL, the other for SQLite
* multiple Loggers (one for debug messages, one for errors)

View File

@@ -3,23 +3,6 @@
namespace DesignPatterns\NullObject;
/**
* NullOutput is a example of NullObject pattern. It is not formely a Design
* Pattern by the GoF but it's a schema which appears frequently enough to
* be a pattern. Futhermore it is a really good pattern in my opinion :
* - the code in the client is simple
* - it reduces the chance of null pointer exception
* - less "if" => less test cases
*
* The purpose : every time you have a method which returns an object or null,
* you should return an object or a "NullObject". With NullObject, you don't need
* statement like "if (!is_null($obj)) { $obj->callSomething(); }" anymore.
*
* In this case, this a logger which does nothing. Other examples :
* - null logger of symfony profiler
* - null output in symfony/console
* - null handler in a Chain of Responsiblities pattern
* - null command in a Command pattern
*
* Performance concerns : ok there is a call for nothing but we spare an "if is_null"
* I didn't run a benchmark but I think it's equivalent.
*
@@ -29,7 +12,7 @@ namespace DesignPatterns\NullObject;
class NullLogger implements LoggerInterface
{
/**
* @param string $str
* {@inheritdoc}
*/
public function log($str)
{

20
NullObject/README.md Normal file
View File

@@ -0,0 +1,20 @@
# Null Object
## Purpose
NullOutput is a example of NullObject pattern. It is not formally a Design Pattern by the GoF but it's a schema which appears frequently enough to
be a pattern. Furthermore it is a really good pattern in my opinion:
* the code in the client is simple
* it reduces the chance of null pointer exception
* less "if" => less test cases
Every time you have a method which returns an object or null, you should return an object or a `NullObject`. With NullObject, you don't need
a statement like `if (!is_null($obj)) { $obj->callSomething(); }` anymore.
## Examples
* Symfony2: null logger of profiler
* Symfony2: null output in Symfony/Console
* null handler in a Chain of Responsibilities pattern
* null command in a Command pattern

14
Observer/README.md Normal file
View File

@@ -0,0 +1,14 @@
# Observer
## Purpose
To implement a publish/subscribe behaviour to an object, whenever a "Subject" object changes it's state, the attached
"Observers" will be notified. It is used to shorten the amount of coupled objects and uses loose coupling instead.
## Examples
* a message queue system is observed to show the progress of a job in a GUI
## Note
PHP already defines two interfaces that can help to implement this pattern: SplObserver and SplSubject.

View File

@@ -3,17 +3,7 @@
namespace DesignPatterns\Observer;
/**
* Observer pattern
*
* Purpose:
* to implement a publish/subscribe behaviour to an object, whenever a "Subject" object changes it's state, the attached
* "Observers" will be notified. It is used to shorten the amount of coupled objects and uses loose coupling instead
*
* Examples:
* - a message queue system is observed to show the progress of a job in a GUI
*
* PHP already defines two interfaces that can help to implement this pattern: SplObserver and SplSubject
*
* class UserObserver
*/
class UserObserver implements \SplObserver
{

View File

@@ -3,14 +3,7 @@
namespace DesignPatterns\Prototype;
/**
* Prototype pattern
*
* Purpose:
* to avoid the cost of creating objects the standard way (new Foo()) and instead create a prototype and clone it
*
* Examples:
* - Large amounts of data (e.g. create 1,000,000 rows in a database at once via a ORM)
*
* class BookPrototype
*/
abstract class BookPrototype
{

9
Prototype/README.md Normal file
View File

@@ -0,0 +1,9 @@
# Prototype
## Purpose
To avoid the cost of creating objects the standard way (new Foo()) and instead create a prototype and clone it
## Examples
* Large amounts of data (e.g. create 1,000,000 rows in a database at once via a ORM)

9
Proxy/README.md Normal file
View File

@@ -0,0 +1,9 @@
# Proxy
## Purpose
To interface to anything that is expensive or impossible to duplicate.
## Examples
* Doctrine2 uses proxies to implement framework magic (e.g. lazy initialization) in them, while the user still works with his own entity classes and will never use nor touch the proxies

View File

@@ -3,15 +3,7 @@
namespace DesignPatterns\Proxy;
/**
* Proxy pattern
*
* Purpose:
* to interface to anything that is expensive or impossible to duplicate
*
* Examples:
* - Doctrine2 uses proxies to implement framework magic (e.g. lazy initialization) in them, while the user still works
* with his own entity classes and will never use nor touch the proxies
*
* class Record
*/
class Record
{

11
Registry/README.md Normal file
View File

@@ -0,0 +1,11 @@
# Registry
## Purpose
To implement a central storage for objects often used throughout the application, is typically implemented using
an abstract class with only static methods (or using the Singleton pattern)
## Examples
* Zend Framework: `Zend_Registry` holds the application's logger object, front controller etc.
* Yii Framework: `CWebApplication` holds all the application components, such as `CWebUser`, `CUrlManager`, etc.

View File

@@ -1,18 +1,9 @@
<?php
namespace DesignPatterns;
namespace DesignPatterns\Registry;
/**
* Registry pattern
*
* Purpose:
* to implement a central storage for objects often used throughout the application, is typically implemented using
* an abstract class with only static methods (or using the Singleton pattern)
*
* Example:
* - Zend Framework: Zend_Registry holds the application's logger object, front controller etc.
* - Yii Framework: CWebApplication holds all the application components, such as CWebUser, CUrlManager, etc.
*
* class Registry
*/
abstract class Registry
{

View File

@@ -1,6 +1,6 @@
<?php
use DesignPatterns\Registry;
use DesignPatterns\Registry\Registry;
// while bootstrapping the application
Registry::set(Registry::LOGGER, new \StdClass());

View File

@@ -3,13 +3,7 @@
namespace DesignPatterns\SimpleFactory;
/**
* ConcreteFactory is a simple factory pattern.
*
* It differs from the static factory because it is NOT static and as you
* know : static => global => evil
*
* Therefore, you can haZ multiple factories, differently parametrized,
* you can subclass it and you can mock-up it.
* class ConcreteFactory
*/
class ConcreteFactory
{

9
SimpleFactory/README.md Normal file
View File

@@ -0,0 +1,9 @@
# Simple Factory
## Purpose
ConcreteFactory is a simple factory pattern.
It differs from the static factory because it is NOT static and as you know: static => global => evil!
Therefore, you can haZ multiple factories, differently parametrized, you can subclass it and you can mock-up it.

13
Singleton/README.md Normal file
View File

@@ -0,0 +1,13 @@
# Singleton
**THIS IS CONSIDERED TO BE AN ANTI-PATTERN! FOR BETTER TESTABILITY AND MAINTAINABILITY USE DEPENDENCY INJECTION!**
## Purpose
To have only one instance of this object in the application that will handle all calls.
## Examples
* DB Connector
* Logger (may also be a Multiton if there are many log files for several purposes)
* Lock file for the application (there is only one in the filesystem ...)

View File

@@ -3,19 +3,7 @@
namespace DesignPatterns\Singleton;
/**
* Singleton pattern
*
* --------------------------------------------------------------------------------------------------------------
* THIS IS CONSIDERED TO BE AN ANTI-PATTERN! FOR BETTER TESTABILITY AND MAINTAINABILITY USE DEPENDENCY INJECTION!
* --------------------------------------------------------------------------------------------------------------
*
* Purpose:
* to have only one instance of this object in the application that will handle all calls
*
* Examples:
* - DB Connector
* - Logger (may also be a Multiton if there are many log files for several purposes)
* - Lock file for the application (there is only one in the filesystem ...)
* class Singleton
*/
class Singleton
{

5
State/README.md Normal file
View File

@@ -0,0 +1,5 @@
# State
## Purpose
Encapsulate varying behavior fo the same routine based on an object's state. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements.

11
StaticFactory/README.md Normal file
View File

@@ -0,0 +1,11 @@
# Static Factory
## Purpose
Similar to the AbstractFactory, this pattern is used to create series of related or dependant objects.
The difference between this and the abstract factory pattern is that the static factory pattern uses just one static
method to create all types of objects it can create. It is usually named `factory` or `build`.
## Examples
* Zend Framework: `Zend_Cache_Backend` or `_Frontend` use a factory method create cache backends or frontends

View File

@@ -3,16 +3,6 @@
namespace DesignPatterns\StaticFactory;
/**
* Static Factory pattern
*
* Purpose:
* similar to the AbstractFactory, this pattern is used to create series of related or dependant objects.
* The difference between this and the abstract factory pattern is that the static factory pattern uses just one static
* method to create all types of objects it can create. It is usually named "factory" or "build".
*
* Examples:
* - Zend Framework: Zend_Cache_Backend or _Frontend use a factory method create cache backends or frontends
*
* Note1: Remember, static => global => evil
* Note2: Cannot be subclassed or mock-upped or have multiple different instances
*/

16
Strategy/README.md Normal file
View File

@@ -0,0 +1,16 @@
# Strategy
## Terminology:
* Context
* Strategy
* Concrete Strategy
## Purpose
To separate strategies and to enable fast switching between them. Also this pattern is a good alternative to inheritance (instead of having an abstract class that is extended).
## Examples
* sorting a list of objects, one strategy by date, the other by id
* simplify unit testing: e.g. switching between file and in-memory storage

View File

@@ -2,24 +2,6 @@
namespace DesignPatterns\Strategy;
/**
* strategy pattern
*
* Terminology:
* - Context
* - Strategy
* - Concrete Strategy
*
* Purpose:
* to separate strategies and to enable fast switching between them.
* also this pattern is a good alternative to inheritance (instead of having an abstract class that is extended)
*
* Examples:
* - sorting a list of objects, one strategy by date, the other by id
* - simplify unit testing: e.g. switching between file and in-memory storage
*
*/
$elements = array(
array(
'id' => 2,

View File

@@ -3,21 +3,7 @@
namespace DesignPatterns\TemplateMethod;
/**
* Template Method is a behavioral design pattern.
*
* Perhaps you have encountered it many times already. The idea is to let subclasses
* of this abstract template "finish" the behavior of an algorithm.
*
* A.k.a the "Hollywood principle" : "" Don't call us, we call you. ""
* This class is not called by subclasses but the inverse.
* How ? With abstraction of course.
*
* In other words, this is a skeleton of algorithm, well-suited for framework
* libraries. The user has just to implement one method and the superclass do
* the job.
*
* It is an easy way to decouple concrete classes and reduce copy-paste,
* that's why you'll find it everywhere.
*
*/
abstract class Journey
{

14
TemplateMethod/README.md Normal file
View File

@@ -0,0 +1,14 @@
# Template Method
## Purpose
Template Method is a behavioral design pattern.
Perhaps you have encountered it many times already. The idea is to let subclasses of this abstract template "finish" the behavior of an algorithm.
A.k.a the "Hollywood principle": "Don't call us, we call you." This class is not called by subclasses but the inverse.
How? With abstraction of course.
In other words, this is a skeleton of algorithm, well-suited for framework libraries. The user has just to implement one method and the superclass do the job.
It is an easy way to decouple concrete classes and reduce copy-paste, that's why you'll find it everywhere.

8
Visitor/README.md Normal file
View File

@@ -0,0 +1,8 @@
# Visitor
## Purpose
The Visitor Pattern lets you outsource operations on objects to other objects. The main reason to do this is to keep a separation of concerns.
But classes have to define a contract to allow visitors (the `Role::accept` method in the example).
The contract is an abstract class but you can have also a clean interface. In that case, each Visitor has to choose itself which method to invoke on the visitor.

View File

@@ -3,14 +3,7 @@
namespace DesignPatterns\Visitor;
/**
* Visitor Pattern
*
* Purpose:
* The Visitor Pattern lets you outsource operations on objects to other objects. The main reason to do this is to keep
* a separation of concerns. But classes have to define an contract to allow visitors (the "accept" method in the example below).
*
* The contract is an abstract class but you can have also a clean interface.
* In that case, each Visitor has to choose itself which method to invoke on the visitor.
* class Role
*/
abstract class Role
{