The document is a slide presentation titled "Advanced OO Patterns" given by Tobias Schlitt, a co-founder of Qafoo GmbH. It discusses object-oriented design patterns like lazy initialization, dependency injection, and the service locator pattern. The presentation provides code examples and motivations for using these patterns to achieve goals like modularity, flexibility, reusability and testability in object-oriented software design.
2. Advanced OO Patterns 2 / 44
Outline
Introduction
Lazy Initialization
Dependency Injection
Service Locator
Data Storage
3. Advanced OO Patterns 3 / 44
About me
Degree in computer sience
More than 10 years of
professional PHP
Open source enthusiast
Apache Zeta Components
Arbit
PHPUnit
...
4. Advanced OO Patterns 3 / 44
About me
Degree in computer sience
More than 10 years of
professional PHP
Open source enthusiast
Apache Zeta Components
Arbit
PHPUnit
...
5. Advanced OO Patterns 3 / 44
About me
Degree in computer sience
More than 10 years of
professional PHP
Open source enthusiast
Apache Zeta Components
Arbit
PHPUnit
...
6. Advanced OO Patterns 3 / 44
About me
Degree in computer sience
Co-Founder of
More than 10 years of Qafoo GmbH
professional PHP http://qafoo.com
Open source enthusiast
Apache Zeta Components Qafoo
passion for software quality
Arbit
PHPUnit
...
7. Advanced OO Patterns 3 / 44
About me
Degree in computer sience
Co-Founder of
More than 10 years of Qafoo GmbH
professional PHP http://qafoo.com
Open source enthusiast
Apache Zeta Components Qafoo
passion for software quality
Arbit
We help people to produce
PHPUnit
...
high quality PHP code.
8. Advanced OO Patterns 4 / 44
Disclaimer
This talk cannot be in depth
This talk shall inspire you
This talk will not show UML diagrams
This talk will show you quite some code
This talk can seriously harm your coding habbits
9. Advanced OO Patterns 4 / 44
Disclaimer
This talk cannot be in depth
This talk shall inspire you
This talk will not show UML diagrams
This talk will show you quite some code
This talk can seriously harm your coding habbits
10. Advanced OO Patterns 4 / 44
Disclaimer
This talk cannot be in depth
This talk shall inspire you
This talk will not show UML diagrams
This talk will show you quite some code
This talk can seriously harm your coding habbits
11. Advanced OO Patterns 4 / 44
Disclaimer
This talk cannot be in depth
This talk shall inspire you
This talk will not show UML diagrams
This talk will show you quite some code
This talk can seriously harm your coding habbits
12. Advanced OO Patterns 4 / 44
Disclaimer
This talk cannot be in depth
This talk shall inspire you
This talk will not show UML diagrams
This talk will show you quite some code
This talk can seriously harm your coding habbits
19. Advanced OO Patterns 5 / 44
Patterns are . . .
. . . universal solutions.
. . . good habbits.
. . . coding templates.
. . . names for proven ideas how a certain class of problems
can be solved.
20. Advanced OO Patterns 6 / 44
Patterns are not . . .
. . . appliable to every problem.
. . . directly transferable to code.
. . . always the best solution.
22. Advanced OO Patterns 8 / 44
Well known patterns
Signal / Observer
Iterator
Visitor
Adapter
Singleton
Factory
23. Advanced OO Patterns 8 / 44
Well known patterns
Signal / Observer
Iterator
Visitor
Adapter
Singleton
Factory
24. Advanced OO Patterns 9 / 44
Outline
Introduction
Lazy Initialization
Dependency Injection
Service Locator
Data Storage
25. Advanced OO Patterns 10 / 44
Motivation
Building a full object graph is
Complex
Time consuming
Memory consuming
Do you use all objects in every request?
Idea: Initialize object when needed for the first time
26. Advanced OO Patterns 10 / 44
Motivation
Building a full object graph is
Complex
Time consuming
Memory consuming
Do you use all objects in every request?
Idea: Initialize object when needed for the first time
27. Advanced OO Patterns 10 / 44
Motivation
Building a full object graph is
Complex
Time consuming
Memory consuming
Do you use all objects in every request?
Idea: Initialize object when needed for the first time
28. Advanced OO Patterns 11 / 44
Simple lazy initialization
1 <?php
2
3 class DatabaseInitializer
4 {
5 p r o t e c t e d $dsn ;
6
7 p r o t e c t e d $db ;
8
9 public function c o n s t r u c t ( $dsn )
10 {
11 $ t h i s − sn = $dsn ;
>d
12 }
13
14 p u b l i c f u n c t i o n getDatabase ()
15 {
16 i f ( $this− >db === n u l l )
17 {
18 $this− >db = new D a t a b a s e ( $ t h i s − s n ) ;
>d
19 }
20 return $this− >db ;
21 }
22 }
29. Advanced OO Patterns 11 / 44
Simple lazy initialization
1 <?php
2
3 class DatabaseInitializer
4 {
5 p r o t e c t e d $dsn ;
6
7 p r o t e c t e d $db ;
8
9 public function c o n s t r u c t ( $dsn )
10 {
11 $ t h i s − sn = $dsn ;
>d
12 }
13
14 p u b l i c f u n c t i o n getDatabase ()
15 {
16 i f ( $this− >db === n u l l )
17 {
18 $this− >db = new D a t a b a s e ( $ t h i s − s n ) ;
>d
19 }
20 return $this− >db ;
21 }
22 }
30. Advanced OO Patterns 11 / 44
Simple lazy initialization
1 <?php
2
3 class DatabaseInitializer
4 {
5 p r o t e c t e d $dsn ;
6
7 p r o t e c t e d $db ;
8
9 public function c o n s t r u c t ( $dsn )
10 {
11 $ t h i s − sn = $dsn ;
>d
12 }
13
14 p u b l i c f u n c t i o n getDatabase ()
15 {
16 i f ( $this− >db === n u l l )
17 {
18 $this− >db = new D a t a b a s e ( $ t h i s − s n ) ;
>d
19 }
20 return $this− >db ;
21 }
22 }
31. Advanced OO Patterns 12 / 44
Outline
Introduction
Lazy Initialization
Dependency Injection
Service Locator
Data Storage
32. Advanced OO Patterns 13 / 44
Goals of good OO design
Modular
Flexible
Reusable
Testable
S.O.L.I.D.
(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
33. Advanced OO Patterns 13 / 44
Goals of good OO design
Modular
Flexible
Reusable
Testable
S.O.L.I.D.
(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
34. Advanced OO Patterns 13 / 44
Goals of good OO design
Modular
Flexible
Reusable
Testable
S.O.L.I.D.
(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
35. Advanced OO Patterns 13 / 44
Goals of good OO design
Modular
Flexible
Reusable
Testable
S.O.L.I.D.
(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
36. Advanced OO Patterns 13 / 44
Goals of good OO design
Modular
Flexible
Reusable
Testable
S.O.L.I.D.
(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
37. Advanced OO Patterns 14 / 44
What’s the problem here?
1 <?php
2
3 c l a s s MessageDispatcher
4 { Inflexible
5 public function construct ()
6
7
{
$this−>m e s s e n g e r s [ ] = new
Not reusable
JabberMessenger () ;
8 $this−>m e s s e n g e r s [ ] = new Hardly testable
MailMessenger () ;
9 }
10 }
11
12 c l a s s MailMessenger implements Messenger
13 {
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 ( )− o g ( $ t e x t
>l
);
17 $ t h i s − e n d M a i l ( /∗ . . . ∗/ ) ;
>s
18 }
19 }
38. Advanced OO Patterns 14 / 44
What’s the problem here?
1 <?php
2
3 c l a s s MessageDispatcher
4 { Inflexible
5 public function construct ()
6
7
{
$this−>m e s s e n g e r s [ ] = new
Not reusable
JabberMessenger () ;
8 $this−>m e s s e n g e r s [ ] = new Hardly testable
MailMessenger () ;
9 }
10 }
11
12 c l a s s MailMessenger implements Messenger
13 {
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 ( )− o g ( $ t e x t
>l
);
17 $ t h i s − e n d M a i l ( /∗ . . . ∗/ ) ;
>s
18 }
19 }
39. Advanced OO Patterns 14 / 44
What’s the problem here?
1 <?php
2
3 c l a s s MessageDispatcher
4 { Inflexible
5 public function construct ()
6
7
{
$this−>m e s s e n g e r s [ ] = new
Not reusable
JabberMessenger () ;
8 $this−>m e s s e n g e r s [ ] = new Hardly testable
MailMessenger () ;
9 }
10 }
11
12 c l a s s MailMessenger implements Messenger
13 {
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 ( )− o g ( $ t e x t
>l
);
17 $ t h i s − e n d M a i l ( /∗ . . . ∗/ ) ;
>s
18 }
19 }
40. Advanced OO Patterns 14 / 44
What’s the problem here?
1 <?php
2
3 c l a s s MessageDispatcher
4 { Inflexible
5 public function construct ()
6
7
{
$this−>m e s s e n g e r s [ ] = new
Not reusable
JabberMessenger () ;
8 $this−>m e s s e n g e r s [ ] = new Hardly testable
MailMessenger () ;
9 }
10 }
11
12 c l a s s MailMessenger implements Messenger
13 {
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 ( )− o g ( $ t e x t
>l
);
17 $ t h i s − e n d M a i l ( /∗ . . . ∗/ ) ;
>s
18 }
19 }
41. Advanced OO Patterns 15 / 44
Injecting dependencies
1 <?php
2
3 $ m e s s e n g e r = new M e s s a g e D i s p a t c h e r (
4 array (
5 new J a b b e r M e s s e n g e r ( ’ j a b b e r . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
6 new M a i l M e s s e n g e r (
7 new M a i l S m t p T r a n s p o r t ( ’ m a i l . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
8 $ l o g g e r = new L o g g e r (
9 new L o g g i n g D i s p a t c h e r (
10 array (
11 new S y s l o g L o g g e r ( ) ,
12 new F i l e S y s t e m L o g g e r ( ’ l o g / e r r o r s . l o g ’ )
13 )
14 )
15 )
16 )
17 ),
18 $logger
19 );
42. Advanced OO Patterns 15 / 44
Injecting dependencies
1 <?php
2
3 $ m e s s e n g e r = new M e s s a g e D i s p a t c h e r (
4 array (
5 new J a b b e r M e s s e n g e r ( ’ j a b b e r . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
6 new M a i l M e s s e n g e r (
7 new M a i l S m t p T r a n s p o r t ( ’ m a i l . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
8 $ l o g g e r = new L o g g e r (
9 new L o g g i n g D i s p a t c h e r (
10 array (
11 new S y s l o g L o g g e r ( ) ,
12 new F i l e S y s t e m L o g g e r ( ’ l o g / e r r o r s . l o g ’ )
13 )
14 )
15 )
16 )
17 ),
18 $logger
19 );
43. Advanced OO Patterns 15 / 44
Injecting dependencies
1 <?php
2
3 $ m e s s e n g e r = new M e s s a g e D i s p a t c h e r (
4 array (
5 new J a b b e r M e s s e n g e r ( ’ j a b b e r . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
6 new M a i l M e s s e n g e r (
7 new M a i l S m t p T r a n s p o r t ( ’ m a i l . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
8 $ l o g g e r = new L o g g e r (
9 new L o g g i n g D i s p a t c h e r (
10 array (
11 new S y s l o g L o g g e r ( ) ,
12 new F i l e S y s t e m L o g g e r ( ’ l o g / e r r o r s . l o g ’ )
13 )
14 )
15 )
16 )
17 ),
18 $logger
19 );
44. Advanced OO Patterns 15 / 44
Injecting dependencies
1 <?php
2
3 $ m e s s e n g e r = new M e s s a g e D i s p a t c h e r (
4 array (
5 new J a b b e r M e s s e n g e r ( ’ j a b b e r . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
6 new M a i l M e s s e n g e r (
7 new M a i l S m t p T r a n s p o r t ( ’ m a i l . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
8 $ l o g g e r = new L o g g e r (
9 new L o g g i n g D i s p a t c h e r (
10 array (
11 new S y s l o g L o g g e r ( ) ,
12 new F i l e S y s t e m L o g g e r ( ’ l o g / e r r o r s . l o g ’ )
13 )
14 )
15 )
16 )
17 ),
18 $logger
19 );
45. Advanced OO Patterns 15 / 44
Injecting dependencies
1 <?php
2
3 $ m e s s e n g e r = new M e s s a g e D i s p a t c h e r (
4 array (
5 new J a b b e r M e s s e n g e r ( ’ j a b b e r . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
6 new M a i l M e s s e n g e r (
7 new M a i l S m t p T r a n s p o r t ( ’ m a i l . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
8 $ l o g g e r = new L o g g e r (
9 new L o g g i n g D i s p a t c h e r (
10 array (
11 new S y s l o g L o g g e r ( ) ,
12 new F i l e S y s t e m L o g g e r ( ’ l o g / e r r o r s . l o g ’ )
13 )
14 )
15 )
16 )
17 ),
18 $logger
19 );
46. Advanced OO Patterns 15 / 44
Injecting dependencies
1 <?php
2
3 $ m e s s e n g e r = new M e s s a g e D i s p a t c h e r (
4 array (
5 new J a b b e r M e s s e n g e r ( ’ j a b b e r . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
6 new M a i l M e s s e n g e r (
7 new M a i l S m t p T r a n s p o r t ( ’ m a i l . e x a m p l e . o r g ’ , ’ u s e r ’ , ’ p a s s ’ ) ,
8 $ l o g g e r = new L o g g e r (
9 new L o g g i n g D i s p a t c h e r (
10 array (
11 new S y s l o g L o g g e r ( ) ,
12 new F i l e S y s t e m L o g g e r ( ’ l o g / e r r o r s . l o g ’ )
13 )
14 )
15 )
16 )
17 ),
18 $logger
19 );
47. Advanced OO Patterns 16 / 44
What is desired?
Don’t have ctors all over the place
Manage dependencies
Replace dependencies fine grained
Lazy initialization
48. Advanced OO Patterns 17 / 44
The Arbit DIC
Exemplary for a high-end DIC
Shared objects (initialized once)
Closures for lazy initialization
Inherent dependency resolution
Base class for custom DICs
Heavy use of interceptors
No implementation details,
see here: http://bit.ly/arbitDIC
49. Advanced OO Patterns 17 / 44
The Arbit DIC
Exemplary for a high-end DIC
Shared objects (initialized once)
Closures for lazy initialization
Inherent dependency resolution
Base class for custom DICs
Heavy use of interceptors
No implementation details,
see here: http://bit.ly/arbitDIC
50. Advanced OO Patterns 17 / 44
The Arbit DIC
Exemplary for a high-end DIC
Shared objects (initialized once)
Closures for lazy initialization
Inherent dependency resolution
Base class for custom DICs
Heavy use of interceptors
No implementation details,
see here: http://bit.ly/arbitDIC
51. Advanced OO Patterns 17 / 44
The Arbit DIC
Exemplary for a high-end DIC
Shared objects (initialized once)
Closures for lazy initialization
Inherent dependency resolution
Base class for custom DICs
Heavy use of interceptors
No implementation details,
see here: http://bit.ly/arbitDIC
52. Advanced OO Patterns 18 / 44
Managing dependencies
3 c l a s s arbitEnvironmentDIC extends arbitDependencyInjectionContainer
4 {
13 public function i n i t i a l i z e ()
14 {
38 }
39 }
53. Advanced OO Patterns 18 / 44
Managing dependencies
3 c l a s s arbitEnvironmentDIC extends arbitDependencyInjectionContainer
4 {
13 public function i n i t i a l i z e ()
14 {
38 }
39 }
54. Advanced OO Patterns 19 / 44
Managing dependencies
3 c l a s s arbitEnvironmentDIC extends arbitDependencyInjectionContainer
4 {
13 public function i n i t i a l i z e ()
14 {
15 $this− ache = f u n c t i o n ( $dic )
>c
16 {
17 r e t u r n new a r b i t F i l e s y s t e m C a c h e ( $ d i c− e q u e s t − o n t r o l l e r ) ;
>r >c
18 };
38 }
39 }
55. Advanced OO Patterns 20 / 44
Managing dependencies
3 c l a s s arbitEnvironmentDIC extends arbitDependencyInjectionContainer
4 {
13 public function i n i t i a l i z e ()
14 {
20 $this− >m e s s e n g e r = f u n c t i o n ( $ d i c )
21 {
22 r e t u r n new a r b i t M e s s e n g e r ( a r r a y (
23 ’ e m a i l ’ = $ d i c−
> >m a i l M e s s e n g e r ,
24 ) );
25 };
38 }
39 }
56. Advanced OO Patterns 21 / 44
Managing dependencies
3 c l a s s arbitEnvironmentDIC extends arbitDependencyInjectionContainer
4 {
13 public function i n i t i a l i z e ()
14 {
27 $this− >m a i l M e s s e n g e r = f u n c t i o n ( $ d i c )
28 {
29 r e t u r n new a r b i t M a i l M e s s e n g e r (
30 $ d i c−>m a i l T r a n s p o r t ,
31 $ d i c− o n f i g u r a t i o n −
>c >main ,
32 $ d i c− o n f i g u r a t i o n − r o j e c t ( $ d i c− e q u e s t − o n t r o l l e r ) ,
>c >p >r >c
33 $ d i c− i e w s− e c o r a t o r
>v >d
34 );
35 };
38 }
39 }
57. Advanced OO Patterns 22 / 44
Dependency Injection Approaches
Constructor injection
We just saw that
Setter injection
Use set*()
Default instances?
Interface injection
Specific to some containers
58. Advanced OO Patterns 22 / 44
Dependency Injection Approaches
Constructor injection
We just saw that
Setter injection
Use set*()
Default instances?
Interface injection
Specific to some containers
59. Advanced OO Patterns 22 / 44
Dependency Injection Approaches
Constructor injection
We just saw that
Setter injection
Use set*()
Default instances?
Interface injection
Specific to some containers
60. Advanced OO Patterns 23 / 44
More about DIC
Phemto - A dependency injector for PHP 5
http://phemto.sourceforge.net/
Pimple - A small PHP 5.3 dependency injection container
https://github.com/fabpot/Pimple
Bucket - Basic di-container for php
https://github.com/troelskn/bucket
Symfony Dependency Injection
http://components.symfony-project.org/
dependency-injection/
Martin Fowler on Dependency Injection
http://martinfowler.com/articles/injection.html
61. Advanced OO Patterns 23 / 44
More about DIC
Phemto - A dependency injector for PHP 5
http://phemto.sourceforge.net/
Pimple - A small PHP 5.3 dependency injection container
https://github.com/fabpot/Pimple
Bucket - Basic di-container for php
https://github.com/troelskn/bucket
Symfony Dependency Injection
http://components.symfony-project.org/
dependency-injection/
Martin Fowler on Dependency Injection
http://martinfowler.com/articles/injection.html
62. Advanced OO Patterns 24 / 44
Outline
Introduction
Lazy Initialization
Dependency Injection
Service Locator
Data Storage
63. Advanced OO Patterns 25 / 44
Service Locator
Object to retrieve a Service from
Deliver locator instead of service directly
Basically saves constructor parameters
64. Advanced OO Patterns 25 / 44
Service Locator
Object to retrieve a Service from
Deliver locator instead of service directly
Basically saves constructor parameters
65. Advanced OO Patterns 26 / 44
Service Locator
1 <?php
2
3 c l a s s MessageServiceLocator
4 {
5 public function c o n s t r u c t ( array $messengers , Logger $ l o g g e r )
6 { /∗ . . . ∗/ }
7
8 public function getMessengers ()
9 { /∗ . . . ∗/ }
10
11 public function getLogger ()
12 { /∗ . . . ∗/ }
13 }
14
15 c l a s s MessageDispatcher
16 {
17 public function construct ( MessageServiceLocator $serviceLoc )
18 { /∗ . . . ∗/ }
19 }
20
21 ?>
66. Advanced OO Patterns 26 / 44
Service Locator
1 <?php
2
3 c l a s s MessageServiceLocator
4 {
5 public function c o n s t r u c t ( array $messengers , Logger $ l o g g e r )
6 { /∗ . . . ∗/ }
7
8 public function getMessengers ()
9 { /∗ . . . ∗/ }
10
11 public function getLogger ()
12 { /∗ . . . ∗/ }
13 }
14
15 c l a s s MessageDispatcher
16 {
17 public function construct ( MessageServiceLocator $serviceLoc )
18 { /∗ . . . ∗/ }
19 }
20
21 ?>
67. Advanced OO Patterns 26 / 44
Service Locator
1 <?php
2
3 c l a s s MessageServiceLocator
4 {
5 public function c o n s t r u c t ( array $messengers , Logger $ l o g g e r )
6 { /∗ . . . ∗/ }
7
8 public function getMessengers ()
9 { /∗ . . . ∗/ }
10
11 public function getLogger ()
12 { /∗ . . . ∗/ }
13 }
14
15 c l a s s MessageDispatcher
16 {
17 public function construct ( MessageServiceLocator $serviceLoc )
18 { /∗ . . . ∗/ }
19 }
20
21 ?>
68. Advanced OO Patterns 26 / 44
Service Locator
1 <?php
2
3 c l a s s MessageServiceLocator
4 {
5 public function c o n s t r u c t ( array $messengers , Logger $ l o g g e r )
6 { /∗ . . . ∗/ }
7
8 public function getMessengers ()
9 { /∗ . . . ∗/ }
10
11 public function getLogger ()
12 { /∗ . . . ∗/ }
13 }
14
15 c l a s s MessageDispatcher
16 {
17 public function construct ( MessageServiceLocator $serviceLoc )
18 { /∗ . . . ∗/ }
19 }
20
21 ?>
72. Advanced OO Patterns 29 / 44
The situation
Model (application) Storage
store
restore
73. Advanced OO Patterns 30 / 44
Challenges
Model and storage structure differ
Object relational impedance mismatch
Different access approaches
Query language differences
Storage back end might change
Back ends could even be mixed
...
74. Advanced OO Patterns 30 / 44
Challenges
Model and storage structure differ
Object relational impedance mismatch
Different access approaches
Query language differences
Storage back end might change
Back ends could even be mixed
...
75. Advanced OO Patterns 30 / 44
Challenges
Model and storage structure differ
Object relational impedance mismatch
Different access approaches
Query language differences
Storage back end might change
Back ends could even be mixed
...
76. Advanced OO Patterns 30 / 44
Challenges
Model and storage structure differ
Object relational impedance mismatch
Different access approaches
Query language differences
Storage back end might change
Back ends could even be mixed
...
77. Advanced OO Patterns 30 / 44
Challenges
Model and storage structure differ
Object relational impedance mismatch
Different access approaches
Query language differences
Storage back end might change
Back ends could even be mixed
...
78. Advanced OO Patterns 30 / 44
Challenges
Model and storage structure differ
Object relational impedance mismatch
Different access approaches
Query language differences
Storage back end might change
Back ends could even be mixed
...
79. Advanced OO Patterns 30 / 44
Challenges
Model and storage structure differ
Object relational impedance mismatch
Different access approaches
Query language differences
Storage back end might change
Back ends could even be mixed
...
80. Advanced OO Patterns 31 / 44
Active Record
1 <?php
2
3 class Invoice extends ActiveRecord
4 {
5 protected $id ;
6 protected $positions ;
7 protected $vat ;
8 // . . .
9
10 public function calculateValue ()
11 { /∗ b u s i n e s s l o g i c ∗/ }
12 }
13
14 c l a s s ActiveRecord
15 {
16 public function 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 }
81. Advanced OO Patterns 31 / 44
Active Record
1 <?php
2
3 class Invoice extends ActiveRecord
4 {
5 protected $id ;
6 protected $positions ;
7 protected $vat ;
8 // . . .
9
10 public function calculateValue ()
11 { /∗ b u s i n e s s l o g i c ∗/ }
12 }
13
14 c l a s s ActiveRecord
15 {
16 public function 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 }
82. Advanced OO Patterns 31 / 44
Active Record
1 <?php
2
3 class Invoice extends ActiveRecord
4 {
5 protected $id ;
6 protected $positions ;
7 protected $vat ;
8 // . . .
9
10 public function calculateValue ()
11 { /∗ b u s i n e s s l o g i c ∗/ }
12 }
13
14 c l a s s ActiveRecord
15 {
16 public function 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 }
83. Advanced OO Patterns 31 / 44
Active Record
1 <?php
2
3 class Invoice extends ActiveRecord
4 {
5 protected $id ;
6 protected $positions ;
7 protected $vat ;
8 // . . .
9
10 public function calculateValue ()
11 { /∗ b u s i n e s s l o g i c ∗/ }
12 }
13
14 c l a s s ActiveRecord
15 {
16 public function 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 }
84. Advanced OO Patterns 32 / 44
Active Record
Combines storage and business logic
Commonly storage logic in base class
Model class corresponds to database record
85. Advanced OO Patterns 33 / 44
Evaluation
Pros Cons
Very easy to use Model structure = storage
Very few code to structure
write Classes become complex
Business logic
Storage logic
Broken object semantics
Changes ripple over
Hard to exchange storage logic
Really hard to test!
86. Advanced OO Patterns 33 / 44
Evaluation
Pros Cons
Very easy to use Model structure = storage
Very few code to structure
write Classes become complex
Business logic
Storage logic
Broken object semantics
Changes ripple over
Hard to exchange storage logic
Really hard to test!
87. Advanced OO Patterns 33 / 44
Evaluation
Pros Cons
Very easy to use Model structure = storage
Very few code to structure
write Classes become complex
Business logic
Storage logic
Broken object semantics
Changes ripple over
Hard to exchange storage logic
Really hard to test!
88. Advanced OO Patterns 33 / 44
Evaluation
Pros Cons
Very easy to use Model structure = storage
Very few code to structure
write Classes become complex
Business logic
Storage logic
Broken object semantics
Changes ripple over
Hard to exchange storage logic
Really hard to test!
89. Advanced OO Patterns 33 / 44
Evaluation
Pros Cons
Very easy to use Model structure = storage
Very few code to structure
write Classes become complex
Business logic
Storage logic
Broken object semantics
Changes ripple over
Hard to exchange storage logic
Really hard to test!
90. Advanced OO Patterns 33 / 44
Evaluation
Pros Cons
Very easy to use Model structure = storage
Very few code to structure
write Classes become complex
Business logic
Storage logic
Broken object semantics
Changes ripple over
Hard to exchange storage logic
Really hard to test!
91. Advanced OO Patterns 33 / 44
Evaluation
Pros Cons
Very easy to use Model structure = storage
Very few code to structure
write Classes become complex
Business logic
Storage logic
Broken object semantics
Changes ripple over
Hard to exchange storage logic
Really hard to test!
92. Advanced OO Patterns 33 / 44
Evaluation
Pros Cons
Very easy to use Model structure = storage
Very few code to structure
write Classes become complex
Business logic
Storage logic
Broken object semantics
Changes ripple over
Hard to exchange storage logic
Really hard to test!
93. Advanced OO Patterns 34 / 44
Lesson learned . . .
De-couple business and storage logic!
94. Advanced OO Patterns 35 / 44
Row Data Gateway
1 <?php
2
3 class Invoice
4 {
5 p r o t e c t e d $data ;
6 // . . .
7
8 public function c o n s t r u c t ( InvoiceGateway $data )
9 { $this− ata = $data ; }
>d
10
11 public function calculateValue ()
12 { /∗ b u s i n e s s l o g i c ∗/ }
13 }
14
15 c l a s s InvoiceGateway
16 {
17 protected $id ;
18 protected $positions ;
19 protected $vat ;
20
21 public function i n s e r t ()
22 { /∗ . . . ∗/ }
23 p u b l i c f u n c t i o n update ()
24 { /∗ . . . ∗/ }
25 }
95. Advanced OO Patterns 35 / 44
Row Data Gateway
1 <?php
2
3 class Invoice
4 {
5 p r o t e c t e d $data ;
6 // . . .
7
8 public function c o n s t r u c t ( InvoiceGateway $data )
9 { $this− ata = $data ; }
>d
10
11 public function calculateValue ()
12 { /∗ b u s i n e s s l o g i c ∗/ }
13 }
14
15 c l a s s InvoiceGateway
16 {
17 protected $id ;
18 protected $positions ;
19 protected $vat ;
20
21 public function i n s e r t ()
22 { /∗ . . . ∗/ }
23 p u b l i c f u n c t i o n update ()
24 { /∗ . . . ∗/ }
25 }
96. Advanced OO Patterns 35 / 44
Row Data Gateway
1 <?php
2
3 class Invoice
4 {
5 p r o t e c t e d $data ;
6 // . . .
7
8 public function c o n s t r u c t ( InvoiceGateway $data )
9 { $this− ata = $data ; }
>d
10
11 public function calculateValue ()
12 { /∗ b u s i n e s s l o g i c ∗/ }
13 }
14
15 c l a s s InvoiceGateway
16 {
17 protected $id ;
18 protected $positions ;
19 protected $vat ;
20
21 public function i n s e r t ()
22 { /∗ . . . ∗/ }
23 p u b l i c f u n c t i o n update ()
24 { /∗ . . . ∗/ }
25 }
97. Advanced OO Patterns 35 / 44
Row Data Gateway
1 <?php
2
3 class Invoice
4 {
5 p r o t e c t e d $data ;
6 // . . .
7
8 public function c o n s t r u c t ( InvoiceGateway $data )
9 { $this− ata = $data ; }
>d
10
11 public function calculateValue ()
12 { /∗ b u s i n e s s l o g i c ∗/ }
13 }
14
15 c l a s s InvoiceGateway
16 {
17 protected $id ;
18 protected $positions ;
19 protected $vat ;
20
21 public function i n s e r t ()
22 { /∗ . . . ∗/ }
23 p u b l i c f u n c t i o n update ()
24 { /∗ . . . ∗/ }
25 }
98. Advanced OO Patterns 36 / 44
Row Data Gateway
Decouples storage from business logic
Still convenient OO interface for storage
Still some objects coupled to storage
(Table Data Gateway is a somewhat similar approach)
99. Advanced OO Patterns 36 / 44
Row Data Gateway
Decouples storage from business logic
Still convenient OO interface for storage
Still some objects coupled to storage
(Table Data Gateway is a somewhat similar approach)
100. Advanced OO Patterns 37 / 44
Evaluation
Pros Cons
Easy to use Some objects model DB
Few code to write structure
Gateways can be Changes still ripple over
generated
Still hard to exchange
Easier to test storage logic
101. Advanced OO Patterns 37 / 44
Evaluation
Pros Cons
Easy to use Some objects model DB
Few code to write structure
Gateways can be Changes still ripple over
generated
Still hard to exchange
Easier to test storage logic
102. Advanced OO Patterns 37 / 44
Evaluation
Pros Cons
Easy to use Some objects model DB
Few code to write structure
Gateways can be Changes still ripple over
generated
Still hard to exchange
Easier to test storage logic
103. Advanced OO Patterns 37 / 44
Evaluation
Pros Cons
Easy to use Some objects model DB
Few code to write structure
Gateways can be Changes still ripple over
generated
Still hard to exchange
Easier to test storage logic
104. Advanced OO Patterns 37 / 44
Evaluation
Pros Cons
Easy to use Some objects model DB
Few code to write structure
Gateways can be Changes still ripple over
generated
Still hard to exchange
Easier to test storage logic
105. Advanced OO Patterns 38 / 44
Data Mapper
1 <?php
2
3 class Invoice
4 {
5 protected $positions ;
6 protected $vat ;
7 // . . .
8
9 public function calculateValue ()
10 { /∗ b u s i n e s s l o g i c ∗/ }
11 }
12
13 interface InvoiceMapper
14 {
15 public function store ( Invoice $invoice ) ;
16 public f u n c t i o n update ( I n v o i c e $ i n v o i c e ) ;
17 public f u n c t i o n f i n d B y C u s t o m e r ( Customer $ c u s t o m e r ) ;
18 }
19
20 c l a s s DbInvoiceMapper implements InvoiceMapper
21 {
22 // . . .
23 }
24
25 ?>
106. Advanced OO Patterns 38 / 44
Data Mapper
1 <?php
2
3 class Invoice
4 {
5 protected $positions ;
6 protected $vat ;
7 // . . .
8
9 public function calculateValue ()
10 { /∗ b u s i n e s s l o g i c ∗/ }
11 }
12
13 interface InvoiceMapper
14 {
15 public function store ( Invoice $invoice ) ;
16 public f u n c t i o n update ( I n v o i c e $ i n v o i c e ) ;
17 public f u n c t i o n f i n d B y C u s t o m e r ( Customer $ c u s t o m e r ) ;
18 }
19
20 c l a s s DbInvoiceMapper implements InvoiceMapper
21 {
22 // . . .
23 }
24
25 ?>
107. Advanced OO Patterns 38 / 44
Data Mapper
1 <?php
2
3 class Invoice
4 {
5 protected $positions ;
6 protected $vat ;
7 // . . .
8
9 public function calculateValue ()
10 { /∗ b u s i n e s s l o g i c ∗/ }
11 }
12
13 interface InvoiceMapper
14 {
15 public function store ( Invoice $invoice ) ;
16 public f u n c t i o n update ( I n v o i c e $ i n v o i c e ) ;
17 public f u n c t i o n f i n d B y C u s t o m e r ( Customer $ c u s t o m e r ) ;
18 }
19
20 c l a s s DbInvoiceMapper implements InvoiceMapper
21 {
22 // . . .
23 }
24
25 ?>
108. Advanced OO Patterns 38 / 44
Data Mapper
1 <?php
2
3 class Invoice
4 {
5 protected $positions ;
6 protected $vat ;
7 // . . .
8
9 public function calculateValue ()
10 { /∗ b u s i n e s s l o g i c ∗/ }
11 }
12
13 interface InvoiceMapper
14 {
15 public function store ( Invoice $invoice ) ;
16 public f u n c t i o n update ( I n v o i c e $ i n v o i c e ) ;
17 public f u n c t i o n f i n d B y C u s t o m e r ( Customer $ c u s t o m e r ) ;
18 }
19
20 c l a s s DbInvoiceMapper implements InvoiceMapper
21 {
22 // . . .
23 }
24
25 ?>
109. Advanced OO Patterns 39 / 44
Data Mapper
Decouple storage from model
No OO modelling of DB structure
Model does not even know a database exists
110. Advanced OO Patterns 40 / 44
Evaluation
Pros Cons
Complete decoupling Quite some code
Model is not aware of storage to write
Clean storage interface Mapping can
Implement different storages! become complex
DB changes only affect
mapping layer
Model changes only affect
mapping layer
Nice for testing
111. Advanced OO Patterns 40 / 44
Evaluation
Pros Cons
Complete decoupling Quite some code
Model is not aware of storage to write
Clean storage interface Mapping can
Implement different storages! become complex
DB changes only affect
mapping layer
Model changes only affect
mapping layer
Nice for testing
112. Advanced OO Patterns 40 / 44
Evaluation
Pros Cons
Complete decoupling Quite some code
Model is not aware of storage to write
Clean storage interface Mapping can
Implement different storages! become complex
DB changes only affect
mapping layer
Model changes only affect
mapping layer
Nice for testing
113. Advanced OO Patterns 40 / 44
Evaluation
Pros Cons
Complete decoupling Quite some code
Model is not aware of storage to write
Clean storage interface Mapping can
Implement different storages! become complex
DB changes only affect
mapping layer
Model changes only affect
mapping layer
Nice for testing
114. Advanced OO Patterns 40 / 44
Evaluation
Pros Cons
Complete decoupling Quite some code
Model is not aware of storage to write
Clean storage interface Mapping can
Implement different storages! become complex
DB changes only affect
mapping layer
Model changes only affect
mapping layer
Nice for testing
115. Advanced OO Patterns 40 / 44
Evaluation
Pros Cons
Complete decoupling Quite some code
Model is not aware of storage to write
Clean storage interface Mapping can
Implement different storages! become complex
DB changes only affect
mapping layer
Model changes only affect
mapping layer
Nice for testing
116. Advanced OO Patterns 40 / 44
Evaluation
Pros Cons
Complete decoupling Quite some code
Model is not aware of storage to write
Clean storage interface Mapping can
Implement different storages! become complex
DB changes only affect
mapping layer
Model changes only affect
mapping layer
Nice for testing
117. Advanced OO Patterns 40 / 44
Evaluation
Pros Cons
Complete decoupling Quite some code
Model is not aware of storage to write
Clean storage interface Mapping can
Implement different storages! become complex
DB changes only affect
mapping layer
Model changes only affect
mapping layer
Nice for testing
118. Advanced OO Patterns 41 / 44
Attribution
Large parts of this talk are inspired by
Patterns of Enterprise Application Architecture
by Martin Fowler
ISBN 978-0321127426 — http://amzn.to/PofEAA
Highy recommended!
119. Advanced OO Patterns 42 / 44
Conclusion
Patterns are not the holy grail!
They assign names to good ideas
They help you to talk about concepts
They can inspire you
120. Advanced OO Patterns 42 / 44
Conclusion
Patterns are not the holy grail!
They assign names to good ideas
They help you to talk about concepts
They can inspire you
122. Advanced OO Patterns 44 / 44
Thanks for listening
Please rate this talk at
http://joind.in/2774
and / or give me some feedback right now!
123. Advanced OO Patterns 44 / 44
Thanks for listening
Please rate this talk at
http://joind.in/2774
and / or give me some feedback right now!
This is very important for . . .
Speakers
Organizers
You!
124. Advanced OO Patterns 44 / 44
Thanks for listening
Please rate this talk at
http://joind.in/2774
and / or give me some feedback right now!
Stay in touch
Tobias Schlitt
toby@qafoo.com
@tobySen / @qafoo
Rent a PHP quality expert:
http://qafoo.com