Slide 1

Slide 1 text

Do you speak Design Patterns in PHP? Josh Butts, Ralph Schindler, Enrico Zimuel Tutorial ZendCon 2013

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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)

Slide 4

Slide 4 text

Design Patterns

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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.

Slide 12

Slide 12 text

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.

Slide 13

Slide 13 text

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.

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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.

Slide 18

Slide 18 text

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.

Slide 19

Slide 19 text

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.

Slide 20

Slide 20 text

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.

Slide 21

Slide 21 text

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.

Slide 22

Slide 22 text

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.

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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.

Slide 25

Slide 25 text

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"

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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.

Slide 28

Slide 28 text

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.

Slide 29

Slide 29 text

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.

Slide 30

Slide 30 text

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.

Slide 31

Slide 31 text

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.

Slide 32

Slide 32 text

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.

Slide 33

Slide 33 text

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.

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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.

Slide 36

Slide 36 text

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.

Slide 37

Slide 37 text

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.

Slide 38

Slide 38 text

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.

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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