Talk about solving cross-cutting concerns in PHP at DutchPHP Conference.
Discussed questions:
1) OOP features and limitations
2) OOP patterns for solving cross-cutting concerns
3) Aspect-Oriented approach for solving cross-cutting concerns
4) Examples of using AOP for real life application
3. ‣ Head of Software Architecture
at Alpari (RU) Forex Broker
About me:
2
lisachenko
lisachenko
4. ‣ Head of Software Architecture
at Alpari (RU) Forex Broker
‣ Have worked with computers
since 7 years old
About me:
2
lisachenko
lisachenko
5. ‣ Head of Software Architecture
at Alpari (RU) Forex Broker
‣ Have worked with computers
since 7 years old
‣ Clean code advocate, guru in
enterprise architecture
About me:
2
lisachenko
lisachenko
6. ‣ Head of Software Architecture
at Alpari (RU) Forex Broker
‣ Have worked with computers
since 7 years old
‣ Clean code advocate, guru in
enterprise architecture
‣ Author of the aspect-oriented
framework Go! AOP
http://go.aopphp.com
About me:
2
lisachenko
lisachenko
9. Agenda
‣ Advantages of Object-Oriented Paradigm
‣ Limitations of OOP and how they affect our
application
3
10. Agenda
‣ Advantages of Object-Oriented Paradigm
‣ Limitations of OOP and how they affect our
application
‣ Existing object-oriented ways of solving
cross-cutting concerns
3
11. Agenda
‣ Advantages of Object-Oriented Paradigm
‣ Limitations of OOP and how they affect our
application
‣ Existing object-oriented ways of solving
cross-cutting concerns
‣ Pros and cons: the aspect-oriented
approach of solving cross-cutting concerns
3
12. Agenda
‣ Advantages of Object-Oriented Paradigm
‣ Limitations of OOP and how they affect our
application
‣ Existing object-oriented ways of solving
cross-cutting concerns
‣ Pros and cons: the aspect-oriented
approach of solving cross-cutting concerns
‣ Examples of using aspects in real life
applications
3
23. What are the problems?
‣ Limitation of object-oriented
representation of real life processes
11
24. What are the problems?
‣ Limitation of object-oriented
representation of real life processes
‣ Essential complexity results in strong
coupling between components
11
25. What are the problems?
‣ Limitation of object-oriented
representation of real life processes
‣ Essential complexity results in strong
coupling between components
‣ Essential complexity results in scattered
implementation of our concerns
11
28. Cross-cutting concerns - why
they affect our code?
14
Task: Implement an audit system that checks
access permission for each public method over
all classes in our system and then logs this
information into the security journal.
40. Decorator
Design pattern that allows
behavior to be added to an
individual object, either
statically or dynamically,
without affecting the behavior
of other objects from the
same class.
22
45. Decorator
+ Respects LSP - We can pass an instance of a
decorator everywhere the original object is expected.
+ Keeps SRP for the original class because it doesn’t
contain secondary concerns now
- Too many decorator classes for each combination of
concern+concrete interface
- Secondary concerns (authorization, caching, etc.) are
scattered across all decorators
- Additional overhead for calling original methods
24
46. Mediator
Defines an object that
incapsulates all logic of
interactions between objects,
giving them the ability to
work without explicit
references to each other
25
53. Mediator
+ All secondary concerns can be moved to separate
classes without duplication (SRP for secondary
concerns)
+ Keeps SRP for the original class, because it doesn’t
contain secondary concerns now
+ The most flexible way of extending a system
- Requires specific changes in the original class to
perform notification of mediator
- Hard to debug code with complex logic of interaction
because there are no explicit links between objects
28
54. Текст
Take control of everything
What if we combine all the best features of the
decorator and mediator into the one pattern?
58. Go! AOP Framework
31
‣ Inspired by famous AspectJ and Spring
frameworks
‣ Over 800 stargazers on Github - thank you!
59. Go! AOP Framework
31
‣ Inspired by famous AspectJ and Spring
frameworks
‣ Over 800 stargazers on Github - thank you!
‣ Over 200k installations on Packagist
60. Go! AOP Framework
31
‣ Inspired by famous AspectJ and Spring
frameworks
‣ Over 800 stargazers on Github - thank you!
‣ Over 200k installations on Packagist
‣ PHP5.6, PHP7.0 and Opcache compatible
61. Go! AOP Framework
31
‣ Inspired by famous AspectJ and Spring
frameworks
‣ Over 800 stargazers on Github - thank you!
‣ Over 200k installations on Packagist
‣ PHP5.6, PHP7.0 and Opcache compatible
‣ There are bridges for SF2, ZF2, Laravel…
77. How it works
39
The original class is renamed and replaced with a
new class with additional behavior; stored in the
cache
78. How it works
39
The original class is renamed and replaced with a
new class with additional behavior; stored in the
cache
79. How it works
39
The original class is renamed and replaced with a
new class with additional behavior; stored in the
cache
Simple inheritance
80. How it works
39
The original class is renamed and replaced with a
new class with additional behavior; stored in the
cache
Simple inheritance
81. How it works
39
The original class is renamed and replaced with a
new class with additional behavior; stored in the
cache
Simple inheritance
Overridden method
87. AOP
+ Keeps SRP for the original class because it doesn’t
contain secondary concerns now
+ All secondary concerns are stored in separate classes
without duplication (SRP for secondary concerns)
+ Very flexible way of extending our system (like mediator
does)
+ Does not require changes in original classes
- No tools to debug AOP code; no help from IDE
- Overhead for AOP initialization and execution
44
98. Logic of CircuitBreaker
50
‣ For each public method execution we count
the number of failures in APC/Memcache.
‣ If the number of failures is too high, then we
break the circuit to prevent subsequent failures.
99. Logic of CircuitBreaker
50
‣ For each public method execution we count
the number of failures in APC/Memcache.
‣ If the number of failures is too high, then we
break the circuit to prevent subsequent failures.
‣ If the circuit is broken, then the original method
body should not be executed for the
configured amount of time.
100. Logic of CircuitBreaker
50
‣ For each public method execution we count
the number of failures in APC/Memcache.
‣ If the number of failures is too high, then we
break the circuit to prevent subsequent failures.
‣ If the circuit is broken, then the original method
body should not be executed for the
configured amount of time.
‣ https://github.com/ejsmont-artur/php-circuit-
breaker can be used.
111. More examples for AOP
55
‣ Profiling methods with pinba extension and
Intaro Pinboard
112. More examples for AOP
55
‣ Profiling methods with pinba extension and
Intaro Pinboard
‣ Feature toggle pattern
113. More examples for AOP
55
‣ Profiling methods with pinba extension and
Intaro Pinboard
‣ Feature toggle pattern
‣ Authorization control
114. More examples for AOP
55
‣ Profiling methods with pinba extension and
Intaro Pinboard
‣ Feature toggle pattern
‣ Authorization control
‣ Traditional caching, logging, transaction
control, security audit
115. More examples for AOP
55
‣ Profiling methods with pinba extension and
Intaro Pinboard
‣ Feature toggle pattern
‣ Authorization control
‣ Traditional caching, logging, transaction
control, security audit
‣ Design by contract programming (Php-Deal
library)
116. More examples for AOP
55
‣ Profiling methods with pinba extension and
Intaro Pinboard
‣ Feature toggle pattern
‣ Authorization control
‣ Traditional caching, logging, transaction
control, security audit
‣ Design by contract programming (Php-Deal
library)
‣ Aspect-oriented testing (AspectMock)
118. Conclusion
56
‣ OOP is a nice tool for solving accidental
complexity but not for essential complexity.
119. Conclusion
56
‣ OOP is a nice tool for solving accidental
complexity but not for essential complexity.
‣ Pay attention to code scattering and code
tangling.
120. Conclusion
56
‣ OOP is a nice tool for solving accidental
complexity but not for essential complexity.
‣ Pay attention to code scattering and code
tangling.
‣ Try to extract secondary concerns into
separate classes via OOP decomposition for
small applications.
121. Conclusion
56
‣ OOP is a nice tool for solving accidental
complexity but not for essential complexity.
‣ Pay attention to code scattering and code
tangling.
‣ Try to extract secondary concerns into
separate classes via OOP decomposition for
small applications.
‣ Try to use AOP for complex enterprise
applications.
122. Thank you for the attention!
https://github.com/goaop
https://github.com/lisachenko
https://twitter.com/lisachenko