Skip to content

Commit 79c2417

Browse files
author
angelo.yanve
committed
feat: add Dependency Inversion principle implementation
1 parent c7d79f2 commit 79c2417

File tree

5 files changed

+109
-1
lines changed

5 files changed

+109
-1
lines changed

04-SOLID/04x05_DIP/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
## Example
2+
3+
In this example we are going to show a great implementation of the Dependency Inversion Principle (DIP) with the example of [EmailService](../04x02_OCP/README.md).
4+
5+
We are going to create a `EmailService` class that will be the high-level module and we will create a `SendGridService` and `MailChimpService` classes that will be the low-level modules.\
6+
We will use the `MailService` class to send an email and we will use the `SendGridService` and `MailChimpService` classes to send the email respecting the DIP.

04-SOLID/04x05_DIP/bad.ts

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
interface IMail {
2+
from: string
3+
to: string
4+
subject: string
5+
body: string
6+
//... other fields
7+
}
8+
9+
interface ShortEmailTransmissionResult {
10+
success: boolean
11+
message: string
12+
}
13+
14+
interface IMailService {
15+
sendMail(email: IMail): Promise<ShortEmailTransmissionResult>
16+
}
17+
18+
19+
class _SendGridService implements IMailService {
20+
sendMail(email: IMail): Promise<ShortEmailTransmissionResult> {
21+
// send mail
22+
return Promise.resolve({success: true, message: 'Mail sent successfully'});
23+
}
24+
}
25+
26+
class _MailChimpService implements IMailService {
27+
sendMail(email: IMail): Promise<ShortEmailTransmissionResult> {
28+
// send mail
29+
return Promise.resolve({success: true, message: 'Mail sent successfully'});
30+
}
31+
}
32+
33+
class _EmailService {
34+
// we're limiting ourselves to a particlar concrete class.
35+
private emailService: _SendGridService; // <- concretion
36+
constructor (emailService: _SendGridService) { // <- concretion
37+
this.emailService = emailService;
38+
}
39+
40+
send_newMail(email: IMail): Promise<ShortEmailTransmissionResult> {
41+
return this.emailService.sendMail(email);
42+
}
43+
}

04-SOLID/04x05_DIP/good.ts

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
interface IMail {
2+
from: string
3+
to: string
4+
subject: string
5+
body: string
6+
//... other fields
7+
}
8+
9+
interface ShortEmailTransmissionResult {
10+
success: boolean
11+
message: string
12+
}
13+
14+
interface IMailService {
15+
sendMail(email: IMail): Promise<ShortEmailTransmissionResult>
16+
}
17+
18+
19+
class SendGridService implements IMailService {
20+
sendMail(email: IMail): Promise<ShortEmailTransmissionResult> {
21+
// send mail
22+
return Promise.resolve({success: true, message: 'Mail sent successfully'});
23+
}
24+
}
25+
26+
class MailChimpService implements IMailService {
27+
sendMail(email: IMail): Promise<ShortEmailTransmissionResult> {
28+
// send mail
29+
return Promise.resolve({success: true, message: 'Mail sent successfully'});
30+
}
31+
}
32+
33+
//? IMPORTANT: We're no longer limiting ourselves to a particlar concrete class.
34+
35+
class EmailService {
36+
private emailService: IMailService; // <- abstraction
37+
constructor (emailService: IMailService) { // <- abstraction
38+
this.emailService = emailService;
39+
}
40+
41+
sendMail(email: IMail): Promise<ShortEmailTransmissionResult> {
42+
return this.emailService.sendMail(email);
43+
}
44+
45+
}

04-SOLID/04x05_DIP/use-case.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
3+
const mailChimpService = new MailChimpService();
4+
const sendGridService = new SendGridService();
5+
6+
const emailService = new EmailService(mailChimpService); //or new EmailService(sendGridService);

04-SOLID/README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,12 @@ This principle is about **inheritance** and **polymorphism**. It states that if
3737

3838
This principle is about **interfaces**. It states it’s better to have `smaller`, `focused` **interfaces** rather than large, monolithic ones.
3939

40-
**Example:** go to files[InterfaceSegregationPrinciple](./04x04_ISP)
40+
**Example:** go to files[InterfaceSegregationPrinciple](./04x04_ISP)
41+
42+
## Dependency Inversion Principle (DIP)
43+
***High-level modules should not depend on low-level modules. Both should depend on abstractions.***
44+
45+
- **High-level modules** are `interfaces` and `abstract classes` that define the policy of the application.
46+
- **Low-level modules** are the concrete `classes` that implement the policy.
47+
48+
**Example:** go to files [DependencyInversionPrinciple](./04x05_DIP)

0 commit comments

Comments
 (0)