SlideShare a Scribd company logo
1 of 32
S.O.L.I.D. PRINCIPLES
FACEBOOK DEVC - BEIRUT
• Senior Consultant at Deloitte Digital
• Worked on Mobile Applications and their respective backends.
• Experience ranges between Mobile Development, Software
engineering & scaling, and Large-Scale Hybrid Application
development
A LITTLE ABOUT ME
Jad Salhani
Outline
• S.O.L.I.D. principles
• Being a good developer is not just about writing code.
S.O.L.I.D. Principles
• Single Responsibility Principle
• Open Closed Principle
• Liskov Substitution Principle
• Interface Segregation Principle
• Dependency Inversion Principle
S
SINGLE RESPONSIBILITY
DO ONE THING WELL
The Single Responsibility principle can be
summarized by this sentence: “Do one thing, and
do it well.”
A responsibility is a “reason to change”, and a
class or a module should have only one reason to
change.
1 <?php
2 namespace FBDevc;
3 use DB;
4
5 class OrdersReport
6 {
7 public function getOrdersInfo($startDate, $endDate)
8 {
9 $orders = $this->queryDBForOrders($startDate, $endDate);
10
11 return $this->format($orders);
12 }
13
14 protected function queryDBForOrders($startDate, $endDate)
15 { // If we would update our persistence layer in the future,
16 // we would have to do changes here too. <=> reason to change!
17 return DB::table('orders')->whereBetween('created_at', [$startDate, $endDate])->get();
18 }
19
20 protected function format($orders)
21 { // If we changed the way we want to format the output,
22 // we would have to make changes here. <=> reason to change!
23 return '<h1>Orders: ' . $orders . '</h1>';
24 }
25 }
1 <?php
2 namespace Report;
3 use ReportRepositoriesOrdersRepository;
4
5 class OrdersReport
6 {
7 protected $repo;
8 protected $formatter;
9
10 public function __construct(OrdersRepository $repo, OrdersOutPutInterface $formatter)
11 {
12 $this->repo = $repo;
13 $this->formatter = $formatter;
14 }
15
16 public function getOrdersInfo($startDate, $endDate)
17 {
18 $orders = $this->repo->getOrdersWithDate($startDate, $endDate);
19
20 return $this->formatter->output($orders);
21 }
22 }
23
24 namespace Report;
25
26 interface OrdersOutPutInterface
27 {
28 public function output($orders);
29 }
30
31 namespace Report;
32
33 class HtmlOutput implements OrdersOutPutInterface
34 {
35 public function output($orders)
36 {
37 return '<h1>Orders: ' . $orders . '</h1>';
38 }
39
40 }
41
42 namespace ReportRepositories;
43 use DB;
44
45 class OrdersRepository
46 {
47 public function getOrdersWithDate($startDate, $endDate)
48 {
49 return DB::table('orders')->whereBetween('created_at', [$startDate, $endDate])->get();
50 }
51 }
O
OPENED CLOSED
PRINCIPAL
Wikipedia
The Open / Closed Principle states that software entities
(classes, modules, functions, etc.) should be open for
extension, but closed for modification.
HUH?
• Software entities should be extendable without changing the
contents of the class you’re extending
• If Jad wants to use Salah and George, Salah and George
should have the same background so that Jad doesn’t
differentiate between them when executing his tasks.
1 <?php
2 class Salah
3 {
4 public $language;
5 public $motivation;
6
7 public function __construct($language, $motivation)
8 {
9 $this->language = $language;
10 $this->motivation = $motivation;
11 }
12
13 public function mentor(){
14 $knowledge = "If you have enough $this->motivation, you can learn $this->language";
15 return $knowledge;
16 }
17 }
18
19 class George
20 {
21 public $language;
22
23 public function __construct($language)
24 {
25 $this->language = $language;
26 }
27
28 public function mentor(){
29 $knowledge = "To learn $this->language all you need is to believe in yourself";
30 return $knowledge;
31 }
32 }
33 class Jad
34 {
35 public function improveCommunity($mentorPerson)
36 {
37
38 if ($mentorPerson instanceof Salah) {
39 $knowledge = "Salah Knowledge: {$mentorPerson->mentor()}";
40 } else {
41 $knowledge = "George Knowledge: {$mentorPerson->mentor()}";
42 }
43
44 return $knowledge;
45 }
46 }
47
48 $salah = new Salah("Javascript", "A LOT");
49 $george = new George("Node");
50 $batal = new Jad();
51 echo $batal->improveCommunity($salah);
1 <?php
2 interface FacebookLeadInterface
3 {
4 public function mentor();
5 }
6
7 class Salah implements FacebookLeadInterface
8 {
9 public $language;
10 public $motivation;
11
12 public function __construct($language, $motivation)
13 {
14 $this->language = $language;
15 $this->motivation = $motivation;
16 }
17
18 public function mentor(){
19 $knowledge = "If you have enough $this->motivation, you can learn $this->language";
20 return $knowledge;
21 }
22 }
23
24 class George implements FacebookLeadInterface
25 {
26 public $language;
27
28 public function __construct($language)
29 {
30 $this->language = $language;
31 }
32
33 public function mentor(){
34 $knowledge = "To learn $this->language all you need is to believe in yourself";
35 return $knowledge;
36 }
37 }
38
39 class Jad
40 {
41 public function improveCommunity(FacebookLeadInterface $person)
42 {
43 return "Facebook Lead Knowledge: {$person->mentor()}";
44 }
45 }
46
47 $salah = new Salah("Javascript", "A LOT");
48 $george = new George("Node");
49 $batal = new Jad();
50 echo $batal->improveCommunity($salah);
L
LISKOV SUBSTITUTION
RESPONSIBILITY
Any implementation of an abstraction
(interface) should be substitutable in any place
that the abstraction is accepted. 
Two children who learned driving from their dad should be interchangeable as
drivers.
1 <?php
2 interface FacebookLeadInterface
3 {
4 public function mentor(): string;
5 }
6
7 class Salah implements FacebookLeadInterface
8 {
9 public $language;
10 public $motivation;
11
12 public function __construct($language, $motivation)
13 {
14 $this->language = $language;
15 $this->motivation = $motivation;
16 }
17
18 public function mentor(){
19 $knowledge = "If you have enough $this->motivation, you can learn $this->language";
20 return $knowledge;
21 }
22 }
23
24 class George implements FacebookLeadInterface
25 {
26 public $language;
27
28 public function __construct($language)
29 {
30 $this->language = $language;
31 }
32
33 public function mentor(){
34
35 $knowledge = [
36 "To learn $this->language all you need is to believe in yourself",
37 "Sleep is overrated and for the weak",
38 "Working 18 hours a day is not wrong",
39 "Never stop working and improving"
40 ];
41 /*
42 Violates Liskov Substitution Principle because:
43 - the return type is different
44 - the consumer of this subclass and Salah won't work identically
45 */
46 // return $knowledge;
47
48 // to fix this
49 return join(", ", $knowledge);
50 }
51 }
I
INTERFACE SEGREGATION
RESPONSIBILITY
Jad Salhani - 2020
You don’t use an Airbus 330 to take a flying tour of a city.
• A module should not be forced to implement parts of an
interface that it doesn’t use
• Interfaces and Contracts should be split as to have no
unnecessarily implemented methods.
SPOT THE DIFFERENCE
1 <?php
2 interface Workable
3 {
4 public function work();
5 public function sleep();
6 }
7
8 class HumanWorker implements Workable
9 {
10 public function work()
11 {
12 var_dump('works');
13 }
14
15 public function sleep()
16 {
17 var_dump('sleep');
18 }
19 }
20
21 class RobotWorker implements Workable
22 {
23 public function work()
24 {
25 var_dump('works');
26 }
27
28 public function sleep()
29 {
30 // No need
31 }
32 }
1 <?php
2 interface Workable
3 {
4 public function work();
5 }
6
7 interface Sleepable
8 {
9 public function sleep();
10 }
11
12 class HumanWorker implements Workable, Sleepable
13 {
14 public function work()
15 {
16 var_dump('works');
17 }
18
19 public function sleep()
20 {
21 var_dump('sleep');
22 }
23 }
24
25 class RobotWorker implements Workable
26 {
27 public function work()
28 {
29 var_dump('works');
30 }
31 }
D
DEPENDENCY INVERSION
RESPONSIBILITY
• Not to be confused with Dependency
Injection
• High level modules should not depend on low
level modules
• All modules should depend on abstractions
not concretions
1 <?php
2 class MySQLConnection
3 {
4 /**
5 * db connection
6 */
7 public function connect()
8 {
9 var_dump('MYSQL Connection');
10 }
11 }
12
13 class PasswordReminder
14 {
15 /**
16 * @var MySQLConnection
17 */
18 private $dbConnection;
19
20
21 public function __construct(MySQLConnection
$dbConnection)
22 {
23 $this->dbConnection = $dbConnection;
24 }
25 }
1 <?php
2 interface ConnectionInterface
3 {
4 public function connect();
5 }
6
7 class DbConnection implements ConnectionInterface
8 {
9
10 /**
11 * db connection
12 */
13 public function connect()
14 {
15 var_dump('MYSQL Connection');
16 }
17 }
18
19 class PasswordReminder
20 {
21 /**
22 * @var MySQLConnection
23 */
24
25 private $dbConnection;
26
27 public function __construct(ConnectionInterface
$dbConnection)
28 {
29 $this->dbConnection = $dbConnection;
30 }
31 }
SEPARATE YOUR LAYERS
Becoming a software engineer
DIFFERENT TYPES
• Developer
• Software Engineer
Demonstration
1 class Test extends React.component {
2 service;
3
4 componentDidMount() {
5 this.service = new Service();
6 }
7
8 render() {
9 return (
10 <View>
11 {Service.getPotato()}
12 </View>
13 )
14 }
15 }
16
17
18 class Service {
19 vegetables;
20
21 constructor() {
22 this.vegetables.potato = "Very Good";
23 }
24
25 static getPotato() {
26 return this.vegetables.potato;
27 }
28
29 test() {
30 return this.vegetables.potato;
31 }
32 }
THANK YOU!
http://github.com/jadsalhani

More Related Content

Similar to S.O.L.I.D. Principles

PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodeSWIFTotter Solutions
 
Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Chris Tankersley
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in LaravelHAO-WEN ZHANG
 
Dependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPDependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPmtoppa
 
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...Constanța Developers
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormMichelangelo van Dam
 
So S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeSo S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeNeil Crookes
 
Clean code for WordPress
Clean code for WordPressClean code for WordPress
Clean code for WordPressmtoppa
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Yevhen Kotelnytskyi
 
Advanced Interfaces and Repositories in Laravel
Advanced Interfaces and Repositories in LaravelAdvanced Interfaces and Repositories in Laravel
Advanced Interfaces and Repositories in LaravelJonathan Behr
 
OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsChris Tankersley
 
OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsChris Tankersley
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibilitymachuga
 
2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#Daniel Fisher
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Yevhen Kotelnytskyi
 

Similar to S.O.L.I.D. Principles (20)

PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
 
Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016Coming to Terms with OOP In Drupal - php[world] 2016
Coming to Terms with OOP In Drupal - php[world] 2016
 
Android Data Persistence
Android Data PersistenceAndroid Data Persistence
Android Data Persistence
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Dependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPDependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHP
 
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStorm
 
So S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeSo S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better Code
 
Fatc
FatcFatc
Fatc
 
Clean code for WordPress
Clean code for WordPressClean code for WordPress
Clean code for WordPress
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
 
Advanced Interfaces and Repositories in Laravel
Advanced Interfaces and Repositories in LaravelAdvanced Interfaces and Repositories in Laravel
Advanced Interfaces and Repositories in Laravel
 
OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP Is More Than Cars and Dogs
OOP Is More Than Cars and Dogs
 
SOLID
SOLIDSOLID
SOLID
 
OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP Is More Than Cars and Dogs
OOP Is More Than Cars and Dogs
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibility
 
2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
 
Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
 

Recently uploaded

SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 

Recently uploaded (20)

SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 

S.O.L.I.D. Principles

  • 2. • Senior Consultant at Deloitte Digital • Worked on Mobile Applications and their respective backends. • Experience ranges between Mobile Development, Software engineering & scaling, and Large-Scale Hybrid Application development A LITTLE ABOUT ME Jad Salhani
  • 3. Outline • S.O.L.I.D. principles • Being a good developer is not just about writing code.
  • 5. • Single Responsibility Principle • Open Closed Principle • Liskov Substitution Principle • Interface Segregation Principle • Dependency Inversion Principle
  • 7.
  • 8. DO ONE THING WELL The Single Responsibility principle can be summarized by this sentence: “Do one thing, and do it well.” A responsibility is a “reason to change”, and a class or a module should have only one reason to change.
  • 9. 1 <?php 2 namespace FBDevc; 3 use DB; 4 5 class OrdersReport 6 { 7 public function getOrdersInfo($startDate, $endDate) 8 { 9 $orders = $this->queryDBForOrders($startDate, $endDate); 10 11 return $this->format($orders); 12 } 13 14 protected function queryDBForOrders($startDate, $endDate) 15 { // If we would update our persistence layer in the future, 16 // we would have to do changes here too. <=> reason to change! 17 return DB::table('orders')->whereBetween('created_at', [$startDate, $endDate])->get(); 18 } 19 20 protected function format($orders) 21 { // If we changed the way we want to format the output, 22 // we would have to make changes here. <=> reason to change! 23 return '<h1>Orders: ' . $orders . '</h1>'; 24 } 25 }
  • 10. 1 <?php 2 namespace Report; 3 use ReportRepositoriesOrdersRepository; 4 5 class OrdersReport 6 { 7 protected $repo; 8 protected $formatter; 9 10 public function __construct(OrdersRepository $repo, OrdersOutPutInterface $formatter) 11 { 12 $this->repo = $repo; 13 $this->formatter = $formatter; 14 } 15 16 public function getOrdersInfo($startDate, $endDate) 17 { 18 $orders = $this->repo->getOrdersWithDate($startDate, $endDate); 19 20 return $this->formatter->output($orders); 21 } 22 } 23 24 namespace Report; 25 26 interface OrdersOutPutInterface 27 { 28 public function output($orders); 29 } 30 31 namespace Report; 32 33 class HtmlOutput implements OrdersOutPutInterface 34 { 35 public function output($orders) 36 { 37 return '<h1>Orders: ' . $orders . '</h1>'; 38 } 39 40 } 41 42 namespace ReportRepositories; 43 use DB; 44 45 class OrdersRepository 46 { 47 public function getOrdersWithDate($startDate, $endDate) 48 { 49 return DB::table('orders')->whereBetween('created_at', [$startDate, $endDate])->get(); 50 } 51 }
  • 12. Wikipedia The Open / Closed Principle states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
  • 13. HUH? • Software entities should be extendable without changing the contents of the class you’re extending • If Jad wants to use Salah and George, Salah and George should have the same background so that Jad doesn’t differentiate between them when executing his tasks.
  • 14. 1 <?php 2 class Salah 3 { 4 public $language; 5 public $motivation; 6 7 public function __construct($language, $motivation) 8 { 9 $this->language = $language; 10 $this->motivation = $motivation; 11 } 12 13 public function mentor(){ 14 $knowledge = "If you have enough $this->motivation, you can learn $this->language"; 15 return $knowledge; 16 } 17 } 18 19 class George 20 { 21 public $language; 22 23 public function __construct($language) 24 { 25 $this->language = $language; 26 } 27 28 public function mentor(){ 29 $knowledge = "To learn $this->language all you need is to believe in yourself"; 30 return $knowledge; 31 } 32 } 33 class Jad 34 { 35 public function improveCommunity($mentorPerson) 36 { 37 38 if ($mentorPerson instanceof Salah) { 39 $knowledge = "Salah Knowledge: {$mentorPerson->mentor()}"; 40 } else { 41 $knowledge = "George Knowledge: {$mentorPerson->mentor()}"; 42 } 43 44 return $knowledge; 45 } 46 } 47 48 $salah = new Salah("Javascript", "A LOT"); 49 $george = new George("Node"); 50 $batal = new Jad(); 51 echo $batal->improveCommunity($salah);
  • 15. 1 <?php 2 interface FacebookLeadInterface 3 { 4 public function mentor(); 5 } 6 7 class Salah implements FacebookLeadInterface 8 { 9 public $language; 10 public $motivation; 11 12 public function __construct($language, $motivation) 13 { 14 $this->language = $language; 15 $this->motivation = $motivation; 16 } 17 18 public function mentor(){ 19 $knowledge = "If you have enough $this->motivation, you can learn $this->language"; 20 return $knowledge; 21 } 22 } 23 24 class George implements FacebookLeadInterface 25 { 26 public $language; 27 28 public function __construct($language) 29 { 30 $this->language = $language; 31 } 32 33 public function mentor(){ 34 $knowledge = "To learn $this->language all you need is to believe in yourself"; 35 return $knowledge; 36 } 37 } 38 39 class Jad 40 { 41 public function improveCommunity(FacebookLeadInterface $person) 42 { 43 return "Facebook Lead Knowledge: {$person->mentor()}"; 44 } 45 } 46 47 $salah = new Salah("Javascript", "A LOT"); 48 $george = new George("Node"); 49 $batal = new Jad(); 50 echo $batal->improveCommunity($salah);
  • 17.
  • 18. Any implementation of an abstraction (interface) should be substitutable in any place that the abstraction is accepted.  Two children who learned driving from their dad should be interchangeable as drivers.
  • 19. 1 <?php 2 interface FacebookLeadInterface 3 { 4 public function mentor(): string; 5 } 6 7 class Salah implements FacebookLeadInterface 8 { 9 public $language; 10 public $motivation; 11 12 public function __construct($language, $motivation) 13 { 14 $this->language = $language; 15 $this->motivation = $motivation; 16 } 17 18 public function mentor(){ 19 $knowledge = "If you have enough $this->motivation, you can learn $this->language"; 20 return $knowledge; 21 } 22 } 23 24 class George implements FacebookLeadInterface 25 { 26 public $language; 27 28 public function __construct($language) 29 { 30 $this->language = $language; 31 } 32 33 public function mentor(){ 34 35 $knowledge = [ 36 "To learn $this->language all you need is to believe in yourself", 37 "Sleep is overrated and for the weak", 38 "Working 18 hours a day is not wrong", 39 "Never stop working and improving" 40 ]; 41 /* 42 Violates Liskov Substitution Principle because: 43 - the return type is different 44 - the consumer of this subclass and Salah won't work identically 45 */ 46 // return $knowledge; 47 48 // to fix this 49 return join(", ", $knowledge); 50 } 51 }
  • 21.
  • 22. Jad Salhani - 2020 You don’t use an Airbus 330 to take a flying tour of a city.
  • 23. • A module should not be forced to implement parts of an interface that it doesn’t use • Interfaces and Contracts should be split as to have no unnecessarily implemented methods.
  • 24. SPOT THE DIFFERENCE 1 <?php 2 interface Workable 3 { 4 public function work(); 5 public function sleep(); 6 } 7 8 class HumanWorker implements Workable 9 { 10 public function work() 11 { 12 var_dump('works'); 13 } 14 15 public function sleep() 16 { 17 var_dump('sleep'); 18 } 19 } 20 21 class RobotWorker implements Workable 22 { 23 public function work() 24 { 25 var_dump('works'); 26 } 27 28 public function sleep() 29 { 30 // No need 31 } 32 } 1 <?php 2 interface Workable 3 { 4 public function work(); 5 } 6 7 interface Sleepable 8 { 9 public function sleep(); 10 } 11 12 class HumanWorker implements Workable, Sleepable 13 { 14 public function work() 15 { 16 var_dump('works'); 17 } 18 19 public function sleep() 20 { 21 var_dump('sleep'); 22 } 23 } 24 25 class RobotWorker implements Workable 26 { 27 public function work() 28 { 29 var_dump('works'); 30 } 31 }
  • 26.
  • 27. • Not to be confused with Dependency Injection • High level modules should not depend on low level modules • All modules should depend on abstractions not concretions
  • 28. 1 <?php 2 class MySQLConnection 3 { 4 /** 5 * db connection 6 */ 7 public function connect() 8 { 9 var_dump('MYSQL Connection'); 10 } 11 } 12 13 class PasswordReminder 14 { 15 /** 16 * @var MySQLConnection 17 */ 18 private $dbConnection; 19 20 21 public function __construct(MySQLConnection $dbConnection) 22 { 23 $this->dbConnection = $dbConnection; 24 } 25 } 1 <?php 2 interface ConnectionInterface 3 { 4 public function connect(); 5 } 6 7 class DbConnection implements ConnectionInterface 8 { 9 10 /** 11 * db connection 12 */ 13 public function connect() 14 { 15 var_dump('MYSQL Connection'); 16 } 17 } 18 19 class PasswordReminder 20 { 21 /** 22 * @var MySQLConnection 23 */ 24 25 private $dbConnection; 26 27 public function __construct(ConnectionInterface $dbConnection) 28 { 29 $this->dbConnection = $dbConnection; 30 } 31 } SEPARATE YOUR LAYERS
  • 31. Demonstration 1 class Test extends React.component { 2 service; 3 4 componentDidMount() { 5 this.service = new Service(); 6 } 7 8 render() { 9 return ( 10 <View> 11 {Service.getPotato()} 12 </View> 13 ) 14 } 15 } 16 17 18 class Service { 19 vegetables; 20 21 constructor() { 22 this.vegetables.potato = "Very Good"; 23 } 24 25 static getPotato() { 26 return this.vegetables.potato; 27 } 28 29 test() { 30 return this.vegetables.potato; 31 } 32 }