PHP is undervalued in the world of web development. Yet, with the rise of PHP7, modern frameworks, and design principles, PHP has grown far beyond the basic scripting language it started as. In this presentation, we'll focus on what distinguishes a good PHP developer from a strong one. We'll learn how we can become better developers and make use of the SOLID design principles to deliver scalable and extendable solutions.
From Good to SOLID: How to become a better PHP developer
1. From good to SOLID
How to become a better PHP developer?
2. Katerina
Trajchevska
● Senior Software Engineer & co-
founder of Adeva
● Remote Work Advocate
● Community Volunteer
● Consultant with startups and
Fortune 500 companies
Software Engineer and co-
founder of Adeva
3. Disclaimer: Code documentation is
omitted in the following code samples
for simplicity.
In practice, you always want to
document your code.
4. Single Responsibility Principle
● A class should have one, and only one, reason to change.
● Huge benefit for maintainability and stability of already tested code.
● Uncle Bob’s everyday example: cleaning up your room
● A place for everything and everything in its place.
5.
6. What’s wrong with this class?
● Multiple responsibilities: it has to know the database structure of 2 different
tables and the output screen for displaying the article.
● 3 Reasons to change:
○ Changing the articles table
○ Changing the comments table
○ Changing the output device
How can we improve this structure?
7. Gather everything together that has the
same reason to change.
Separate the things that change for a
different reason.
8.
9.
10.
11. Result: 3 small classes with
very specific names that have
only one reason to change.
12. Open Closed Principle
● A class should be open for extension but closed for modification.
● Extend functionality by adding new code instead of changing existing code.
● Everyday example: Open Source library
● Goal: Separate the behaviors, so the system can easily be extended, but never
broken.
● Uses the concept of Polymorphism: having a single interface for different
entities.
13.
14.
15.
16.
17. What’s wrong with this example?
● The module is open for modification: every time we want to extend the
functionality, we change the AreaCalculator class.
● Code is error prone: every time we change the calculate function, all
dependencies need to be retested.
How can we improve this structure?
23. Result: Being able to extend
the system’s behavior without
changing the existing code.
24. Liskov Substitution Principle
● Any derived class should be able to substitute its parent class without the
consumer knowing it.
● Every class that implements an interface, must be able to substitute any
reference throughout the code that implements that interface.
● Everyday example: Driving
● Goal: Every part of the code should get the expected result no matter what
instance of a class you send to it, given it implements the same interface.
25.
26.
27.
28. What is wrong with this class?
● Returns a collection (object of objects) while the FileStorage returns an
array.
● Changing the FileStorage instance with an instance of DBStorage will
break the code - it expects an array and doesn’t know how to behave with
anything else it receives.
How can we fix it?
29.
30.
31. Result: Being able to replace
any class in the code with
another one that implements
the same interface without
changing anything.
32. Dependency Inversion Principle
● Never depend on anything concrete, only depend on abstractions.
● High level modules should not depend on low level modules. They should
depend on abstractions.
● All boils down to decoupling our code.
● Everyday example: Sockets and plugging electrical devices.
● Goal: to be able to change an implementation easily without altering the code
anyhow.
33.
34. What’s wrong with this example?
● The Book class depends on MySqlConnection.
● We can’t change the database connection (low level module) without changing
the Book class (high level module).
● The Book class shouldn’t care about what database engine we use.
How can we fix this?
35.
36. Result: Ability to change low
level modules without
changing the high level
modules.
37. Interface Segregation Principle
● A client should never be forced to depend on methods it doesn't use.
● Or, a client should never depend on anything more than the method it’s calling.
● Everyday example: Hiking with work backpack
● Goal: changing one method in a class shouldn’t affect classes that don’t
depend on it.
38.
39.
40.
41. What’s wrong with this class?
● It depends on the whole UserInterface and has knowledge for
unnecessary items, like how to register a user.
● It only needs the getNotifyEmail method.
How do we fix it?
46. Final words about SOLID
● Contributes to code maintainability and extensibility: saves a lot of
development effort through good software architecture.
● You can apply SOLID principles to class methods and functions as well.
● Engineering principles, not strict rules.
● Always use common sense when applying SOLID principles - beware of too
deep fractionation of your code that makes it hard to maintain.