SlideShare ist ein Scribd-Unternehmen logo
1 von 37
Downloaden Sie, um offline zu lesen
Services, Mappers,
Models: Enterprise
Thinking in PHP
Aaron Saray - MKEPUG
Why trust this guy?
              ● 21 years:
                programmer
              ● 12 years: internet
                programmer
              ● PHP Design
                Patterns - WROX
              ● Manager of Web
                Team @ LPi

              ● So handsome
Disclaimer!!
I don't have a BS CS. But that doesn't matter.
Best practices exist in programming.
Not everyone programs the same way.
There is more than one way to solve a problem.
Understand the core concepts, don't get hung
up on the minutiae.
For every solution I have, you can do it a
different way too. Yours may work too!
What are we talking
about today?
● Services, Mappers, Models
  ○ Go by a few different names
  ○ Mix and max

● Future proofing our solutions
  ○ separation of concerns
  ○ enterprise thinking

● Making life easier by investments up front
What are Models?
● Represent a true entity in your business
   ○ user, visitor
   ○ box, ps3, blu-ray movie

● They know about themselves in their current state
   ○ they don't know if they're incomplete
   ○ they don't know how they're populated


● Do logic from the business
   ○ logical transformation that makes sense in your
     realm
What are Models? (cont)
Examples:

● User:
  ○ first name, last name, age
     ■ calculates fullname
     ■ calculates user requires adult consent

● PS3
  ○ serial number, model number
    ■ calculates date manufactured from serial #
What are Models? (cont 2)
Out of the realm of model:

● Have I been saved to the database?

● Have I been created from a form input or a
  MySQL result set?

● How can I get more information about
  myself?
What are Mappers?
● Mappers map data to a model

● Mappers know about models. Models do not
  know about mappers.

● Mappers are dependent on the data source
  ○ Swap data sources? Introduce a new mapper!
What are Mappers? (cont)
● Mapper interprets a request and creates a
  corresponding call to MySQL
  ○ request for a package with ID #7, create MySQL call
    for that, get results, apply to the model I received.

● Mapper applies data results to a model in
  the proper way

● Mappers are very foreign to most
  ○ Most Frameworks provide generic ones with "magic"
  ○ Most custom code lacks mappers
What are Services?
● Services are the way that the rest of the
  code requests objects

● Services know about a Model, and it's
  corresponding Mapper. Models and
  Mappers don't know about services.

● Services interpret requests, create new
  models, and invoke mappers to populate
  models.
What are Services? (cont)
● Services understand logical identifiers of
  models
   ○ fetchById()

● Services can create containers or single
  result sets
   ○ fetchPaginator(), fetchByEmail()

● Services retrieve and persist data
   ○ fetching / saving / updating
What are Services? (cont2)
● Services rarely change once created
  ○   Mappers change with new data sets
  ○   Models change with new logic
  ○   Retrieval methods are relatively stoic
  ○   Persistence methods CAN change more often
Show me an example!
 Show User
 Details for
  User # 5

  UserService::fetchById(5)          new User();

                              UserMapper MySQL query
                                      ID = 5
Yay!


                              Apply fetchAssoc to model
Example Code:
● It's easy for me to show you a perfect
  situation
  ○ But unless you're making something brand new, it's
    not really feasible

● Let's look at some novice PHP code
  ○ and refactor to Enterprise Thinking code!
What we're accomplishing?
● Will use MySQL to retrieve user information

● Want to show the full name, email address,
  of user 5 on the screen

●   Don't do this!
Controller Code
Class Code - Part 1
Class Code - Part 2
So What's Wrong
With This?
● From my introduction, you can spot some
  things

● What are they?
Bad Things:




         Seems like the User model is in charge of retrieving
         data based off the ID
More Bad Things
                  I'm not sure if this data is
                  coming from the database -
                  where the rest is. It's a one-off




                           Yup, the user has to
                           populate itself, plus it
                           has to understand that
                           this is a key.
More Bad Things:

                                                        The model is now forever
                                                        tied to the data source,
                                                        and must be modified if it
                                                        changes.




                                                               Here logic is being done
 The model is mapping itself to the data set results.          in the model. That's fine.
 If a data source is changed, even the creation of             However, it's using map-
 "full name" is lost.                                          able data. :(
Save me!
● Model should be only concerned with itself
   ○ full name is logic

● Mapper should connect and retrieve MySQL
  data and apply it to the model

● Service should be initialized in the controller
  and retrieve the proper user of ID 5
A Simpler User Model
                                                 No population. Only stores data,
                                                 and calculations (see below).




   Creating a full name is actually a logical calculation. For example,
   American name, this is correct.
   Latino heritage full name may contain multiple last names.
Mapper for MySQL
            Only for MySQL - this is important!!



                   Mapper creates connection.




                                Mapper understands ID,
                                but has to receive a new
                                user instance. Can't
                                create one itself.



                                  Retrieve data, and
                                  apply it to the object.
User Service


                           Initialize a User
                           for the mapper.

                                               Get new
                                               mapper.
                                               Send to
                                               mapper the
                                               user and the
                                               data access
                                               pointer
                                               (user id).
               Return the properly
               populated model to
               the requestor.
Updated Controller Code
                     Instead of creating a new
                     User object, create a
                     new service object.
                     Then, ask the service for
                     the user of ID #5.




                  Don't forget! The full
                  name is not really a
                  property - so now it's a
                  method call in our code.
What was gained?
● Model now only deals with business
  information

● Service can easily ask for and interpret
  requests for particular models

● Bound our mapper to MySQL
   ○ made it easier to swap out data sources
Ruh Roh!
● Requirements change!

● Choose your poison:
  ○ your boss said to new partner "it won't be a big deal,
    of COURSE we can use your feed instead of our
    database"

  ○ your client says "omg omg omg we now need to use
    this feed because it's the newest thing do it now!"
Requirement Change:
Instead of using MySQL, now all user data
must be retrieved from a XML feed request.

Using a GET request, call the feed URL with a
parameter of the user ID.

You can expect an XML document with one
node with the attribute as the ID, and nodes for
the user information.
What We Used to
Have to Do
● Back in the day
  ○   Open up the User class and modify code
  ○   Possibly delete old code and lose it
  ○   Modify the model even though nothing has changed
  ○   Cry
What we will do now
● Create a new mapper class named after the
  Remote XML feed
  ○ note: we don't have to get rid of any old code
    ■ what if boss changes his mind back?

● Change one line in Service class

● To summarize:
  ○ One line change of existing code
  ○ Rest is brand new code
    ■ SUCH A SMALL IMPACT
Fine: I did change the
controller




           The only change is including the new file instead. A good
           autoloader would have made this a non-issue. But, I had
           to show you this. Ignore it as a required 'change'
One line change in Service


                     See? Simple
                     little change. If I
                     want to go back
                     to the old code, I
                     can change this
                     mapper back.
New Mapper Class

                   Same method
                   call, just
                   different data
                   retrieval and
                   preparation.
Final Thoughts
● Probably should create a mapper interface -
  so that all mappers now have a mapFromId()
  method

● It is easy to swap back and forth with
  different data sources

● Business req changes are now easier
   ○ least impact on each individual part
The End

                       Aaron Saray
             Milwaukee PHP Web Developer


Questions?       http://aaronsaray.com

                         @aaronsaray

Weitere ähnliche Inhalte

Was ist angesagt?

Everyday Functional Programming in JavaScript
Everyday Functional Programming in JavaScriptEveryday Functional Programming in JavaScript
Everyday Functional Programming in JavaScriptLeo Hernandez
 
Web development basics (Part-1)
Web development basics (Part-1)Web development basics (Part-1)
Web development basics (Part-1)Rajat Pratap Singh
 
Web development basics (Part-2)
Web development basics (Part-2)Web development basics (Part-2)
Web development basics (Part-2)Rajat Pratap Singh
 
Javascript Roadmap - The Basics
Javascript Roadmap - The BasicsJavascript Roadmap - The Basics
Javascript Roadmap - The BasicsAswin Barath
 
JavaScript operators
JavaScript operatorsJavaScript operators
JavaScript operatorsVivek Kumar
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Matthias Noback
 
Java Script An Introduction By HWA
Java Script An Introduction By HWAJava Script An Introduction By HWA
Java Script An Introduction By HWAEmma Wood
 

Was ist angesagt? (12)

Everyday Functional Programming in JavaScript
Everyday Functional Programming in JavaScriptEveryday Functional Programming in JavaScript
Everyday Functional Programming in JavaScript
 
Java script ppt
Java script pptJava script ppt
Java script ppt
 
Web application
Web applicationWeb application
Web application
 
Web development basics (Part-1)
Web development basics (Part-1)Web development basics (Part-1)
Web development basics (Part-1)
 
Web development basics (Part-2)
Web development basics (Part-2)Web development basics (Part-2)
Web development basics (Part-2)
 
Html
HtmlHtml
Html
 
Javascript Roadmap - The Basics
Javascript Roadmap - The BasicsJavascript Roadmap - The Basics
Javascript Roadmap - The Basics
 
JavaScript operators
JavaScript operatorsJavaScript operators
JavaScript operators
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
 
Js slideshare
Js   slideshareJs   slideshare
Js slideshare
 
Java Script An Introduction By HWA
Java Script An Introduction By HWAJava Script An Introduction By HWA
Java Script An Introduction By HWA
 
Es6 features part 1
Es6 features part 1Es6 features part 1
Es6 features part 1
 

Andere mochten auch

Proved PHP Design Patterns for Data Persistence
Proved PHP Design Patterns for Data PersistenceProved PHP Design Patterns for Data Persistence
Proved PHP Design Patterns for Data PersistenceGjero Krsteski
 
Clean architecture with ddd layering in php
Clean architecture with ddd layering in phpClean architecture with ddd layering in php
Clean architecture with ddd layering in phpLeonardo Proietti
 
Implementing DDD Concepts in PHP
Implementing DDD Concepts in PHPImplementing DDD Concepts in PHP
Implementing DDD Concepts in PHPSteve Rhoades
 
Anatomy of a Modern PHP Application Architecture
Anatomy of a Modern PHP Application Architecture Anatomy of a Modern PHP Application Architecture
Anatomy of a Modern PHP Application Architecture AppDynamics
 
10 commandments for better android development
10 commandments for better android development10 commandments for better android development
10 commandments for better android developmentTrey Robinson
 
We Built It, And They Didn't Come!
We Built It, And They Didn't Come!We Built It, And They Didn't Come!
We Built It, And They Didn't Come!Lukas Fittl
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objectsjulien pauli
 
Visual guide to selling software as a service by @prezly
Visual guide to selling software as a service by @prezlyVisual guide to selling software as a service by @prezly
Visual guide to selling software as a service by @prezlyPrezly
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
Composer The Right Way - 010PHP
Composer The Right Way - 010PHPComposer The Right Way - 010PHP
Composer The Right Way - 010PHPRafael Dohms
 
Programming objects with android
Programming objects with androidProgramming objects with android
Programming objects with androidfirenze-gtug
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHPGuilherme Blanco
 
Kicking the Bukkit: Anatomy of an open source meltdown
Kicking the Bukkit: Anatomy of an open source meltdownKicking the Bukkit: Anatomy of an open source meltdown
Kicking the Bukkit: Anatomy of an open source meltdownRyanMichela
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practicesfloydophone
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projectsIgnacio Martín
 
From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...Jérôme Petazzoni
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
 
From Idea to Execution: Spotify's Discover Weekly
From Idea to Execution: Spotify's Discover WeeklyFrom Idea to Execution: Spotify's Discover Weekly
From Idea to Execution: Spotify's Discover WeeklyChris Johnson
 

Andere mochten auch (20)

Proved PHP Design Patterns for Data Persistence
Proved PHP Design Patterns for Data PersistenceProved PHP Design Patterns for Data Persistence
Proved PHP Design Patterns for Data Persistence
 
Clean architecture with ddd layering in php
Clean architecture with ddd layering in phpClean architecture with ddd layering in php
Clean architecture with ddd layering in php
 
Implementing DDD Concepts in PHP
Implementing DDD Concepts in PHPImplementing DDD Concepts in PHP
Implementing DDD Concepts in PHP
 
Anatomy of a Modern PHP Application Architecture
Anatomy of a Modern PHP Application Architecture Anatomy of a Modern PHP Application Architecture
Anatomy of a Modern PHP Application Architecture
 
10 commandments for better android development
10 commandments for better android development10 commandments for better android development
10 commandments for better android development
 
We Built It, And They Didn't Come!
We Built It, And They Didn't Come!We Built It, And They Didn't Come!
We Built It, And They Didn't Come!
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
 
Visual guide to selling software as a service by @prezly
Visual guide to selling software as a service by @prezlyVisual guide to selling software as a service by @prezly
Visual guide to selling software as a service by @prezly
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Composer The Right Way - 010PHP
Composer The Right Way - 010PHPComposer The Right Way - 010PHP
Composer The Right Way - 010PHP
 
Programming objects with android
Programming objects with androidProgramming objects with android
Programming objects with android
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
 
Kicking the Bukkit: Anatomy of an open source meltdown
Kicking the Bukkit: Anatomy of an open source meltdownKicking the Bukkit: Anatomy of an open source meltdown
Kicking the Bukkit: Anatomy of an open source meltdown
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practices
 
Clean code
Clean codeClean code
Clean code
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
How to Design Indexes, Really
How to Design Indexes, ReallyHow to Design Indexes, Really
How to Design Indexes, Really
 
From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
From Idea to Execution: Spotify's Discover Weekly
From Idea to Execution: Spotify's Discover WeeklyFrom Idea to Execution: Spotify's Discover Weekly
From Idea to Execution: Spotify's Discover Weekly
 

Ähnlich wie Enterprise PHP: mappers, models and services

BSSML16 L10. Summary Day 2 Sessions
BSSML16 L10. Summary Day 2 SessionsBSSML16 L10. Summary Day 2 Sessions
BSSML16 L10. Summary Day 2 SessionsBigML, Inc
 
Universal job embedding in recommendation (public ver.)
Universal job embedding in recommendation (public ver.)Universal job embedding in recommendation (public ver.)
Universal job embedding in recommendation (public ver.)Marsan Ma
 
Choosing the Right Database - Facebook DevC Malang Hackdays 2017
Choosing the Right Database - Facebook DevC Malang Hackdays 2017Choosing the Right Database - Facebook DevC Malang Hackdays 2017
Choosing the Right Database - Facebook DevC Malang Hackdays 2017Rendy Bambang Junior
 
SOA with Zend Framework
SOA with Zend FrameworkSOA with Zend Framework
SOA with Zend FrameworkMike Willbanks
 
Real world machine learning with Java for Fumankaitori.com
Real world machine learning with Java for Fumankaitori.comReal world machine learning with Java for Fumankaitori.com
Real world machine learning with Java for Fumankaitori.comMathieu Dumoulin
 
ML Platform Q1 Meetup: Airbnb's End-to-End Machine Learning Infrastructure
ML Platform Q1 Meetup: Airbnb's End-to-End Machine Learning InfrastructureML Platform Q1 Meetup: Airbnb's End-to-End Machine Learning Infrastructure
ML Platform Q1 Meetup: Airbnb's End-to-End Machine Learning InfrastructureFei Chen
 
Converting Your Legacy Data to S1000D
Converting Your Legacy Data to S1000DConverting Your Legacy Data to S1000D
Converting Your Legacy Data to S1000Ddclsocialmedia
 
Single Responsibility Principle
Single Responsibility PrincipleSingle Responsibility Principle
Single Responsibility PrincipleBADR
 
Designing and coding for cloud-native applications using Python, Harjinder Mi...
Designing and coding for cloud-native applications using Python, Harjinder Mi...Designing and coding for cloud-native applications using Python, Harjinder Mi...
Designing and coding for cloud-native applications using Python, Harjinder Mi...Pôle Systematic Paris-Region
 
Prototyping Workshop - Wireframes, Mockups, Prototypes
Prototyping Workshop - Wireframes, Mockups, PrototypesPrototyping Workshop - Wireframes, Mockups, Prototypes
Prototyping Workshop - Wireframes, Mockups, PrototypesMarta Soncodi
 
Machine Learning Startup
Machine Learning StartupMachine Learning Startup
Machine Learning StartupBen Lackey
 
Accelerating Data Science with Better Data Engineering on Databricks
Accelerating Data Science with Better Data Engineering on DatabricksAccelerating Data Science with Better Data Engineering on Databricks
Accelerating Data Science with Better Data Engineering on DatabricksDatabricks
 
Big data-science-oanyc
Big data-science-oanycBig data-science-oanyc
Big data-science-oanycOpen Analytics
 
BIG Data Science: A Path Forward
BIG Data Science:  A Path ForwardBIG Data Science:  A Path Forward
BIG Data Science: A Path ForwardDan Mallinger
 
Data Scenarios 2020: 6 Amazing Transformations
Data Scenarios 2020: 6 Amazing TransformationsData Scenarios 2020: 6 Amazing Transformations
Data Scenarios 2020: 6 Amazing TransformationsSafe Software
 
Social Analytics with MongoDB
Social Analytics with MongoDBSocial Analytics with MongoDB
Social Analytics with MongoDBPatrick Stokes
 

Ähnlich wie Enterprise PHP: mappers, models and services (20)

BSSML16 L10. Summary Day 2 Sessions
BSSML16 L10. Summary Day 2 SessionsBSSML16 L10. Summary Day 2 Sessions
BSSML16 L10. Summary Day 2 Sessions
 
Universal job embedding in recommendation (public ver.)
Universal job embedding in recommendation (public ver.)Universal job embedding in recommendation (public ver.)
Universal job embedding in recommendation (public ver.)
 
Choosing the Right Database - Facebook DevC Malang Hackdays 2017
Choosing the Right Database - Facebook DevC Malang Hackdays 2017Choosing the Right Database - Facebook DevC Malang Hackdays 2017
Choosing the Right Database - Facebook DevC Malang Hackdays 2017
 
SOA with Zend Framework
SOA with Zend FrameworkSOA with Zend Framework
SOA with Zend Framework
 
Real world machine learning with Java for Fumankaitori.com
Real world machine learning with Java for Fumankaitori.comReal world machine learning with Java for Fumankaitori.com
Real world machine learning with Java for Fumankaitori.com
 
Intro to ember.js
Intro to ember.jsIntro to ember.js
Intro to ember.js
 
ML Platform Q1 Meetup: Airbnb's End-to-End Machine Learning Infrastructure
ML Platform Q1 Meetup: Airbnb's End-to-End Machine Learning InfrastructureML Platform Q1 Meetup: Airbnb's End-to-End Machine Learning Infrastructure
ML Platform Q1 Meetup: Airbnb's End-to-End Machine Learning Infrastructure
 
Converting Your Legacy Data to S1000D
Converting Your Legacy Data to S1000DConverting Your Legacy Data to S1000D
Converting Your Legacy Data to S1000D
 
DevOps Days Rockies MLOps
DevOps Days Rockies MLOpsDevOps Days Rockies MLOps
DevOps Days Rockies MLOps
 
Single Responsibility Principle
Single Responsibility PrincipleSingle Responsibility Principle
Single Responsibility Principle
 
Designing and coding for cloud-native applications using Python, Harjinder Mi...
Designing and coding for cloud-native applications using Python, Harjinder Mi...Designing and coding for cloud-native applications using Python, Harjinder Mi...
Designing and coding for cloud-native applications using Python, Harjinder Mi...
 
Prototyping Workshop - Wireframes, Mockups, Prototypes
Prototyping Workshop - Wireframes, Mockups, PrototypesPrototyping Workshop - Wireframes, Mockups, Prototypes
Prototyping Workshop - Wireframes, Mockups, Prototypes
 
Project report
Project reportProject report
Project report
 
Machine Learning Startup
Machine Learning StartupMachine Learning Startup
Machine Learning Startup
 
Accelerating Data Science with Better Data Engineering on Databricks
Accelerating Data Science with Better Data Engineering on DatabricksAccelerating Data Science with Better Data Engineering on Databricks
Accelerating Data Science with Better Data Engineering on Databricks
 
Big data-science-oanyc
Big data-science-oanycBig data-science-oanyc
Big data-science-oanyc
 
BIG Data Science: A Path Forward
BIG Data Science:  A Path ForwardBIG Data Science:  A Path Forward
BIG Data Science: A Path Forward
 
Data Scenarios 2020: 6 Amazing Transformations
Data Scenarios 2020: 6 Amazing TransformationsData Scenarios 2020: 6 Amazing Transformations
Data Scenarios 2020: 6 Amazing Transformations
 
Python and data analytics
Python and data analyticsPython and data analytics
Python and data analytics
 
Social Analytics with MongoDB
Social Analytics with MongoDBSocial Analytics with MongoDB
Social Analytics with MongoDB
 

Enterprise PHP: mappers, models and services

  • 2. Why trust this guy? ● 21 years: programmer ● 12 years: internet programmer ● PHP Design Patterns - WROX ● Manager of Web Team @ LPi ● So handsome
  • 3. Disclaimer!! I don't have a BS CS. But that doesn't matter. Best practices exist in programming. Not everyone programs the same way. There is more than one way to solve a problem. Understand the core concepts, don't get hung up on the minutiae. For every solution I have, you can do it a different way too. Yours may work too!
  • 4. What are we talking about today? ● Services, Mappers, Models ○ Go by a few different names ○ Mix and max ● Future proofing our solutions ○ separation of concerns ○ enterprise thinking ● Making life easier by investments up front
  • 5. What are Models? ● Represent a true entity in your business ○ user, visitor ○ box, ps3, blu-ray movie ● They know about themselves in their current state ○ they don't know if they're incomplete ○ they don't know how they're populated ● Do logic from the business ○ logical transformation that makes sense in your realm
  • 6. What are Models? (cont) Examples: ● User: ○ first name, last name, age ■ calculates fullname ■ calculates user requires adult consent ● PS3 ○ serial number, model number ■ calculates date manufactured from serial #
  • 7. What are Models? (cont 2) Out of the realm of model: ● Have I been saved to the database? ● Have I been created from a form input or a MySQL result set? ● How can I get more information about myself?
  • 8. What are Mappers? ● Mappers map data to a model ● Mappers know about models. Models do not know about mappers. ● Mappers are dependent on the data source ○ Swap data sources? Introduce a new mapper!
  • 9. What are Mappers? (cont) ● Mapper interprets a request and creates a corresponding call to MySQL ○ request for a package with ID #7, create MySQL call for that, get results, apply to the model I received. ● Mapper applies data results to a model in the proper way ● Mappers are very foreign to most ○ Most Frameworks provide generic ones with "magic" ○ Most custom code lacks mappers
  • 10. What are Services? ● Services are the way that the rest of the code requests objects ● Services know about a Model, and it's corresponding Mapper. Models and Mappers don't know about services. ● Services interpret requests, create new models, and invoke mappers to populate models.
  • 11. What are Services? (cont) ● Services understand logical identifiers of models ○ fetchById() ● Services can create containers or single result sets ○ fetchPaginator(), fetchByEmail() ● Services retrieve and persist data ○ fetching / saving / updating
  • 12. What are Services? (cont2) ● Services rarely change once created ○ Mappers change with new data sets ○ Models change with new logic ○ Retrieval methods are relatively stoic ○ Persistence methods CAN change more often
  • 13. Show me an example! Show User Details for User # 5 UserService::fetchById(5) new User(); UserMapper MySQL query ID = 5 Yay! Apply fetchAssoc to model
  • 14. Example Code: ● It's easy for me to show you a perfect situation ○ But unless you're making something brand new, it's not really feasible ● Let's look at some novice PHP code ○ and refactor to Enterprise Thinking code!
  • 15. What we're accomplishing? ● Will use MySQL to retrieve user information ● Want to show the full name, email address, of user 5 on the screen ● Don't do this!
  • 17. Class Code - Part 1
  • 18. Class Code - Part 2
  • 19. So What's Wrong With This? ● From my introduction, you can spot some things ● What are they?
  • 20. Bad Things: Seems like the User model is in charge of retrieving data based off the ID
  • 21. More Bad Things I'm not sure if this data is coming from the database - where the rest is. It's a one-off Yup, the user has to populate itself, plus it has to understand that this is a key.
  • 22. More Bad Things: The model is now forever tied to the data source, and must be modified if it changes. Here logic is being done The model is mapping itself to the data set results. in the model. That's fine. If a data source is changed, even the creation of However, it's using map- "full name" is lost. able data. :(
  • 23. Save me! ● Model should be only concerned with itself ○ full name is logic ● Mapper should connect and retrieve MySQL data and apply it to the model ● Service should be initialized in the controller and retrieve the proper user of ID 5
  • 24. A Simpler User Model No population. Only stores data, and calculations (see below). Creating a full name is actually a logical calculation. For example, American name, this is correct. Latino heritage full name may contain multiple last names.
  • 25. Mapper for MySQL Only for MySQL - this is important!! Mapper creates connection. Mapper understands ID, but has to receive a new user instance. Can't create one itself. Retrieve data, and apply it to the object.
  • 26. User Service Initialize a User for the mapper. Get new mapper. Send to mapper the user and the data access pointer (user id). Return the properly populated model to the requestor.
  • 27. Updated Controller Code Instead of creating a new User object, create a new service object. Then, ask the service for the user of ID #5. Don't forget! The full name is not really a property - so now it's a method call in our code.
  • 28. What was gained? ● Model now only deals with business information ● Service can easily ask for and interpret requests for particular models ● Bound our mapper to MySQL ○ made it easier to swap out data sources
  • 29. Ruh Roh! ● Requirements change! ● Choose your poison: ○ your boss said to new partner "it won't be a big deal, of COURSE we can use your feed instead of our database" ○ your client says "omg omg omg we now need to use this feed because it's the newest thing do it now!"
  • 30. Requirement Change: Instead of using MySQL, now all user data must be retrieved from a XML feed request. Using a GET request, call the feed URL with a parameter of the user ID. You can expect an XML document with one node with the attribute as the ID, and nodes for the user information.
  • 31. What We Used to Have to Do ● Back in the day ○ Open up the User class and modify code ○ Possibly delete old code and lose it ○ Modify the model even though nothing has changed ○ Cry
  • 32. What we will do now ● Create a new mapper class named after the Remote XML feed ○ note: we don't have to get rid of any old code ■ what if boss changes his mind back? ● Change one line in Service class ● To summarize: ○ One line change of existing code ○ Rest is brand new code ■ SUCH A SMALL IMPACT
  • 33. Fine: I did change the controller The only change is including the new file instead. A good autoloader would have made this a non-issue. But, I had to show you this. Ignore it as a required 'change'
  • 34. One line change in Service See? Simple little change. If I want to go back to the old code, I can change this mapper back.
  • 35. New Mapper Class Same method call, just different data retrieval and preparation.
  • 36. Final Thoughts ● Probably should create a mapper interface - so that all mappers now have a mapFromId() method ● It is easy to swap back and forth with different data sources ● Business req changes are now easier ○ least impact on each individual part
  • 37. The End Aaron Saray Milwaukee PHP Web Developer Questions? http://aaronsaray.com @aaronsaray