Advanced OO PatternsOSI Days 2011
Tobias Schlitt (@tobySen)
November 21, 2011
Advanced OO Patterns 1 / 56
Outline
Introduction
Dependency Injection
Service Locator
Data Storage
Advanced OO Patterns 2 / 56
About me
I Degree in computer sience
I Prof. PHP since 1999
I Open source enthusiast
I FLOSS contributor
Qafoopassion for software quality
Advanced OO Patterns 3 / 56
About me
I Degree in computer sience
I Prof. PHP since 1999
I Open source enthusiast
I FLOSS contributor
Co-founder of
Qafoopassion for software quality
Advanced OO Patterns 3 / 56
About me
I Degree in computer sience
I Prof. PHP since 1999
I Open source enthusiast
I FLOSS contributor
Co-founder of
Qafoopassion for software quality
Helping teams to createhigh quality PHP software.
Advanced OO Patterns 3 / 56
About me
I Degree in computer sience
I Prof. PHP since 1999
I Open source enthusiast
I FLOSS contributor
Co-founder of
Qafoopassion for software quality
Helping teams to createhigh quality PHP software.
http://qafoo.com
Advanced OO Patterns 3 / 56
Disclaimer
I This talk cannot be in depth
I This talk shall inspire you
I This talk will not show UML diagrams
I This talk will show you quite some code
I This talk can seriously harm your coding habbits
Advanced OO Patterns 4 / 56
Disclaimer
I This talk cannot be in depth
I This talk shall inspire you
I This talk will not show UML diagrams
I This talk will show you quite some code
I This talk can seriously harm your coding habbits
Advanced OO Patterns 4 / 56
Disclaimer
I This talk cannot be in depth
I This talk shall inspire you
I This talk will not show UML diagrams
I This talk will show you quite some code
I This talk can seriously harm your coding habbits
Advanced OO Patterns 4 / 56
Disclaimer
I This talk cannot be in depth
I This talk shall inspire you
I This talk will not show UML diagrams
I This talk will show you quite some code
I This talk can seriously harm your coding habbits
Advanced OO Patterns 4 / 56
Disclaimer
I This talk cannot be in depth
I This talk shall inspire you
I This talk will not show UML diagrams
I This talk will show you quite some code
I This talk can seriously harm your coding habbits
Advanced OO Patterns 4 / 56
Patterns are . . .
. . . names for proven ideas how a certain class of problemscan be solved.
Advanced OO Patterns 5 / 56
Patterns are not . . .
I . . . appliable to every problem.
I . . . directly transferable to code.
I . . . written in stone.
I . . . always the best solution.
Advanced OO Patterns 6 / 56
Pattern classification
I Creational
I Structural
I Behavioural
I Architectural
Advanced OO Patterns 7 / 56
Well known patterns
Factory
Adapter
Iterator
Singleton
Signal / Observer
Visitor
Advanced OO Patterns 8 / 56
Well known patterns
Factory
Adapter
Iterator
Singleton
Signal / Observer
Visitor
Advanced OO Patterns 8 / 56
Outline
Introduction
Dependency Injection
Service Locator
Data Storage
Advanced OO Patterns 9 / 56
Goals of good OO design
I Modular
I Flexible
I Reusable
I Testable
I S.O.L.I.D.(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
Advanced OO Patterns 10 / 56
Goals of good OO design
I Modular
I Flexible
I Reusable
I Testable
I S.O.L.I.D.(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
Advanced OO Patterns 10 / 56
Goals of good OO design
I Modular
I Flexible
I Reusable
I Testable
I S.O.L.I.D.(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
Advanced OO Patterns 10 / 56
Goals of good OO design
I Modular
I Flexible
I Reusable
I Testable
I S.O.L.I.D.(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
Advanced OO Patterns 10 / 56
Goals of good OO design
I Modular
I Flexible
I Reusable
I Testable
I S.O.L.I.D.(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
Advanced OO Patterns 10 / 56
What’s the problem here?
1 <?php23 c l a s s MessageD i spatche r4 {5 p u b l i c f u n c t i o n c o n s t r u c t ( )6 {7 $ t h i s−>messenge r s [ ] = new
JabberMessenger ( ) ;8 $ t h i s−>messenge r s [ ] = new
Mai lMessenger ( ) ;9 }
10 }1112 c l a s s Mai lMessenger implements Messenger13 {14 p u b l i c f u n c t i o n sendMessage ( $ t e x t )15 {16 myLogger : : g e t I n s t a n c e ( )−>l og ( $ t e x t
) ;17 $ t h i s−>sendMa i l ( /∗ . . . ∗/ ) ;18 }19 }
I Inflexible
I Not reusable
I Hardly testable
Advanced OO Patterns 11 / 56
What’s the problem here?
1 <?php23 c l a s s MessageD i spatche r4 {5 p u b l i c f u n c t i o n c o n s t r u c t ( )6 {7 $ t h i s−>messenge r s [ ] = new
JabberMessenger ( ) ;8 $ t h i s−>messenge r s [ ] = new
Mai lMessenger ( ) ;9 }
10 }1112 c l a s s Mai lMessenger implements Messenger13 {14 p u b l i c f u n c t i o n sendMessage ( $ t e x t )15 {16 myLogger : : g e t I n s t a n c e ( )−>l og ( $ t e x t
) ;17 $ t h i s−>sendMa i l ( /∗ . . . ∗/ ) ;18 }19 }
I Inflexible
I Not reusable
I Hardly testable
Advanced OO Patterns 11 / 56
What’s the problem here?
1 <?php23 c l a s s MessageD i spatche r4 {5 p u b l i c f u n c t i o n c o n s t r u c t ( )6 {7 $ t h i s−>messenge r s [ ] = new
JabberMessenger ( ) ;8 $ t h i s−>messenge r s [ ] = new
Mai lMessenger ( ) ;9 }
10 }1112 c l a s s Mai lMessenger implements Messenger13 {14 p u b l i c f u n c t i o n sendMessage ( $ t e x t )15 {16 myLogger : : g e t I n s t a n c e ( )−>l og ( $ t e x t
) ;17 $ t h i s−>sendMa i l ( /∗ . . . ∗/ ) ;18 }19 }
I Inflexible
I Not reusable
I Hardly testable
Advanced OO Patterns 11 / 56
What’s the problem here?
1 <?php23 c l a s s MessageD i spatche r4 {5 p u b l i c f u n c t i o n c o n s t r u c t ( )6 {7 $ t h i s−>messenge r s [ ] = new
JabberMessenger ( ) ;8 $ t h i s−>messenge r s [ ] = new
Mai lMessenger ( ) ;9 }
10 }1112 c l a s s Mai lMessenger implements Messenger13 {14 p u b l i c f u n c t i o n sendMessage ( $ t e x t )15 {16 myLogger : : g e t I n s t a n c e ( )−>l og ( $ t e x t
) ;17 $ t h i s−>sendMa i l ( /∗ . . . ∗/ ) ;18 }19 }
I Inflexible
I Not reusable
I Hardly testable
Advanced OO Patterns 11 / 56
Injecting dependencies
1 <?php23 $messenger = new MessageDi spatche r (
19 ) ;
Advanced OO Patterns 12 / 56
Injecting dependencies
1 <?php23 $messenger = new MessageDi spatche r (4 a r r a y (5 new JabberMessenger ( ’ j a b b e r . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,6 new Mai lMessenger (
16 )17 ) ,
19 ) ;
Advanced OO Patterns 13 / 56
Injecting dependencies
1 <?php23 $messenger = new MessageDi spatche r (4 a r r a y (5 new JabberMessenger ( ’ j a b b e r . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,6 new Mai lMessenger (7 new Mai lSmtpTransport ( ’ ma i l . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,
16 )17 ) ,
19 ) ;
Advanced OO Patterns 14 / 56
Injecting dependencies
1 <?php23 $messenger = new MessageDi spatche r (4 a r r a y (5 new JabberMessenger ( ’ j a b b e r . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,6 new Mai lMessenger (7 new Mai lSmtpTransport ( ’ ma i l . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,8 $ l o g g e r = new Logger (
15 )16 )17 ) ,18 $ l o g g e r19 ) ;
Advanced OO Patterns 15 / 56
Injecting dependencies
1 <?php23 $messenger = new MessageDi spatche r (4 a r r a y (5 new JabberMessenger ( ’ j a b b e r . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,6 new Mai lMessenger (7 new Mai lSmtpTransport ( ’ ma i l . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,8 $ l o g g e r = new Logger (9 new Logg i ngD i spa t che r (
14 )15 )16 )17 ) ,18 $ l o g g e r19 ) ;
Advanced OO Patterns 16 / 56
Injecting dependencies
1 <?php23 $messenger = new MessageDi spatche r (4 a r r a y (5 new JabberMessenger ( ’ j a b b e r . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,6 new Mai lMessenger (7 new Mai lSmtpTransport ( ’ ma i l . example . org ’ , ’ u s e r ’ , ’ pa s s ’ ) ,8 $ l o g g e r = new Logger (9 new Logg i ngD i spa t che r (
10 a r r a y (11 new Sys l ogLogge r ( ) ,12 new F i l eSy s t emLogge r ( ’ l o g / e r r o r s . l o g ’ )13 )14 )15 )16 )17 ) ,18 $ l o g g e r19 ) ;
Advanced OO Patterns 17 / 56
DI visualized
Advanced OO Patterns 18 / 56
What is desired?
I Inject all dependencies
I Separate object construction from logic
Advanced OO Patterns 19 / 56
DI visualized
Advanced OO Patterns 20 / 56
What is desired?
I Don’t have ctors all over the place
I Manage dependencies
I Replace dependencies fine grained
I Lazy initialization
Advanced OO Patterns 21 / 56
Builders
1 <?php23 c l a s s Me s s ag eD i s pa t ch e rBu i l d e r4 {5 p r o t e c t e d $ l o gBu i l d e r ;6 p r o t e c t e d $mes sageD i spa tche r ;78 p u b l i c f u n c t i o n c o n s t r u c t ( LogBu i l d e r $ l o gBu i l d e r )9 { /∗ . . . ∗/ }
1011 p u b l i c f u n c t i o n c r e a t eMes s ag eD i s pa t ch e r ( )12 {13 i f ( ! i s s e t ( $ t h i s−>messageD i spa t che r ) )14 {15 $ t h i s−>messageD i spa t che r = new MessageD i spatche r (16 a r r a y (17 new JabberMessenger ( /∗ . . . ∗/ ) ,18 new Mai lMessenger (19 new Mai lSmtpTransport ( /∗ . . . ∗/ ) ,20 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( )21 ) ) ,22 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( ) ) ;23 }24 r e t u r n $ t h i s−>messageD i spa t che r ;25 }26 }
Advanced OO Patterns 22 / 56
Builders
1 <?php23 c l a s s Me s s ag eD i s pa t ch e rBu i l d e r4 {5 p r o t e c t e d $ l o gBu i l d e r ;6 p r o t e c t e d $mes sageD i spa tche r ;78 p u b l i c f u n c t i o n c o n s t r u c t ( LogBu i l d e r $ l o gBu i l d e r )9 { /∗ . . . ∗/ }
1011 p u b l i c f u n c t i o n c r e a t eMes s ag eD i s pa t ch e r ( )12 {13 i f ( ! i s s e t ( $ t h i s−>messageD i spa t che r ) )14 {15 $ t h i s−>messageD i spa t che r = new MessageD i spatche r (16 a r r a y (17 new JabberMessenger ( /∗ . . . ∗/ ) ,18 new Mai lMessenger (19 new Mai lSmtpTransport ( /∗ . . . ∗/ ) ,20 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( )21 ) ) ,22 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( ) ) ;23 }24 r e t u r n $ t h i s−>messageD i spa t che r ;25 }26 }
Advanced OO Patterns 22 / 56
Builders
1 <?php23 c l a s s Me s s ag eD i s pa t ch e rBu i l d e r4 {5 p r o t e c t e d $ l o gBu i l d e r ;6 p r o t e c t e d $mes sageD i spa tche r ;78 p u b l i c f u n c t i o n c o n s t r u c t ( LogBu i l d e r $ l o gBu i l d e r )9 { /∗ . . . ∗/ }
1011 p u b l i c f u n c t i o n c r e a t eMes s ag eD i s pa t ch e r ( )12 {13 i f ( ! i s s e t ( $ t h i s−>messageD i spa t che r ) )14 {15 $ t h i s−>messageD i spa t che r = new MessageD i spatche r (16 a r r a y (17 new JabberMessenger ( /∗ . . . ∗/ ) ,18 new Mai lMessenger (19 new Mai lSmtpTransport ( /∗ . . . ∗/ ) ,20 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( )21 ) ) ,22 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( ) ) ;23 }24 r e t u r n $ t h i s−>messageD i spa t che r ;25 }26 }
Advanced OO Patterns 22 / 56
Builders
1 <?php23 c l a s s Me s s ag eD i s pa t ch e rBu i l d e r4 {5 p r o t e c t e d $ l o gBu i l d e r ;6 p r o t e c t e d $mes sageD i spa tche r ;78 p u b l i c f u n c t i o n c o n s t r u c t ( LogBu i l d e r $ l o gBu i l d e r )9 { /∗ . . . ∗/ }
1011 p u b l i c f u n c t i o n c r e a t eMes s ag eD i s pa t ch e r ( )12 {13 i f ( ! i s s e t ( $ t h i s−>messageD i spa t che r ) )14 {15 $ t h i s−>messageD i spa t che r = new MessageD i spatche r (16 a r r a y (17 new JabberMessenger ( /∗ . . . ∗/ ) ,18 new Mai lMessenger (19 new Mai lSmtpTransport ( /∗ . . . ∗/ ) ,20 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( )21 ) ) ,22 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( ) ) ;23 }24 r e t u r n $ t h i s−>messageD i spa t che r ;25 }26 }
Advanced OO Patterns 22 / 56
Builders
1 <?php23 c l a s s Me s s ag eD i s pa t ch e rBu i l d e r4 {5 p r o t e c t e d $ l o gBu i l d e r ;6 p r o t e c t e d $mes sageD i spa tche r ;78 p u b l i c f u n c t i o n c o n s t r u c t ( LogBu i l d e r $ l o gBu i l d e r )9 { /∗ . . . ∗/ }
1011 p u b l i c f u n c t i o n c r e a t eMes s ag eD i s pa t ch e r ( )12 {13 i f ( ! i s s e t ( $ t h i s−>messageD i spa t che r ) )14 {15 $ t h i s−>messageD i spa t che r = new MessageD i spatche r (16 a r r a y (17 new JabberMessenger ( /∗ . . . ∗/ ) ,18 new Mai lMessenger (19 new Mai lSmtpTransport ( /∗ . . . ∗/ ) ,20 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( )21 ) ) ,22 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( ) ) ;23 }24 r e t u r n $ t h i s−>messageD i spa t che r ;25 }26 }
Advanced OO Patterns 22 / 56
Builders
1 <?php23 c l a s s Me s s ag eD i s pa t ch e rBu i l d e r4 {5 p r o t e c t e d $ l o gBu i l d e r ;6 p r o t e c t e d $mes sageD i spa tche r ;78 p u b l i c f u n c t i o n c o n s t r u c t ( LogBu i l d e r $ l o gBu i l d e r )9 { /∗ . . . ∗/ }
1011 p u b l i c f u n c t i o n c r e a t eMes s ag eD i s pa t ch e r ( )12 {13 i f ( ! i s s e t ( $ t h i s−>messageD i spa t che r ) )14 {15 $ t h i s−>messageD i spa t che r = new MessageD i spatche r (16 a r r a y (17 new JabberMessenger ( /∗ . . . ∗/ ) ,18 new Mai lMessenger (19 new Mai lSmtpTransport ( /∗ . . . ∗/ ) ,20 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( )21 ) ) ,22 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( ) ) ;23 }24 r e t u r n $ t h i s−>messageD i spa t che r ;25 }26 }
Advanced OO Patterns 22 / 56
Builders
1 <?php23 c l a s s Me s s ag eD i s pa t ch e rBu i l d e r4 {5 p r o t e c t e d $ l o gBu i l d e r ;6 p r o t e c t e d $mes sageD i spa tche r ;78 p u b l i c f u n c t i o n c o n s t r u c t ( LogBu i l d e r $ l o gBu i l d e r )9 { /∗ . . . ∗/ }
1011 p u b l i c f u n c t i o n c r e a t eMes s ag eD i s pa t ch e r ( )12 {13 i f ( ! i s s e t ( $ t h i s−>messageD i spa t che r ) )14 {15 $ t h i s−>messageD i spa t che r = new MessageD i spatche r (16 a r r a y (17 new JabberMessenger ( /∗ . . . ∗/ ) ,18 new Mai lMessenger (19 new Mai lSmtpTransport ( /∗ . . . ∗/ ) ,20 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( )21 ) ) ,22 $ t h i s−>l o gBu i l d e r−>c r e a t eLogg e r ( ) ) ;23 }24 r e t u r n $ t h i s−>messageD i spa t che r ;25 }26 }
Advanced OO Patterns 22 / 56
Dependency Injection Container
I Takes care of object creation
I Manages dependencies
I Allows fine grained replacement
Advanced OO Patterns 23 / 56
Manual DIC
1 <?php23 c l a s s Dep end en c y I n j e c t i o nCon t a i n e r4 {
5 p r o t e c t e d $cache ;
10 p u b l i c f u n c t i o n getCache ( )11 {12 i f ( ! i s s e t ( $ t h i s−>cache ) )13 {14 $ t h i s−>cache = new F i l e s y s t emCache ( /∗ . . . ∗/ ) ;15 }16 r e t u r n $ t h i s−>cache ;17 }
42 }
Advanced OO Patterns 24 / 56
Manual DIC
1 <?php23 c l a s s Dep end en c y I n j e c t i o nCon t a i n e r4 {
5 p r o t e c t e d $messenger ;
10 p u b l i c f u n c t i o n getMessenger ( )11 {12 i f ( ! i s s e t ( $ t h i s−>messenger ) )13 {14 $ t h i s−>messenger = new Messenger ( a r r a y (15 ’ ema i l ’ => $ t h i s−>ge tMa i lMes senge r ( ) ,16 ) ) ;17 }18 r e t u r n $ t h i s−>messenger ;19 }
42 }
Advanced OO Patterns 25 / 56
Manual DIC
1 <?php23 c l a s s Dep end en c y I n j e c t i o nCon t a i n e r4 {
5 p r o t e c t e d $ma i lMessenge r ;
10 p u b l i c f u n c t i o n ge tMa i lMes senge r ( )11 {12 i f ( ! i s s e t ( $ t h i s−>mai lMessenge r ) )13 {14 $ t h i s−>mai lMessenge r = new Mai lMessenger (15 $ t h i s−>ge tMa i lT r an spo r t ( )16 ) ;17 }18 r e t u r n $ t h i s−>mai lMessenge r ;19 }2021 /∗ . . . ∗/
42 }
Advanced OO Patterns 26 / 56
The Arbit DIC
I ExemplaryI Shared objects (initialized once)I Closures for lazy initializationI Inherent dependency resolution
I Base class for custom DICs
I Heavy use of interceptors
I No implementation details,see here: http://bit.ly/arbitDIC
Advanced OO Patterns 27 / 56
The Arbit DIC
I ExemplaryI Shared objects (initialized once)I Closures for lazy initializationI Inherent dependency resolution
I Base class for custom DICs
I Heavy use of interceptors
I No implementation details,see here: http://bit.ly/arbitDIC
Advanced OO Patterns 27 / 56
The Arbit DIC
I ExemplaryI Shared objects (initialized once)I Closures for lazy initializationI Inherent dependency resolution
I Base class for custom DICs
I Heavy use of interceptors
I No implementation details,see here: http://bit.ly/arbitDIC
Advanced OO Patterns 27 / 56
The Arbit DIC
I ExemplaryI Shared objects (initialized once)I Closures for lazy initializationI Inherent dependency resolution
I Base class for custom DICs
I Heavy use of interceptors
I No implementation details,see here: http://bit.ly/arbitDIC
Advanced OO Patterns 27 / 56
The Arbit DIC
3 c l a s s a rb i tEnv i ronmentDIC ex t end s a r b i tD e p e n d e n c y I n j e c t i o nCon t a i n e r4 {
13 p u b l i c f u n c t i o n i n i t i a l i z e ( )14 {
38 }39 }
Advanced OO Patterns 28 / 56
The Arbit DIC
3 c l a s s a rb i tEnv i ronmentDIC ex t end s a r b i tD e p e n d e n c y I n j e c t i o nCon t a i n e r4 {
13 p u b l i c f u n c t i o n i n i t i a l i z e ( )14 {
38 }39 }
Advanced OO Patterns 28 / 56
The Arbit DIC
3 c l a s s a rb i tEnv i ronmentDIC ex t end s a r b i tD e p e n d e n c y I n j e c t i o nCon t a i n e r4 {
13 p u b l i c f u n c t i o n i n i t i a l i z e ( )14 {
15 $ t h i s−>cache = f u n c t i o n ( $d i c )16 {17 r e t u r n new a r b i t F i l e s y s t emCa c h e ( $d ic−>r eque s t−>c o n t r o l l e r ) ;18 } ;
38 }39 }
Advanced OO Patterns 29 / 56
Resolving the Cache
1 <?php23 $d i c = new arb i tEnv i ronmentDIC ( ) ;4 $cache = $d ic−>cache ;56 // I n s i d e $d i c t h i s i s s i m i l a r to :78 i f ( ! i s s e t ( $ t h i s−>sha r ed [ ’ cache ’ ] ) )9 {
10 $ t h i s−>sha r ed [ ’ cache ’ ] = $ th i s−>cache ( $ t h i s ) ;11 }1213 // T r i g g e r i n g the c l o s u r e i n $ t h i s−>cache :1415 f u n c t i o n ca cheC l o su r e ( $d i c )16 {17 r e t u r n new a r b i t F i l e s y s t emCa c h e ( $d ic−>r eque s t−>c o n t r o l l e r ) ;18 }
Advanced OO Patterns 30 / 56
Resolving the Cache
1 <?php23 $d i c = new arb i tEnv i ronmentDIC ( ) ;4 $cache = $d ic−>cache ;56 // I n s i d e $d i c t h i s i s s i m i l a r to :78 i f ( ! i s s e t ( $ t h i s−>sha r ed [ ’ cache ’ ] ) )9 {
10 $ t h i s−>sha r ed [ ’ cache ’ ] = $ th i s−>cache ( $ t h i s ) ;11 }1213 // T r i g g e r i n g the c l o s u r e i n $ t h i s−>cache :1415 f u n c t i o n ca cheC l o su r e ( $d i c )16 {17 r e t u r n new a r b i t F i l e s y s t emCa c h e ( $d ic−>r eque s t−>c o n t r o l l e r ) ;18 }
Advanced OO Patterns 30 / 56
Resolving the Cache
1 <?php23 $d i c = new arb i tEnv i ronmentDIC ( ) ;4 $cache = $d ic−>cache ;56 // I n s i d e $d i c t h i s i s s i m i l a r to :78 i f ( ! i s s e t ( $ t h i s−>sha r ed [ ’ cache ’ ] ) )9 {
10 $ t h i s−>sha r ed [ ’ cache ’ ] = $ th i s−>cache ( $ t h i s ) ;11 }1213 // T r i g g e r i n g the c l o s u r e i n $ t h i s−>cache :1415 f u n c t i o n ca cheC l o su r e ( $d i c )16 {17 r e t u r n new a r b i t F i l e s y s t emCa c h e ( $d ic−>r eque s t−>c o n t r o l l e r ) ;18 }
Advanced OO Patterns 30 / 56
Resolving the Cache
1 <?php23 $d i c = new arb i tEnv i ronmentDIC ( ) ;4 $cache = $d ic−>cache ;56 // I n s i d e $d i c t h i s i s s i m i l a r to :78 i f ( ! i s s e t ( $ t h i s−>sha r ed [ ’ cache ’ ] ) )9 {
10 $ t h i s−>sha r ed [ ’ cache ’ ] = $ th i s−>cache ( $ t h i s ) ;11 }1213 // T r i g g e r i n g the c l o s u r e i n $ t h i s−>cache :1415 f u n c t i o n ca cheC l o su r e ( $d i c )16 {17 r e t u r n new a r b i t F i l e s y s t emCa c h e ( $d ic−>r eque s t−>c o n t r o l l e r ) ;18 }
Advanced OO Patterns 30 / 56
Resolving the Cache
1 <?php23 $d i c = new arb i tEnv i ronmentDIC ( ) ;4 $cache = $d ic−>cache ;56 // I n s i d e $d i c t h i s i s s i m i l a r to :78 i f ( ! i s s e t ( $ t h i s−>sha r ed [ ’ cache ’ ] ) )9 {
10 $ t h i s−>sha r ed [ ’ cache ’ ] = $ th i s−>cache ( $ t h i s ) ;11 }1213 // T r i g g e r i n g the c l o s u r e i n $ t h i s−>cache :1415 f u n c t i o n ca cheC l o su r e ( $d i c )16 {17 r e t u r n new a r b i t F i l e s y s t emCa c h e ( $d ic−>r eque s t−>c o n t r o l l e r ) ;18 }
Advanced OO Patterns 30 / 56
The Arbit DIC
3 c l a s s a rb i tEnv i ronmentDIC ex t end s a r b i tD e p e n d e n c y I n j e c t i o nCon t a i n e r4 {
13 p u b l i c f u n c t i o n i n i t i a l i z e ( )14 {
20 $ t h i s−>messenger = f u n c t i o n ( $d i c )21 {22 r e t u r n new a rb i tMe s s eng e r ( a r r a y (23 ’ ema i l ’ => $d ic−>mai lMessenger ,24 ) ) ;25 } ;
38 }39 }
Advanced OO Patterns 31 / 56
The Arbit DIC
3 c l a s s a rb i tEnv i ronmentDIC ex t end s a r b i tD e p e n d e n c y I n j e c t i o nCon t a i n e r4 {
13 p u b l i c f u n c t i o n i n i t i a l i z e ( )14 {
27 $ t h i s−>mai lMessenge r = f u n c t i o n ( $d i c )28 {29 r e t u r n new a rb i tMa i lMe s s e ng e r (30 $d ic−>mai lT ranspo r t ,31 $d ic−>c o n f i g u r a t i o n−>main ,32 $d ic−>c o n f i g u r a t i o n−>p r o j e c t ( $d ic−>r eque s t−>c o n t r o l l e r ) ,33 $d ic−>v iews−>d e c o r a t o r34 ) ;35 } ;
38 }39 }
Advanced OO Patterns 32 / 56
Dependency Injection Approaches
I Constructor injectionI We just saw that
I Setter injectionI Use set*()I Default instances?
I Interface injectionI Inject by interfaceI Specify instance for interface
Advanced OO Patterns 33 / 56
Dependency Injection Approaches
I Constructor injectionI We just saw that
I Setter injectionI Use set*()I Default instances?
I Interface injectionI Inject by interfaceI Specify instance for interface
Advanced OO Patterns 33 / 56
Dependency Injection Approaches
I Constructor injectionI We just saw that
I Setter injectionI Use set*()I Default instances?
I Interface injectionI Inject by interfaceI Specify instance for interface
Advanced OO Patterns 33 / 56
More about DIC
I Phemto - A dependency injector for PHP 5http://phemto.sourceforge.net/
I Bucket - Basic di-container for phphttps://github.com/troelskn/bucket
I Symfony Dependency Injectionhttp://components.symfony-project.org/
dependency-injection/
I Pimple - A small PHP 5.3 DIC (used in Silex)https://github.com/fabpot/Pimple
I Martin Fowler on Dependency Injectionhttp://martinfowler.com/articles/injection.html
Advanced OO Patterns 34 / 56
More about DIC
I Phemto - A dependency injector for PHP 5http://phemto.sourceforge.net/
I Bucket - Basic di-container for phphttps://github.com/troelskn/bucket
I Symfony Dependency Injectionhttp://components.symfony-project.org/
dependency-injection/
I Pimple - A small PHP 5.3 DIC (used in Silex)https://github.com/fabpot/Pimple
I Martin Fowler on Dependency Injectionhttp://martinfowler.com/articles/injection.html
Advanced OO Patterns 34 / 56
Outline
Introduction
Dependency Injection
Service Locator
Data Storage
Advanced OO Patterns 35 / 56
Motivation
I Central Registry
I Clients ask for service (abstraction)
I Knows how to ”assemble” services
I Orginates from compiled languages
I Sometimes used similar to DI
I Often used to reduce parameter lists
Advanced OO Patterns 36 / 56
Motivation
I Central Registry
I Clients ask for service (abstraction)
I Knows how to ”assemble” services
I Orginates from compiled languages
I Sometimes used similar to DI
I Often used to reduce parameter lists
Advanced OO Patterns 36 / 56
Motivation
I Central Registry
I Clients ask for service (abstraction)
I Knows how to ”assemble” services
I Orginates from compiled languages
I Sometimes used similar to DI
I Often used to reduce parameter lists
Advanced OO Patterns 36 / 56
Service locator example
1 <?php23 c l a s s S e r v i c e L o c a t o r4 {5 p u b l i c f u n c t i o n getUserGateway ( )6 { /∗ . . . ∗/ }78 p u b l i c f u n c t i o n getProductGateway ( )9 { /∗ . . . ∗/ }
1011 // . . .12 }1314 c l a s s U s e r C o n t r o l l e r15 {16 p u b l i c f u n c t i o n c o n s t r u c t ( S e r v i c e L o c a t o r $ s e r v i c e L o c a t o r )17 { /∗ . . . ∗/ }18 }1920 ?>
Advanced OO Patterns 37 / 56
Service locator example
1 <?php23 c l a s s S e r v i c e L o c a t o r4 {5 p u b l i c f u n c t i o n getUserGateway ( )6 { /∗ . . . ∗/ }78 p u b l i c f u n c t i o n getProductGateway ( )9 { /∗ . . . ∗/ }
1011 // . . .12 }1314 c l a s s U s e r C o n t r o l l e r15 {16 p u b l i c f u n c t i o n c o n s t r u c t ( S e r v i c e L o c a t o r $ s e r v i c e L o c a t o r )17 { /∗ . . . ∗/ }18 }1920 ?>
Advanced OO Patterns 37 / 56
Service locator example
1 <?php23 c l a s s S e r v i c e L o c a t o r4 {5 p u b l i c f u n c t i o n getUserGateway ( )6 { /∗ . . . ∗/ }78 p u b l i c f u n c t i o n getProductGateway ( )9 { /∗ . . . ∗/ }
1011 // . . .12 }1314 c l a s s U s e r C o n t r o l l e r15 {16 p u b l i c f u n c t i o n c o n s t r u c t ( S e r v i c e L o c a t o r $ s e r v i c e L o c a t o r )17 { /∗ . . . ∗/ }18 }1920 ?>
Advanced OO Patterns 37 / 56
Service locator example
1 <?php23 c l a s s S e r v i c e L o c a t o r4 {5 p u b l i c f u n c t i o n getUserGateway ( )6 { /∗ . . . ∗/ }78 p u b l i c f u n c t i o n getProductGateway ( )9 { /∗ . . . ∗/ }
1011 // . . .12 }1314 c l a s s U s e r C o n t r o l l e r15 {16 p u b l i c f u n c t i o n c o n s t r u c t ( S e r v i c e L o c a t o r $ s e r v i c e L o c a t o r )17 { /∗ . . . ∗/ }18 }1920 ?>
Advanced OO Patterns 37 / 56
Service locator example
1 <?php23 c l a s s S e r v i c e L o c a t o r4 {5 p u b l i c f u n c t i o n getUserGateway ( )6 { /∗ . . . ∗/ }78 p u b l i c f u n c t i o n getProductGateway ( )9 { /∗ . . . ∗/ }
1011 // . . .12 }1314 c l a s s U s e r C o n t r o l l e r15 {16 p u b l i c f u n c t i o n c o n s t r u c t ( S e r v i c e L o c a t o r $ s e r v i c e L o c a t o r )17 { /∗ . . . ∗/ }18 }1920 ?>
Advanced OO Patterns 37 / 56
Problems
I Hides dependencies
I Hides code smells
I Enables usage of arbitrary objects
Advanced OO Patterns 38 / 56
Universal Constructors
I Ctor expects only single parameter
I An array with everything the object needs
I Potentially merged with default values
Advanced OO Patterns 39 / 56
Universal Constructors Example
1 <?php23 c l a s s U s e r C o n t r o l l e r4 {5 p u b l i c f u n c t i o n c o n s t r u c t ( $ c o n f i g = n u l l )6 { /∗ . . . ∗/ }7 }
Advanced OO Patterns 40 / 56
The essence
Service Locator
Advanced OO Patterns 41 / 56
Outline
Introduction
Dependency Injection
Service Locator
Data Storage
Advanced OO Patterns 42 / 56
The situation
Model (application) Storage
Advanced OO Patterns 43 / 56
The situation
Model (application) Storage
store
restore
Advanced OO Patterns 43 / 56
Challenges
I Model and storage structure differI Object relational impedance mismatch
I Different access approachesI Query language differences
I Storage back end might change
I Back ends could even be mixed
I . . .
Advanced OO Patterns 44 / 56
Challenges
I Model and storage structure differI Object relational impedance mismatch
I Different access approachesI Query language differences
I Storage back end might change
I Back ends could even be mixed
I . . .
Advanced OO Patterns 44 / 56
Challenges
I Model and storage structure differI Object relational impedance mismatch
I Different access approachesI Query language differences
I Storage back end might change
I Back ends could even be mixed
I . . .
Advanced OO Patterns 44 / 56
Challenges
I Model and storage structure differI Object relational impedance mismatch
I Different access approachesI Query language differences
I Storage back end might change
I Back ends could even be mixed
I . . .
Advanced OO Patterns 44 / 56
Challenges
I Model and storage structure differI Object relational impedance mismatch
I Different access approachesI Query language differences
I Storage back end might change
I Back ends could even be mixed
I . . .
Advanced OO Patterns 44 / 56
Challenges
I Model and storage structure differI Object relational impedance mismatch
I Different access approachesI Query language differences
I Storage back end might change
I Back ends could even be mixed
I . . .
Advanced OO Patterns 44 / 56
Challenges
I Model and storage structure differI Object relational impedance mismatch
I Different access approachesI Query language differences
I Storage back end might change
I Back ends could even be mixed
I . . .
Advanced OO Patterns 44 / 56
Active Record
1 <?php23 c l a s s I n v o i c e e x t end s Ac t i v eReco rd4 {5 p r o t e c t e d $ i d ;6 p r o t e c t e d $ p o s i t i o n s ;7 p r o t e c t e d $vat ;8 // . . .9
10 p u b l i c f u n c t i o n c a l c u l a t eV a l u e ( )11 { /∗ b u s i n e s s l o g i c ∗/ }12 }1314 c l a s s Ac t i v eReco rd15 {16 p u b l i c f u n c t i o n i n s e r t ( )17 { /∗ . . . ∗/ }18 p u b l i c f u n c t i o n update ( )19 { /∗ . . . ∗/ }20 }
Advanced OO Patterns 45 / 56
Active Record
1 <?php23 c l a s s I n v o i c e e x t end s Ac t i v eReco rd4 {5 p r o t e c t e d $ i d ;6 p r o t e c t e d $ p o s i t i o n s ;7 p r o t e c t e d $vat ;8 // . . .9
10 p u b l i c f u n c t i o n c a l c u l a t eV a l u e ( )11 { /∗ b u s i n e s s l o g i c ∗/ }12 }1314 c l a s s Ac t i v eReco rd15 {16 p u b l i c f u n c t i o n i n s e r t ( )17 { /∗ . . . ∗/ }18 p u b l i c f u n c t i o n update ( )19 { /∗ . . . ∗/ }20 }
Advanced OO Patterns 45 / 56
Active Record
1 <?php23 c l a s s I n v o i c e e x t end s Ac t i v eReco rd4 {5 p r o t e c t e d $ i d ;6 p r o t e c t e d $ p o s i t i o n s ;7 p r o t e c t e d $vat ;8 // . . .9
10 p u b l i c f u n c t i o n c a l c u l a t eV a l u e ( )11 { /∗ b u s i n e s s l o g i c ∗/ }12 }1314 c l a s s Ac t i v eReco rd15 {16 p u b l i c f u n c t i o n i n s e r t ( )17 { /∗ . . . ∗/ }18 p u b l i c f u n c t i o n update ( )19 { /∗ . . . ∗/ }20 }
Advanced OO Patterns 45 / 56
Active Record
1 <?php23 c l a s s I n v o i c e e x t end s Ac t i v eReco rd4 {5 p r o t e c t e d $ i d ;6 p r o t e c t e d $ p o s i t i o n s ;7 p r o t e c t e d $vat ;8 // . . .9
10 p u b l i c f u n c t i o n c a l c u l a t eV a l u e ( )11 { /∗ b u s i n e s s l o g i c ∗/ }12 }1314 c l a s s Ac t i v eReco rd15 {16 p u b l i c f u n c t i o n i n s e r t ( )17 { /∗ . . . ∗/ }18 p u b l i c f u n c t i o n update ( )19 { /∗ . . . ∗/ }20 }
Advanced OO Patterns 45 / 56
Active Record
I Combines storage and business logic
I Commonly storage logic in base class
I Model class corresponds to database record
Advanced OO Patterns 46 / 56
Evaluation
Pros
I Very easy to use
I Few code to write
Cons
I Model structure = storagestructure
I Classes become complexI Business logicI Storage logic
I Broken object semantics
I Changes ripple over
I Hard to exchange storage logic
I Really hard to test!
Advanced OO Patterns 47 / 56
Evaluation
Pros
I Very easy to use
I Few code to write
Cons
I Model structure = storagestructure
I Classes become complexI Business logicI Storage logic
I Broken object semantics
I Changes ripple over
I Hard to exchange storage logic
I Really hard to test!
Advanced OO Patterns 47 / 56
Evaluation
Pros
I Very easy to use
I Few code to write
Cons
I Model structure = storagestructure
I Classes become complexI Business logicI Storage logic
I Broken object semantics
I Changes ripple over
I Hard to exchange storage logic
I Really hard to test!
Advanced OO Patterns 47 / 56
Evaluation
Pros
I Very easy to use
I Few code to write
Cons
I Model structure = storagestructure
I Classes become complexI Business logicI Storage logic
I Broken object semantics
I Changes ripple over
I Hard to exchange storage logic
I Really hard to test!
Advanced OO Patterns 47 / 56
Evaluation
Pros
I Very easy to use
I Few code to write
Cons
I Model structure = storagestructure
I Classes become complexI Business logicI Storage logic
I Broken object semantics
I Changes ripple over
I Hard to exchange storage logic
I Really hard to test!
Advanced OO Patterns 47 / 56
Evaluation
Pros
I Very easy to use
I Few code to write
Cons
I Model structure = storagestructure
I Classes become complexI Business logicI Storage logic
I Broken object semantics
I Changes ripple over
I Hard to exchange storage logic
I Really hard to test!
Advanced OO Patterns 47 / 56
Evaluation
Pros
I Very easy to use
I Few code to write
Cons
I Model structure = storagestructure
I Classes become complexI Business logicI Storage logic
I Broken object semantics
I Changes ripple over
I Hard to exchange storage logic
I Really hard to test!
Advanced OO Patterns 47 / 56
Evaluation
Pros
I Very easy to use
I Few code to write
Cons
I Model structure = storagestructure
I Classes become complexI Business logicI Storage logic
I Broken object semantics
I Changes ripple over
I Hard to exchange storage logic
I Really hard to test!
Advanced OO Patterns 47 / 56
Lesson learned . . .
De-couple business and storage logic!
Advanced OO Patterns 48 / 56
Other Approaches
I Table data gateway
I Row data gateway
Advanced OO Patterns 49 / 56
Data Mapper
1 <?php23 c l a s s I n v o i c e4 {5 p r o t e c t e d $ p o s i t i o n s ;6 p r o t e c t e d $vat ;7 // . . .89 p u b l i c f u n c t i o n c a l c u l a t eV a l u e ( )
10 { /∗ b u s i n e s s l o g i c ∗/ }11 }1213 i n t e r f a c e Invo i ceMappe r14 {15 p u b l i c f u n c t i o n s t o r e ( I n v o i c e $ i n v o i c e ) ;16 p u b l i c f u n c t i o n update ( I n v o i c e $ i n v o i c e ) ;17 p u b l i c f u n c t i o n f indByCustomer ( Customer $customer ) ;18 }1920 c l a s s DbInvoiceMapper implements Invo i ceMappe r21 {22 // . . .23 }2425 ?>
Advanced OO Patterns 50 / 56
Data Mapper
1 <?php23 c l a s s I n v o i c e4 {5 p r o t e c t e d $ p o s i t i o n s ;6 p r o t e c t e d $vat ;7 // . . .89 p u b l i c f u n c t i o n c a l c u l a t eV a l u e ( )
10 { /∗ b u s i n e s s l o g i c ∗/ }11 }1213 i n t e r f a c e Invo i ceMappe r14 {15 p u b l i c f u n c t i o n s t o r e ( I n v o i c e $ i n v o i c e ) ;16 p u b l i c f u n c t i o n update ( I n v o i c e $ i n v o i c e ) ;17 p u b l i c f u n c t i o n f indByCustomer ( Customer $customer ) ;18 }1920 c l a s s DbInvoiceMapper implements Invo i ceMappe r21 {22 // . . .23 }2425 ?>
Advanced OO Patterns 50 / 56
Data Mapper
1 <?php23 c l a s s I n v o i c e4 {5 p r o t e c t e d $ p o s i t i o n s ;6 p r o t e c t e d $vat ;7 // . . .89 p u b l i c f u n c t i o n c a l c u l a t eV a l u e ( )
10 { /∗ b u s i n e s s l o g i c ∗/ }11 }1213 i n t e r f a c e Invo i ceMappe r14 {15 p u b l i c f u n c t i o n s t o r e ( I n v o i c e $ i n v o i c e ) ;16 p u b l i c f u n c t i o n update ( I n v o i c e $ i n v o i c e ) ;17 p u b l i c f u n c t i o n f indByCustomer ( Customer $customer ) ;18 }1920 c l a s s DbInvoiceMapper implements Invo i ceMappe r21 {22 // . . .23 }2425 ?>
Advanced OO Patterns 50 / 56
Data Mapper
1 <?php23 c l a s s I n v o i c e4 {5 p r o t e c t e d $ p o s i t i o n s ;6 p r o t e c t e d $vat ;7 // . . .89 p u b l i c f u n c t i o n c a l c u l a t eV a l u e ( )
10 { /∗ b u s i n e s s l o g i c ∗/ }11 }1213 i n t e r f a c e Invo i ceMappe r14 {15 p u b l i c f u n c t i o n s t o r e ( I n v o i c e $ i n v o i c e ) ;16 p u b l i c f u n c t i o n update ( I n v o i c e $ i n v o i c e ) ;17 p u b l i c f u n c t i o n f indByCustomer ( Customer $customer ) ;18 }1920 c l a s s DbInvoiceMapper implements Invo i ceMappe r21 {22 // . . .23 }2425 ?>
Advanced OO Patterns 50 / 56
Data Mapper
I Decouple storage from model
I No OO modelling of DB structure
I Model does not even know a database exists
Advanced OO Patterns 51 / 56
Evaluation
Pros
I Complete decoupling
I Model is not aware of storageI Clean storage interface
I Implement different storages!
I DB changes only affectmapping layer
I Model changes only affectmapping layer
I Nice for testing
Cons
I Quite some codeto write
I Mapping canbecome complex
Advanced OO Patterns 52 / 56
Evaluation
Pros
I Complete decoupling
I Model is not aware of storageI Clean storage interface
I Implement different storages!
I DB changes only affectmapping layer
I Model changes only affectmapping layer
I Nice for testing
Cons
I Quite some codeto write
I Mapping canbecome complex
Advanced OO Patterns 52 / 56
Evaluation
Pros
I Complete decoupling
I Model is not aware of storageI Clean storage interface
I Implement different storages!
I DB changes only affectmapping layer
I Model changes only affectmapping layer
I Nice for testing
Cons
I Quite some codeto write
I Mapping canbecome complex
Advanced OO Patterns 52 / 56
Evaluation
Pros
I Complete decoupling
I Model is not aware of storageI Clean storage interface
I Implement different storages!
I DB changes only affectmapping layer
I Model changes only affectmapping layer
I Nice for testing
Cons
I Quite some codeto write
I Mapping canbecome complex
Advanced OO Patterns 52 / 56
Evaluation
Pros
I Complete decoupling
I Model is not aware of storageI Clean storage interface
I Implement different storages!
I DB changes only affectmapping layer
I Model changes only affectmapping layer
I Nice for testing
Cons
I Quite some codeto write
I Mapping canbecome complex
Advanced OO Patterns 52 / 56
Evaluation
Pros
I Complete decoupling
I Model is not aware of storageI Clean storage interface
I Implement different storages!
I DB changes only affectmapping layer
I Model changes only affectmapping layer
I Nice for testing
Cons
I Quite some codeto write
I Mapping canbecome complex
Advanced OO Patterns 52 / 56
Evaluation
Pros
I Complete decoupling
I Model is not aware of storageI Clean storage interface
I Implement different storages!
I DB changes only affectmapping layer
I Model changes only affectmapping layer
I Nice for testing
Cons
I Quite some codeto write
I Mapping canbecome complex
Advanced OO Patterns 52 / 56
Evaluation
Pros
I Complete decoupling
I Model is not aware of storageI Clean storage interface
I Implement different storages!
I DB changes only affectmapping layer
I Model changes only affectmapping layer
I Nice for testing
Cons
I Quite some codeto write
I Mapping canbecome complex
Advanced OO Patterns 52 / 56
Attribution
Large parts of this talk are inspired by
Patterns of Enterprise Application Architectureby Martin Fowler
ISBN 978-0321127426 — http://amzn.to/PofEAA
Highy recommended!
Advanced OO Patterns 53 / 56
Conclusion
I Patterns are not the holy grail!
I They assign names to good ideas
I They help you to talk about concepts
I They can inspire you
Advanced OO Patterns 54 / 56
Conclusion
I Patterns are not the holy grail!
I They assign names to good ideas
I They help you to talk about concepts
I They can inspire you
Advanced OO Patterns 54 / 56
Q / A
Are there any questions left?
Advanced OO Patterns 55 / 56
Thanks for listening
Slides will be online athttp://talks.qafoo.com
Advanced OO Patterns 56 / 56
Thanks for listening
Slides will be online athttp://talks.qafoo.com
Stay in touch
I Tobias SchlittI [email protected] @tobySen / @qafoo
Rent a PHP quality expert:http://qafoo.com
Advanced OO Patterns 56 / 56