diff --git a/Behavioral/ChainOfResponsibilities/index.rst b/Behavioral/ChainOfResponsibilities/index.rst new file mode 100644 index 0000000..c838a29 --- /dev/null +++ b/Behavioral/ChainOfResponsibilities/index.rst @@ -0,0 +1,57 @@ +Chain Of Responsibilities +========================= + +Purpose: +-------- + +To build a chain of objects to handle a call in sequential order. If one +object cannot handle a call, it delegates the call to the next in the +chain and so forth. + +Examples: +--------- + +- 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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt ChainOfResponsibility UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Handler.php + +.. literalinclude:: Handler.php + :language: php + :linenos: + +Request.php + +.. literalinclude:: Request.php + :language: php + :linenos: + +Test +---- + +Tests/ChainTest.php + +.. literalinclude:: Tests/ChainTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/ChainOfResponsibilities diff --git a/Behavioral/Command/index.rst b/Behavioral/Command/index.rst new file mode 100644 index 0000000..5056f13 --- /dev/null +++ b/Behavioral/Command/index.rst @@ -0,0 +1,76 @@ +Command +======= + +Purpose +------- + +To encapsulate invocation and decoupling. + +We have an Invoker and a Receiver. This pattern uses 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 this 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) + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Command UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +HelloCommand.php + +.. literalinclude:: HelloCommand.php + :language: php + :linenos: + +Receiver.php + +.. literalinclude:: Receiver.php + :language: php + :linenos: + +CommandInterface.php + +.. literalinclude:: CommandInterface.php + :language: php + :linenos: + +Invoker.php + +.. literalinclude:: Invoker.php + :language: php + :linenos: + +Test +---- + +Tests/CommandTest.php + +.. literalinclude:: Tests/CommandTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Command diff --git a/Behavioral/Iterator/index.rst b/Behavioral/Iterator/index.rst new file mode 100644 index 0000000..6241bc8 --- /dev/null +++ b/Behavioral/Iterator/index.rst @@ -0,0 +1,69 @@ +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 + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Iterator UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +BookList.php + +.. literalinclude:: BookList.php + :language: php + :linenos: + +BookListReverseIterator.php + +.. literalinclude:: BookListReverseIterator.php + :language: php + :linenos: + +BookListIterator.php + +.. literalinclude:: BookListIterator.php + :language: php + :linenos: + +Book.php + +.. literalinclude:: Book.php + :language: php + :linenos: + +Test +---- + +Tests/IteratorTest.php + +.. literalinclude:: Tests/IteratorTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Iterator diff --git a/Behavioral/Mediator/index.rst b/Behavioral/Mediator/index.rst new file mode 100644 index 0000000..7df0287 --- /dev/null +++ b/Behavioral/Mediator/index.rst @@ -0,0 +1,54 @@ +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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Mediator UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +MediatorInterface.php + +.. literalinclude:: MediatorInterface.php + :language: php + :linenos: + +Mediator.php + +.. literalinclude:: Mediator.php + :language: php + :linenos: + +Colleague.php + +.. literalinclude:: Colleague.php + :language: php + :linenos: + +Test +---- + +Tests/MediatorTest.php + +.. literalinclude:: Tests/MediatorTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Mediator diff --git a/Behavioral/Memento/index.rst b/Behavioral/Memento/index.rst new file mode 100644 index 0000000..9d28f27 --- /dev/null +++ b/Behavioral/Memento/index.rst @@ -0,0 +1,67 @@ +Memento +======= + +Purpose +------- + +Provide the ability to restore an object to its previous state (undo via +rollback). + +The memento pattern is implemented with three objects: the originator, a +caretaker and a memento. The originator is some object that has an +internal state. The caretaker is going to do something to the +originator, but wants to be able to undo the change. The caretaker first +asks the originator for a memento object. Then it does whatever +operation (or sequence of operations) it was going to do. To roll back +to the state before the operations, it returns the memento object to the +originator. The memento object itself is an opaque object (one which the +caretaker cannot, or should not, change). When using this pattern, care +should be taken if the originator may change other objects or resources +- the memento pattern operates on a single object. + +Examples +-------- + +- The seed of a pseudorandom number generator +- The state in a finite state machine + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Momento UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Caretaker.php + +.. literalinclude:: Caretaker.php + :language: php + :linenos: + +Memento.php + +.. literalinclude:: Memento.php + :language: php + :linenos: + +Originator.php + +.. literalinclude:: Originator.php + :language: php + :linenos: + +Test +---- + +Tests/MementoTest.php + +.. literalinclude:: Tests/MementoTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Memento diff --git a/Behavioral/NullObject/index.rst b/Behavioral/NullObject/index.rst new file mode 100644 index 0000000..eb13a56 --- /dev/null +++ b/Behavioral/NullObject/index.rst @@ -0,0 +1,74 @@ +Null Object +=========== + +Purpose +------- + +NullObject is not a GoF design pattern but a schema which appears +frequently enough to be considered a pattern. It has the following +benefits: + +- Client code is simplified +- Reduces the chance of null pointer exceptions +- Fewer conditionals require less test cases + +Methods that return an object or null should instead return an object or +``NullObject``. ``NullObject``\ s simplify boilerplate code such as +``if (!is_null($obj)) { $obj->callSomething(); }`` to just +``$obj->callSomething();`` by eliminating the conditional check in +client code. + +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 + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt NullObject UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +PrintLogger.php + +.. literalinclude:: PrintLogger.php + :language: php + :linenos: + +NullLogger.php + +.. literalinclude:: NullLogger.php + :language: php + :linenos: + +Service.php + +.. literalinclude:: Service.php + :language: php + :linenos: + +LoggerInterface.php + +.. literalinclude:: LoggerInterface.php + :language: php + :linenos: + +Test +---- + +Tests/LoggerTest.php + +.. literalinclude:: Tests/LoggerTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/NullObject diff --git a/Behavioral/Observer/index.rst b/Behavioral/Observer/index.rst new file mode 100644 index 0000000..c14c448 --- /dev/null +++ b/Behavioral/Observer/index.rst @@ -0,0 +1,57 @@ +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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Observer UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +UserObserver.php + +.. literalinclude:: UserObserver.php + :language: php + :linenos: + +User.php + +.. literalinclude:: User.php + :language: php + :linenos: + +Test +---- + +Tests/ObserverTest.php + +.. literalinclude:: Tests/ObserverTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Observer diff --git a/Behavioral/Specification/index.rst b/Behavioral/Specification/index.rst new file mode 100644 index 0000000..6923159 --- /dev/null +++ b/Behavioral/Specification/index.rst @@ -0,0 +1,75 @@ +Specification +============= + +Purpose +------- + +Builds a clear specification of business rules, where objects can be +checked against. The composite specification class has one method called +``isSatisfiedBy`` that returns either true or false depending on whether +the given object satisfies the specification. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Specification UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Either.php + +.. literalinclude:: Either.php + :language: php + :linenos: + +PriceSpecification.php + +.. literalinclude:: PriceSpecification.php + :language: php + :linenos: + +SpecificationInterface.php + +.. literalinclude:: SpecificationInterface.php + :language: php + :linenos: + +AbstractSpecification.php + +.. literalinclude:: AbstractSpecification.php + :language: php + :linenos: + +Item.php + +.. literalinclude:: Item.php + :language: php + :linenos: + +Plus.php + +.. literalinclude:: Plus.php + :language: php + :linenos: + +Not.php + +.. literalinclude:: Not.php + :language: php + :linenos: + +Test +---- + +Tests/SpecificationTest.php + +.. literalinclude:: Tests/SpecificationTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Specification diff --git a/Behavioral/State/index.rst b/Behavioral/State/index.rst new file mode 100644 index 0000000..0b679c2 --- /dev/null +++ b/Behavioral/State/index.rst @@ -0,0 +1,56 @@ +State +===== + +Purpose +------- + +Encapsulate varying behavior for 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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt State UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +OrderInterface.php + +.. literalinclude:: OrderInterface.php + :language: php + :linenos: + +OrderFactory.php + +.. literalinclude:: OrderFactory.php + :language: php + :linenos: + +OrderController.php + +.. literalinclude:: OrderController.php + :language: php + :linenos: + +ShippingOrder.php + +.. literalinclude:: ShippingOrder.php + :language: php + :linenos: + +CreateOrder.php + +.. literalinclude:: CreateOrder.php + :language: php + :linenos: + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/State diff --git a/Behavioral/Strategy/index.rst b/Behavioral/Strategy/index.rst new file mode 100644 index 0000000..c1a2fe3 --- /dev/null +++ b/Behavioral/Strategy/index.rst @@ -0,0 +1,70 @@ +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 + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Strategy UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +DateComparator.php + +.. literalinclude:: DateComparator.php + :language: php + :linenos: + +IdComparator.php + +.. literalinclude:: IdComparator.php + :language: php + :linenos: + +ObjectCollection.php + +.. literalinclude:: ObjectCollection.php + :language: php + :linenos: + +ComparatorInterface.php + +.. literalinclude:: ComparatorInterface.php + :language: php + :linenos: + +Test +---- + +Tests/StrategyTest.php + +.. literalinclude:: Tests/StrategyTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Strategy diff --git a/Behavioral/TemplateMethod/index.rst b/Behavioral/TemplateMethod/index.rst new file mode 100644 index 0000000..f3be5bc --- /dev/null +++ b/Behavioral/TemplateMethod/index.rst @@ -0,0 +1,63 @@ +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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt TemplateMethod UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +CityJourney.php + +.. literalinclude:: CityJourney.php + :language: php + :linenos: + +Journey.php + +.. literalinclude:: Journey.php + :language: php + :linenos: + +BeachJourney.php + +.. literalinclude:: BeachJourney.php + :language: php + :linenos: + +Test +---- + +Tests/JourneyTest.php + +.. literalinclude:: Tests/JourneyTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/TemplateMethod diff --git a/Behavioral/Visitor/index.rst b/Behavioral/Visitor/index.rst new file mode 100644 index 0000000..85fb280 --- /dev/null +++ b/Behavioral/Visitor/index.rst @@ -0,0 +1,67 @@ +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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Visitor UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Group.php + +.. literalinclude:: Group.php + :language: php + :linenos: + +Role.php + +.. literalinclude:: Role.php + :language: php + :linenos: + +RolePrintVisitor.php + +.. literalinclude:: RolePrintVisitor.php + :language: php + :linenos: + +User.php + +.. literalinclude:: User.php + :language: php + :linenos: + +RoleVisitorInterface.php + +.. literalinclude:: RoleVisitorInterface.php + :language: php + :linenos: + +Test +---- + +Tests/VisitorTest.php + +.. literalinclude:: Tests/VisitorTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Visitor diff --git a/Behavioral/index.rst b/Behavioral/index.rst new file mode 100644 index 0000000..5691a0d --- /dev/null +++ b/Behavioral/index.rst @@ -0,0 +1,40 @@ +Behavioral +========== + +In software engineering, behavioral design patterns are design patterns +that identify common communication patterns between objects and realize +these patterns. By doing so, these patterns increase flexibility in +carrying out this communication. + +- `ChainOfResponsibilities `__ + `:notebook: `__ +- `Command `__ + `:notebook: `__ +- `Iterator `__ + `:notebook: `__ +- `Mediator `__ + `:notebook: `__ +- `NullObject `__ + `:notebook: `__ +- `Observer `__ + `:notebook: `__ +- `Specification `__ + `:notebook: `__ +- `State `__ + `:notebook: `__ +- `Strategy `__ + `:notebook: `__ +- `TemplateMethod `__ + `:notebook: `__ +- `Visitor `__ + `:notebook: `__ + +Code +---- + +You can also find these code on `GitHub`_ + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral diff --git a/Creational/AbstractFactory/index.rst b/Creational/AbstractFactory/index.rst new file mode 100644 index 0000000..707968c --- /dev/null +++ b/Creational/AbstractFactory/index.rst @@ -0,0 +1,69 @@ +Abstract Factory +================ + +Purpose +------- + +To create series of related or dependent 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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt AbstractFactory UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Text.php + +.. literalinclude:: Text.php + :language: php + :linenos: + +JsonFactory.php + +.. literalinclude:: JsonFactory.php + :language: php + :linenos: + +AbstractFactory.php + +.. literalinclude:: AbstractFactory.php + :language: php + :linenos: + +MediaInterface.php + +.. literalinclude:: MediaInterface.php + :language: php + :linenos: + +HtmlFactory.php + +.. literalinclude:: HtmlFactory.php + :language: php + :linenos: + +Picture.php + +.. literalinclude:: Picture.php + :language: php + :linenos: + +Test +---- + +Tests/AbstractFactoryTest.php + +.. literalinclude:: Tests/AbstractFactoryTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/AbstractFactory diff --git a/Creational/Builder/Parts/index.rst b/Creational/Builder/Parts/index.rst new file mode 100644 index 0000000..8760de0 --- /dev/null +++ b/Creational/Builder/Parts/index.rst @@ -0,0 +1,53 @@ +Purpose +======= + +Examples +======== + +- + +Code +---- + +You can also find these code on `GitHub`_ + +Wheel.php + +.. literalinclude:: Wheel.php + :language: php + :linenos: + +Door.php + +.. literalinclude:: Door.php + :language: php + :linenos: + +Car.php + +.. literalinclude:: Car.php + :language: php + :linenos: + +Bike.php + +.. literalinclude:: Bike.php + :language: php + :linenos: + +Vehicle.php + +.. literalinclude:: Vehicle.php + :language: php + :linenos: + +Engine.php + +.. literalinclude:: Engine.php + :language: php + :linenos: + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Builder/Parts diff --git a/Creational/Builder/index.rst b/Creational/Builder/index.rst new file mode 100644 index 0000000..b636e01 --- /dev/null +++ b/Creational/Builder/index.rst @@ -0,0 +1,68 @@ +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 + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Builder UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +BuilderInterface.php + +.. literalinclude:: BuilderInterface.php + :language: php + :linenos: + +CarBuilder.php + +.. literalinclude:: CarBuilder.php + :language: php + :linenos: + +Director.php + +.. literalinclude:: Director.php + :language: php + :linenos: + +BikeBuilder.php + +.. literalinclude:: BikeBuilder.php + :language: php + :linenos: + +Test +---- + +Tests/DirectorTest.php + +.. literalinclude:: Tests/DirectorTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Builder diff --git a/Creational/FactoryMethod/index.rst b/Creational/FactoryMethod/index.rst new file mode 100644 index 0000000..693321f --- /dev/null +++ b/Creational/FactoryMethod/index.rst @@ -0,0 +1,82 @@ +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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt FactoryMethod UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Porsche.php + +.. literalinclude:: Porsche.php + :language: php + :linenos: + +GermanFactory.php + +.. literalinclude:: GermanFactory.php + :language: php + :linenos: + +ItalianFactory.php + +.. literalinclude:: ItalianFactory.php + :language: php + :linenos: + +VehicleInterface.php + +.. literalinclude:: VehicleInterface.php + :language: php + :linenos: + +FactoryMethod.php + +.. literalinclude:: FactoryMethod.php + :language: php + :linenos: + +Bicycle.php + +.. literalinclude:: Bicycle.php + :language: php + :linenos: + +Ferrari.php + +.. literalinclude:: Ferrari.php + :language: php + :linenos: + +Test +---- + +Tests/FactoryMethodTest.php + +.. literalinclude:: Tests/FactoryMethodTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/FactoryMethod diff --git a/Creational/Multiton/index.rst b/Creational/Multiton/index.rst new file mode 100644 index 0000000..66b8764 --- /dev/null +++ b/Creational/Multiton/index.rst @@ -0,0 +1,40 @@ +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) + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Multiton UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Multiton.php + +.. literalinclude:: Multiton.php + :language: php + :linenos: + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Multiton diff --git a/Creational/Pool/index.rst b/Creational/Pool/index.rst new file mode 100644 index 0000000..30d3be0 --- /dev/null +++ b/Creational/Pool/index.rst @@ -0,0 +1,69 @@ +Pool +==== + +The **object pool pattern** is a software creational design pattern that +uses a set of initialized objects kept ready to use – a "pool" – rather +than allocating and destroying them on demand. A client of the pool will +request an object from the pool and perform operations on the returned +object. When the client has finished, it returns the object, which is a +specific type of factory object, to the pool rather than destroying it. + +Object pooling can offer a significant performance boost in situations +where the cost of initializing a class instance is high, the rate of +instantiation of a class is high, and the number of instances in use at +any one time is low. The pooled object is obtained in predictable time +when creation of the new objects (especially over network) may take +variable time. + +However these benefits are mostly true for objects that are expensive +with respect to time, such as database connections, socket connections, +threads and large graphic objects like fonts or bitmaps. In certain +situations, simple object pooling (that hold no external resources, but +only occupy memory) may not be efficient and could decrease performance. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Pool UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Pool.php + +.. literalinclude:: Pool.php + :language: php + :linenos: + +Processor.php + +.. literalinclude:: Processor.php + :language: php + :linenos: + +Worker.php + +.. literalinclude:: Worker.php + :language: php + :linenos: + +Test +---- + +Tests/TestWorker.php + +.. literalinclude:: Tests/TestWorker.php + :language: php + :linenos: + +Tests/PoolTest.php + +.. literalinclude:: Tests/PoolTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Pool diff --git a/Creational/Prototype/index.rst b/Creational/Prototype/index.rst new file mode 100644 index 0000000..31a98a3 --- /dev/null +++ b/Creational/Prototype/index.rst @@ -0,0 +1,55 @@ +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). + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Prototype UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +BookPrototype.php + +.. literalinclude:: BookPrototype.php + :language: php + :linenos: + +BarBookPrototype.php + +.. literalinclude:: BarBookPrototype.php + :language: php + :linenos: + +index.php + +.. literalinclude:: index.php + :language: php + :linenos: + +FooBookPrototype.php + +.. literalinclude:: FooBookPrototype.php + :language: php + :linenos: + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Prototype diff --git a/Creational/SimpleFactory/index.rst b/Creational/SimpleFactory/index.rst new file mode 100644 index 0000000..ff55711 --- /dev/null +++ b/Creational/SimpleFactory/index.rst @@ -0,0 +1,60 @@ +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 have multiple factories, differently parametrized, +you can subclass it and you can mock-up it. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt SimpleFactory UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +ConcreteFactory.php + +.. literalinclude:: ConcreteFactory.php + :language: php + :linenos: + +VehicleInterface.php + +.. literalinclude:: VehicleInterface.php + :language: php + :linenos: + +Scooter.php + +.. literalinclude:: Scooter.php + :language: php + :linenos: + +Bicycle.php + +.. literalinclude:: Bicycle.php + :language: php + :linenos: + +Test +---- + +Tests/SimpleFactoryTest.php + +.. literalinclude:: Tests/SimpleFactoryTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/SimpleFactory diff --git a/Creational/Singleton/index.rst b/Creational/Singleton/index.rst new file mode 100644 index 0000000..7393782 --- /dev/null +++ b/Creational/Singleton/index.rst @@ -0,0 +1,49 @@ +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 + ...) + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Singleton UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Singleton.php + +.. literalinclude:: Singleton.php + :language: php + :linenos: + +Test +---- + +Tests/SingletonTest.php + +.. literalinclude:: Tests/SingletonTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Singleton diff --git a/Creational/StaticFactory/index.rst b/Creational/StaticFactory/index.rst new file mode 100644 index 0000000..85cacf7 --- /dev/null +++ b/Creational/StaticFactory/index.rst @@ -0,0 +1,64 @@ +Static Factory +============== + +Purpose +------- + +Similar to the AbstractFactory, this pattern is used to create series of +related or dependent 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 + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt StaticFactory UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +StaticFactory.php + +.. literalinclude:: StaticFactory.php + :language: php + :linenos: + +FormatterInterface.php + +.. literalinclude:: FormatterInterface.php + :language: php + :linenos: + +FormatString.php + +.. literalinclude:: FormatString.php + :language: php + :linenos: + +FormatNumber.php + +.. literalinclude:: FormatNumber.php + :language: php + :linenos: + +Test +---- + +Tests/StaticFactoryTest.php + +.. literalinclude:: Tests/StaticFactoryTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/StaticFactory diff --git a/Creational/index.rst b/Creational/index.rst new file mode 100644 index 0000000..1e34638 --- /dev/null +++ b/Creational/index.rst @@ -0,0 +1,36 @@ +Creational +========== + +In software engineering, creational design patterns are design patterns +that deal with object creation mechanisms, trying to create objects in a +manner suitable to the situation. The basic form of object creation +could result in design problems or added complexity to the design. +Creational design patterns solve this problem by somehow controlling +this object creation. + +- `AbstractFactory `__ + `:notebook: `__ +- `Builder `__ + `:notebook: `__ +- `FactoryMethod `__ + `:notebook: `__ +- `Multiton `__ (is considered an anti-pattern! :no\_entry:) +- `Pool `__ + `:notebook: `__ +- `Prototype `__ + `:notebook: `__ +- `SimpleFactory `__ +- `Singleton `__ + `:notebook: `__ (is + considered an anti-pattern! :no\_entry:) +- `StaticFactory `__ + +Code +---- + +You can also find these code on `GitHub`_ + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational diff --git a/More/Delegation/index.rst b/More/Delegation/index.rst new file mode 100644 index 0000000..873f3e2 --- /dev/null +++ b/More/Delegation/index.rst @@ -0,0 +1,53 @@ +Delegation +========== + +Purpose +------- + +... + +Examples +-------- + +... + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Delegation UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Usage.php + +.. literalinclude:: Usage.php + :language: php + :linenos: + +TeamLead.php + +.. literalinclude:: TeamLead.php + :language: php + :linenos: + +JuniorDeveloper.php + +.. literalinclude:: JuniorDeveloper.php + :language: php + :linenos: + +Test +---- + +Tests/DelegationTest.php + +.. literalinclude:: Tests/DelegationTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/More/Delegation diff --git a/More/Repository/index.rst b/More/Repository/index.rst new file mode 100644 index 0000000..504be8b --- /dev/null +++ b/More/Repository/index.rst @@ -0,0 +1,61 @@ +Repository +========== + +Purpose +------- + +Mediates between the domain and data mapping layers using a +collection-like interface for accessing domain objects. Repository +encapsulates the set of objects persisted in a data store and the +operations performed over them, providing a more object-oriented view of +the persistence layer. Repository also supports the objective of +achieving a clean separation and one-way dependency between the domain +and data mapping layers. + +Examples +-------- + +- Doctrine 2 ORM: there is Repository that mediates between Entity and + DBAL and contains methods to retrieve objects +- Laravel Framework + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Repository UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +PostRepository.php + +.. literalinclude:: PostRepository.php + :language: php + :linenos: + +Post.php + +.. literalinclude:: Post.php + :language: php + :linenos: + +MemoryStorage.php + +.. literalinclude:: MemoryStorage.php + :language: php + :linenos: + +Storage.php + +.. literalinclude:: Storage.php + :language: php + :linenos: + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/More/Repository diff --git a/More/ServiceLocator/index.rst b/More/ServiceLocator/index.rst new file mode 100644 index 0000000..96bad04 --- /dev/null +++ b/More/ServiceLocator/index.rst @@ -0,0 +1,83 @@ +Service Locator +=============== + +Purpose +------- + +To implement a loosely coupled architecture in order to get better +testable, maintainable and extendable code. DI pattern and Service +Locator pattern are an implementation of the Inverse of Control pattern. + +Usage +----- + +With ``ServiceLocator`` you can register a service for a given +interface. By using the interface you can retrieve the service and use +it in the classes of the application without knowing its implementation. +You can configure and inject the Service Locator object on bootstrap. + +Examples +-------- + +- Zend Framework 2 uses Service Locator to create and share services + used in the framework(i.e. EventManager, ModuleManager, all custom + user services provided by modules, etc...) + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt ServiceLocator UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +LogService.php + +.. literalinclude:: LogService.php + :language: php + :linenos: + +LogServiceInterface.php + +.. literalinclude:: LogServiceInterface.php + :language: php + :linenos: + +DatabaseServiceInterface.php + +.. literalinclude:: DatabaseServiceInterface.php + :language: php + :linenos: + +ServiceLocatorInterface.php + +.. literalinclude:: ServiceLocatorInterface.php + :language: php + :linenos: + +ServiceLocator.php + +.. literalinclude:: ServiceLocator.php + :language: php + :linenos: + +DatabaseService.php + +.. literalinclude:: DatabaseService.php + :language: php + :linenos: + +Test +---- + +Tests/ServiceLocatorTest.php + +.. literalinclude:: Tests/ServiceLocatorTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/More/ServiceLocator diff --git a/More/index.rst b/More/index.rst new file mode 100644 index 0000000..fd0cfb9 --- /dev/null +++ b/More/index.rst @@ -0,0 +1,18 @@ +More +==== + +- `Delegation `__ + `:notebook: `__ +- `ServiceLocator `__ + `:notebook: `__ +- `Repository `__ + +Code +---- + +You can also find these code on `GitHub`_ + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/More diff --git a/Structural/Adapter/index.rst b/Structural/Adapter/index.rst new file mode 100644 index 0000000..5d843dd --- /dev/null +++ b/Structural/Adapter/index.rst @@ -0,0 +1,70 @@ +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 + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Adapter UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +PaperBookInterface.php + +.. literalinclude:: PaperBookInterface.php + :language: php + :linenos: + +EBookInterface.php + +.. literalinclude:: EBookInterface.php + :language: php + :linenos: + +EBookAdapter.php + +.. literalinclude:: EBookAdapter.php + :language: php + :linenos: + +Kindle.php + +.. literalinclude:: Kindle.php + :language: php + :linenos: + +Book.php + +.. literalinclude:: Book.php + :language: php + :linenos: + +Test +---- + +Tests/AdapterTest.php + +.. literalinclude:: Tests/AdapterTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/Adapter diff --git a/Structural/Bridge/index.rst b/Structural/Bridge/index.rst new file mode 100644 index 0000000..e83c84c --- /dev/null +++ b/Structural/Bridge/index.rst @@ -0,0 +1,70 @@ +Purpose +------- + +Decouple an abstraction from its implementation so that the two can vary +independently. (http://en.wikipedia.org/wiki/Bridge\_pattern) + +Sample: +^^^^^^^ + +- `Symfony + DoctrineBridge `__ + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Bridge UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Assemble.php + +.. literalinclude:: Assemble.php + :language: php + :linenos: + +Workshop.php + +.. literalinclude:: Workshop.php + :language: php + :linenos: + +Car.php + +.. literalinclude:: Car.php + :language: php + :linenos: + +Motorcycle.php + +.. literalinclude:: Motorcycle.php + :language: php + :linenos: + +Vehicle.php + +.. literalinclude:: Vehicle.php + :language: php + :linenos: + +Produce.php + +.. literalinclude:: Produce.php + :language: php + :linenos: + +Test +---- + +Tests/BridgeTest.php + +.. literalinclude:: Tests/BridgeTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/Bridge diff --git a/Structural/Composite/index.rst b/Structural/Composite/index.rst new file mode 100644 index 0000000..ad59cc2 --- /dev/null +++ b/Structural/Composite/index.rst @@ -0,0 +1,64 @@ +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 through all its child elements and calls ``render()`` on them +- ``Zend_Config``: a tree of configuration options, each one is a + ``Zend_Config`` object itself + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Composite UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +FormElement.php + +.. literalinclude:: FormElement.php + :language: php + :linenos: + +Form.php + +.. literalinclude:: Form.php + :language: php + :linenos: + +InputElement.php + +.. literalinclude:: InputElement.php + :language: php + :linenos: + +TextElement.php + +.. literalinclude:: TextElement.php + :language: php + :linenos: + +Test +---- + +Tests/CompositeTest.php + +.. literalinclude:: Tests/CompositeTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/Composite diff --git a/Structural/DataMapper/index.rst b/Structural/DataMapper/index.rst new file mode 100644 index 0000000..cd51e7a --- /dev/null +++ b/Structural/DataMapper/index.rst @@ -0,0 +1,59 @@ +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" + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt DataMapper UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +UserMapper.php + +.. literalinclude:: UserMapper.php + :language: php + :linenos: + +User.php + +.. literalinclude:: User.php + :language: php + :linenos: + +Test +---- + +Tests/DataMapperTest.php + +.. literalinclude:: Tests/DataMapperTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/DataMapper diff --git a/Structural/Decorator/index.rst b/Structural/Decorator/index.rst new file mode 100644 index 0000000..6ace194 --- /dev/null +++ b/Structural/Decorator/index.rst @@ -0,0 +1,67 @@ +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) + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Decorator UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +RendererInterface.php + +.. literalinclude:: RendererInterface.php + :language: php + :linenos: + +RenderInXml.php + +.. literalinclude:: RenderInXml.php + :language: php + :linenos: + +Webservice.php + +.. literalinclude:: Webservice.php + :language: php + :linenos: + +RenderInJson.php + +.. literalinclude:: RenderInJson.php + :language: php + :linenos: + +Decorator.php + +.. literalinclude:: Decorator.php + :language: php + :linenos: + +Test +---- + +Tests/DecoratorTest.php + +.. literalinclude:: Tests/DecoratorTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/Decorator diff --git a/Structural/DependencyInjection/index.rst b/Structural/DependencyInjection/index.rst new file mode 100644 index 0000000..544cc64 --- /dev/null +++ b/Structural/DependencyInjection/index.rst @@ -0,0 +1,87 @@ +Dependency Injection +==================== + +Purpose +------- + +To implement a loosely coupled architecture in order to get better +testable, maintainable and extendable code. + +Usage +----- + +Configuration gets injected and ``Connection`` will get all that it +needs from ``$config``. Without DI, the configuration would be created +directly in ``Connection``, which is not very good for testing and +extending ``Connection``. + +Notice we are following Inversion of control principle in ``Connection`` +by asking ``$config`` to implement ``Parameters`` interface. This +decouples our components. We don't care where the source of information +comes from, we only care that ``$config`` has certain methods to +retrieve that information. Read more about Inversion of control +`here `__. + +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) + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt DependencyInjection UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Connection.php + +.. literalinclude:: Connection.php + :language: php + :linenos: + +ArrayConfig.php + +.. literalinclude:: ArrayConfig.php + :language: php + :linenos: + +AbstractConfig.php + +.. literalinclude:: AbstractConfig.php + :language: php + :linenos: + +Parameters.php + +.. literalinclude:: Parameters.php + :language: php + :linenos: + +Test +---- + +Tests/DependencyInjectionTest.php + +.. literalinclude:: Tests/DependencyInjectionTest.php + :language: php + :linenos: + +Tests/config.php + +.. literalinclude:: Tests/config.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/DependencyInjection diff --git a/Structural/Facade/index.rst b/Structural/Facade/index.rst new file mode 100644 index 0000000..6df49cc --- /dev/null +++ b/Structural/Facade/index.rst @@ -0,0 +1,65 @@ +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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Facade UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +OsInterface.php + +.. literalinclude:: OsInterface.php + :language: php + :linenos: + +Facade.php + +.. literalinclude:: Facade.php + :language: php + :linenos: + +BiosInterface.php + +.. literalinclude:: BiosInterface.php + :language: php + :linenos: + +Test +---- + +Tests/FacadeTest.php + +.. literalinclude:: Tests/FacadeTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/Facade diff --git a/Structural/FluentInterface/index.rst b/Structural/FluentInterface/index.rst new file mode 100644 index 0000000..80adfbe --- /dev/null +++ b/Structural/FluentInterface/index.rst @@ -0,0 +1,45 @@ +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 + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt FluentInterface UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Sql.php + +.. literalinclude:: Sql.php + :language: php + :linenos: + +Test +---- + +Tests/FluentInterfaceTest.php + +.. literalinclude:: Tests/FluentInterfaceTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/FluentInterface diff --git a/Structural/Proxy/index.rst b/Structural/Proxy/index.rst new file mode 100644 index 0000000..a7ce379 --- /dev/null +++ b/Structural/Proxy/index.rst @@ -0,0 +1,43 @@ +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 + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Proxy UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +RecordProxy.php + +.. literalinclude:: RecordProxy.php + :language: php + :linenos: + +Record.php + +.. literalinclude:: Record.php + :language: php + :linenos: + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/Proxy diff --git a/Structural/Registry/index.rst b/Structural/Registry/index.rst new file mode 100644 index 0000000..b63e1c6 --- /dev/null +++ b/Structural/Registry/index.rst @@ -0,0 +1,46 @@ +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. + +UML Diagram +----------- + +.. image:: uml/uml.png + :alt: Alt Registry UML Diagram + :align: center + +Code +---- + +You can also find these code on `GitHub`_ + +Registry.php + +.. literalinclude:: Registry.php + :language: php + :linenos: + +Test +---- + +Tests/RegistryTest.php + +.. literalinclude:: Tests/RegistryTest.php + :language: php + :linenos: + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/Registry diff --git a/Structural/index.rst b/Structural/index.rst new file mode 100644 index 0000000..49867ee --- /dev/null +++ b/Structural/index.rst @@ -0,0 +1,37 @@ +Structural +========== + +In Software Engineering, Structural Design Patterns are Design Patterns +that ease the design by identifying a simple way to realize +relationships between entities. + +- `Adapter `__ + `:notebook: `__ +- `Bridge `__ + `:notebook: `__ +- `Composite `__ + `:notebook: `__ +- `DataMapper `__ + `:notebook: `__ +- `Decorator `__ + `:notebook: `__ +- `DependencyInjection `__ + `:notebook: `__ +- `Facade `__ + `:notebook: `__ +- `FluentInterface `__ + `:notebook: `__ +- `Proxy `__ + `:notebook: `__ +- `Registry `__ + `:notebook: `__ + +Code +---- + +You can also find these code on `GitHub`_ + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural diff --git a/index.rst b/index.rst new file mode 100644 index 0000000..d6bb000 --- /dev/null +++ b/index.rst @@ -0,0 +1,153 @@ +DesignPatternsPHP +================= + +|Build Status| + +This is a collection of known design patterns and some sample code how +to implement them in PHP. Every pattern has a small list of examples +(most of them from Zend Framework, Symfony2 or Doctrine2 as I'm most +familiar with this software). + +I think the problem with patterns is that often people do know them but +don't know when to apply which. + +Patterns +-------- + +The patterns can be structured in roughly three different categories. +Please click on the +`:notebook: `__ +for a full explanation of the pattern on Wikipedia. + +`Creational `__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `AbstractFactory `__ + `:notebook: `__ +- `Builder `__ + `:notebook: `__ +- `FactoryMethod `__ + `:notebook: `__ +- `Multiton `__ (is considered an anti-pattern! + :no\_entry:) +- `Pool `__ + `:notebook: `__ +- `Prototype `__ + `:notebook: `__ +- `SimpleFactory `__ +- `Singleton `__ + `:notebook: `__ (is + considered an anti-pattern! :no\_entry:) +- `StaticFactory `__ + +`Structural `__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `Adapter `__ + `:notebook: `__ +- `Bridge `__ + `:notebook: `__ +- `Composite `__ + `:notebook: `__ +- `DataMapper `__ + `:notebook: `__ +- `Decorator `__ + `:notebook: `__ +- `DependencyInjection `__ + `:notebook: `__ +- `Facade `__ + `:notebook: `__ +- `FluentInterface `__ + `:notebook: `__ +- `Proxy `__ + `:notebook: `__ +- `Registry `__ + `:notebook: `__ + +`Behavioral `__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `ChainOfResponsibilities `__ + `:notebook: `__ +- `Command `__ + `:notebook: `__ +- `Iterator `__ + `:notebook: `__ +- `Mediator `__ + `:notebook: `__ +- `Memento `__ + `:notebook: `__ +- `NullObject `__ + `:notebook: `__ +- `Observer `__ + `:notebook: `__ +- `Specification `__ + `:notebook: `__ +- `State `__ + `:notebook: `__ +- `Strategy `__ + `:notebook: `__ +- `TemplateMethod `__ + `:notebook: `__ +- `Visitor `__ + `:notebook: `__ + +`More `__ +~~~~~~~~~~~~~~~ + +- `Delegation `__ + `:notebook: `__ +- `ServiceLocator `__ + `:notebook: `__ +- `Repository `__ + +Contribute +---------- + +Please feel free to fork and extend existing or add your own examples +and send a pull request with your changes! To establish a consistent +code quality, please check your code using +`PHP\_CodeSniffer `__ +against `PSR2 +standard `__ +using ``./vendor/bin/phpcs -p --standard=PSR2 --ignore=vendor .``. + +License +------- + +(The MIT License) + +Copyright (c) 2014 Dominik Liebler and +`contributors `__ + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +.. |Build Status| image:: https://travis-ci.org/domnikl/DesignPatternsPHP.png?branch=master + :target: https://travis-ci.org/domnikl/DesignPatternsPHP + +Code +---- + +You can also find these code on `GitHub`_ + +Test +---- + +.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/