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

    View Slide

  2. About us
    Ralph Schindler
    Software Engineer
    Zend Technologies
    Enrico Zimuel
    Software Engineer
    Zend Technologies
    Josh Butts
    Director of Development
    Offers.com

    View Slide

  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)

    View Slide

  4. Design Patterns

    View Slide

  5. Definition
    “A formal way of documenting a solution
    to a design problem in a particular field
    of expertise.”
    Wikipedia

    View Slide

  6. 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

    View Slide

  7. How We’ll Present Patterns
    1) Describe the problem
    2) Describe the solution
    3) Describe when it is applicable

    View Slide

  8. 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()

    View Slide

  9. 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

    View Slide

  10. 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".

    View Slide

  11. 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.

    View Slide

  12. 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.

    View Slide

  13. 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.

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. 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."

    View Slide

  17. 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.

    View Slide

  18. 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.

    View Slide

  19. 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.

    View Slide

  20. 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.

    View Slide

  21. 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.

    View Slide

  22. 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.

    View Slide

  23. 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

    View Slide

  24. 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.

    View Slide

  25. 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"

    View Slide

  26. 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

    View Slide

  27. 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.

    View Slide

  28. 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.

    View Slide

  29. 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.

    View Slide

  30. 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.

    View Slide

  31. 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.

    View Slide

  32. 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.

    View Slide

  33. 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.

    View Slide

  34. Adapter (scenario)

    You want to accept payments online from both
    paypal and standard credit cards, but the APIs for
    this are quite different

    View Slide

  35. 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.

    View Slide

  36. 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.

    View Slide

  37. 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.

    View Slide

  38. 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.

    View Slide

  39. 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

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

  42. Thanks!
    Vote this talk at https://joind.in/9045

    View Slide