Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Do you speak design patterns in PHP?

Do you speak design patterns in PHP?

In this tutorial we want to present some of the most used design patterns in PHP. We will introduce the patterns in a pratical way, that means coding! This tutorial has been presented at ZendCon 2013 in Santa Clara (California). http://www.zendcon.com

Enrico Zimuel

October 07, 2013
Tweet

More Decks by Enrico Zimuel

Other Decks in Programming

Transcript

  1. Do you speak Design Patterns in PHP? Josh Butts, Ralph

    Schindler, Enrico Zimuel Tutorial ZendCon 2013
  2. About us Ralph Schindler Software Engineer Zend Technologies Enrico Zimuel

    Software Engineer Zend Technologies Josh Butts Director of Development Offers.com
  3. Source code and exercise • All the design patterns that

    we are going to present are here: https://github.com/zfcampus/zendcon-design-patterns • For each pattern we prosed an exercise (exercise.php) that you can complete. Of course, we proposed also the solution (solution.php)
  4. Definition “A formal way of documenting a solution to a

    design problem in a particular field of expertise.” Wikipedia
  5. More? 1) Design Patterns act as a diction between developers

    2) They help describe common “blueprints”, which further might assist in … 3) Justifying a particular design decision
  6. How We’ll Present Patterns 1) Describe the problem 2) Describe

    the solution 3) Describe when it is applicable
  7. Some Non-pattern Best Practices & Things To Remember (About PHP)

    1. PHP’s object model is single inheritance / multiple interface 2. Interfaces are not required 3. Constructors are allowed in interfaces (but should never go there) 4. PHP is designed to be dynamic • new $myClass()
  8. Dependency Injection • Dependency injection is a software design pattern

    that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time • We're actually talking about Inversion of Control • Dependency Injection is the concept of introducing one or more dependent objects into a consuming object as to fulfill the consuming objects requirements
  9. Dependency Injection (2) • In practice, inversion of control /

    dependency injection is a style of software construction where reusable code controls the execution of problem-specific code. It carries the strong connotation that the reusable code and the problem-specific code are developed independently, which often results in a single integrated application. Inversion of control as a design guideline serves the following purposes: • There is a decoupling of the execution of a certain task from implementation • Every module can focus on what it is designed for • Modules make no assumptions about what other systems do but rely on their contracts • Replacing modules have no side effect on other modules • Hollywood Principle: "Don't call us, we'll call you".
  10. Dependency Injection (scenario) • You have many objects that need

    to talk to a database. Instead of opening multiple connections to the database, which is an object, you want to maintain a single instance and single open connection.
  11. 12 Strategy • The strategy pattern is essentially a system

    for for pluggable logic, designed to be easily switched out giving varying implementations of the same task. • This pattern is often used in sorting and filtering scenarios. It may also be used for data storage/persistance, and in a more concrete definition, adapters.
  12. 13 Strategy (scenario) • You have a collection of business

    objects that represent items for sale in a shopping cart system. You may want to allow users to narrow results in the view layer by various different criteria, depending on their tastes.
  13. Decorator • The Decorator is a design pattern that allows

    behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class
  14. Decorator (scenario) • You want to add a label and

    manage the error output for an InpuText class that manage input text from user's FORM
  15. FactoryMethod • The essence of the Factory Method Pattern is

    to "implement the concept of factories and deals with the problem of creating objects (products) without specifying the exact class of object that will be created."
  16. FactoryMethod (2) • This pattern is highly useful in situations

    where creating an actual concrete object is complex/expensive or the target concrete type is unknown to the caller. • When integrating separate systems. On one side, there is a framework that is providing significant value by solving the most common aspects of a problem. On the other side is the framework consumer who wants to build on the framework to fulfill specific use cases. Since the framework can't fully imagine all possible use cases, the framework plans for this ability to extend through abstraction. One such abstraction for object creation is a Factory Method.
  17. FactoryMethod (3) • In this particular pattern, the framework does

    not have to be burdened with how specific instances of a particular concrete type are created, it simply abstracts the creation into an interface that the framework consumer can them implement. The end result is framework consumer can fulfill his specific use cases surrounding object/instance creation in his own way, while leveraging the wholesale value added by the framework.
  18. FactoryMethod (scenario) • From the Framework side perspective: • You

    want to build a shopping cart framework, but you don't want to create concrete product model objects because you want your consumers to provide both the factory for product model objects as well as those speific product model objects.
  19. FactoryMethod (scenario) (2) • From the consumer side perspective: •

    You want to be able to build your product object model without having to extend a base product model provided by a shopping cart system. Ideally, you can develop your own product object model and simply introduce a mechanism into the shopping cart framework that can then consume these product objects.
  20. Observer • The observer pattern is used to promote loose

    coupling between objects. "Subjects" may be subscribed to by "Observers", such that hanges to the subject trigger a notification to one or more observers. Usually, the observers are passed the entire subject as context.
  21. Observer (scenario) • A data model may be changed from

    various different points in the code. You want to implement a logger that keeps track of when the model changes.
  22. 23 Proxy • A proxy, in its most general form,

    is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate • In situations where multiple copies of a complex object must exist, the proxy pattern can be adapted to incorporate the flyweight pattern in order to reduce the application's memory footprint. Typically, one instance of the complex object and multiple proxy objects are created, all of which contain a reference to the single original complex object
  23. 24 Proxy (scenario) • Imagine you have an Image class

    that loads the file on constructor. We want to create a Proxy class that loads the image only if needed, for instance only during the dispaly.
  24. Abstract Factory • The essence of the Abstract Factory Pattern

    is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes"
  25. Abstract Factory (2) • This pattern is highly useful when

    integrating separate systems. On one side, there is a framework that is providing significant value by solving the most common aspects of a problem. On the other side is the framework consumer who wants to build on the framework to fulfill specific use cases. Since the framework can't fully imagine all possible use cases, the framework plans for this ability to extend through abstraction. One such abstraction is an Abstract Factory
  26. Abstract Factory (3) • In this particular pattern, the framework

    does not have to be burdened with how many specific instances of a particular concrete type are created, it simply abstracts the creation of those concrete types into an interface that the framework consumer can them implement. The end result is framework consumer can fulfill his specific use cases surrounding object/instance creation in his own way, while leveraging the wholesale value added by the framework.
  27. Abstract Factory (scenario) • From the Framework side perspective: •

    You want to build a shopping cart framework, but you don't want to create concrete product model and shipping method objects because you want your consumers to provide both the factory for product & shipping method model objects as well as those speific product and shipping method objects.
  28. Abstract Factory (scenario) (2) • From the consumer side perspective:

    • You want to be able to build your product and shipping method object model without having to extend a base model provided by a shopping cart system. Ideally, you can develop your own product object model and simply introduce a mechanism into the shopping cart framework that can then consume these product objects.
  29. Prototype • The prototype pattern is a creational design pattern.

    It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.
  30. Prototype (2) • This pattern is used to: • avoid

    subclasses of an object creator in the client application, like the abstract factory pattern does; • avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application. • Prohibitively expensive could mean that the object's creation workflow is too involved or it could mean that computationally "cloning" an existing object is less expensive than using the "new" operator. This is especially useful when you want to deal with sets of objects that have a small amount of variation but might also share a set of dependencies.
  31. Prototype (scenario) • Similar to the Factory Method, we want

    to delegate the creation of a particular object type to the consumer. Instead of using a factory, and because we know there will be a large set of these objects the might have wired dependencies, this particular extension point will use prototypical object creation: the prototype pattern.
  32. Adapter • Adapters are used to take the public API's

    of classes that would not otherwise be compatible, and layer on top of them a common interface. Generally, the adapter class will contain a reference to a concrete instance of the adaptee. • Examples of adapters include: Database adapters / drivers, cache adapters, and third-party API adapters.
  33. Adapter (scenario) • You want to accept payments online from

    both paypal and standard credit cards, but the APIs for this are quite different
  34. 35 Visitor • The Visitor design pattern is a way

    of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures. It is one way to follow the open/closed principle. • In essence, the visitor allows one to add new virtual functions to a family of classes without modifying the classes themselves; instead, one creates a visitor class that implements all of the appropriate specializations of the virtual function.
  35. 36 Visitor (scenario) • We want to implement a simple

    data structure that manages GET or POST input data, being it single or multiple values. We want to implement a pair of Visitor pattern to define operations on these data structures.
  36. Data Mapper • Mapper patterns are used to translate data

    from one state into another. Most often, mappers are used to convert "flat" data into an object graph, or vice-versa, as you would do when savnig and retrieving objects from a database. The key point of the mapper pattern is that the objects don't need to be aware of the interfaces of the other states that the mapper may be aware of. • Mappers also promote loose coupling and separation of concerns. Many ORM systems use a datamapper pattern. Doctrine 2.x uses datamappers, whereas Doctrine 1.x used an ActiveRecord pattern, which does not allow for separation of business logic and persistence.
  37. Data Mapper (scenario) • Data from a database (in associative

    array form) needs to be converted into model objects. At some point in the future, those objects need to be mapped back into associative array form to be written back to the database.
  38. 39 Iterator • The iterator pattern is a design pattern

    in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled
  39. 40 Iterator (scenario) • We want to implement the Fibonacci

    series of numbers using the PHP Iterator pattern: http://php.net/manual/en/class.iterator.php
  40. 41 References Books: • E.Gamma, R.Helm, R.Johnson, J.Vissided, Design Patterns:

    Elements of Reusable Object-Oriented Software, Addison-Wesley Professional, 1994 • Martin Fowler, Patterns of Enterprise Application Architecture, Addison-Wesley Professional, 2012 • William Sanders, Learning PHP Design Patterns, O'Reilly Media, 2013 • Matt Zandstra, PHP Objects, Patterns and Practice, Apress, 2010 Web: • https://github.com/domnikl/DesignPatternsPHP • https://speakerdeck.com/ezimuel/design-patterns-bootcamp