Skip to content

Commit cd455da

Browse files
mouredev#30 - javascript
1 parent dd2be53 commit cd455da

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
//#30 - Principio SOLID de Inversión de Dependencias (Dependency Inversion Principle (DIP))
2+
/*
3+
* EJERCICIO:
4+
* Explora el "Principio SOLID de Inversión de Dependencias (Dependency Inversion
5+
* Principle, DIP)" y crea un ejemplo simple donde se muestre su funcionamiento
6+
* de forma correcta e incorrecta.
7+
*
8+
* DIFICULTAD EXTRA (opcional):
9+
* Crea un sistema de notificaciones.
10+
* Requisitos:
11+
* 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas).
12+
* 2. El sistema de notificaciones no puede depender de las implementaciones específicas.
13+
* Instrucciones:
14+
* 1. Crea la interfaz o clase abstracta.
15+
* 2. Desarrolla las implementaciones específicas.
16+
* 3. Crea el sistema de notificaciones usando el DIP.
17+
* 4. Desarrolla un código que compruebe que se cumple el principio.
18+
*/
19+
//Bibliografy: The Web Development Glossary (Jens Oliver Meiert) (Z-Library)
20+
//GPT
21+
22+
/* Dependency Inversion Principle
23+
A specific form of decoupling software modules. When following this
24+
principle, the conventional dependency relationships established from
25+
high-level policy-setting modules to low-level dependency modules are
26+
reversed, thus rendering high-level modules independent of the low-level
27+
module implementation details. The principle states 1) that high-level
28+
modules should not depend on low-level modules, but that both should
29+
depend on abstractions (e.g., interfaces), and 2) that abstractions should
30+
not depend on details, but that details (concrete implementations) should
31+
depend on abstractions.
32+
33+
A class that contains methods for use by other classes without having to be
34+
the parent class of those other classes. How those other classes gain access
35+
to the mixin’s methods depends on the language. Mixins are sometimes
36+
described as being “included” rather than “inherited.” Mixins encourage
37+
code reuse and can be used to avoid the inheritance ambiguity that
38+
multiple inheritance can cause, or to work around lack of support for
39+
multiple inheritance in a language. A mixin can also be viewed as an
40+
interface with implemented methods. This pattern is an example of
41+
enforcing the Dependency Inversion Principle */
42+
43+
let log = console.log;
44+
45+
window.addEventListener('load', ()=>{
46+
const body = document.querySelector('body');
47+
const title = document.createElement('h1');
48+
49+
body.style.setProperty('background', '#000');
50+
body.style.setProperty('text-align', 'center');
51+
52+
title.textContent = 'Retosparaprogramadores #30.';
53+
title.style.setProperty('font-size', '3.5vmax');
54+
title.style.setProperty('color', '#fff');
55+
title.style.setProperty('line-height', '100vh');
56+
57+
body.appendChild(title);
58+
59+
setTimeout(()=>{
60+
alert('Retosparaprogramadores #30. Please open the Browser Developer Tools.');
61+
}, 2000);
62+
log( 'Retosparaprogramadores #30');
63+
});
64+
65+
//Incorrect Example
66+
67+
class USABillingService1 {
68+
calculateCharge(duration) {
69+
return duration * 0.10; // $0.10 per minute
70+
}
71+
}
72+
73+
class CallBillingService1 {
74+
constructor() {
75+
this.billingService = new USABillingService1(); // Direct dependency
76+
}
77+
78+
billCall(duration) {
79+
const charge = this.billingService.calculateCharge(duration);
80+
log(`Total charge: ${charge.toFixed(2)}`);
81+
}
82+
}
83+
84+
const callBillingService1 = new CallBillingService1();
85+
callBillingService1.billCall(22); // Total charge: 2.20
86+
87+
88+
//Correct Example
89+
90+
class IBillingService {
91+
calculateCharge(duration) {
92+
throw new Error("Method 'calculateCharge()' must be implemented for this Billing Service.");
93+
}
94+
}
95+
96+
class USABillingService extends IBillingService {
97+
constructor(){
98+
super();
99+
this.location = 'USA';
100+
}
101+
102+
calculateCharge(duration) {
103+
return duration * 0.10;
104+
}
105+
}
106+
107+
class EuropeBillingService extends IBillingService {
108+
constructor() {
109+
super();
110+
this.location = 'Europe';
111+
}
112+
113+
calculateCharge(duration) {
114+
return duration * 0.15;
115+
}
116+
}
117+
118+
class AsiaBillingService extends IBillingService {
119+
constructor() {
120+
super();
121+
this.location = 'Asia';
122+
}
123+
124+
calculateCharge(duration) {
125+
return duration * 0.05;
126+
}
127+
}
128+
129+
class CallBillingService {
130+
constructor(billingService) {
131+
this.billingService = billingService; // Dependency injection
132+
}
133+
134+
billCall(duration) {
135+
const charge = this.billingService.calculateCharge(duration);
136+
log(`Total charge for ${this.billingService.location}: ${charge.toFixed(2)}`);
137+
}
138+
}
139+
140+
const usaBillingService = new USABillingService();
141+
const europeBillingService = new EuropeBillingService();
142+
const asiaBillingService = new AsiaBillingService();
143+
144+
const callBillingServiceUSA = new CallBillingService(usaBillingService);
145+
const callBillingServiceEurope = new CallBillingService(europeBillingService);
146+
const callBillingServiceAsia = new CallBillingService(asiaBillingService);
147+
148+
callBillingServiceUSA.billCall(127.22); // Total charge for USA: 12.72
149+
callBillingServiceEurope.billCall(17.56); // Total charge for Europe: 2.63
150+
callBillingServiceAsia.billCall(45.23); // Total charge for Asia: 2.26
151+
152+
153+
//Extra Dificulty Exercise
154+
class INotificationService {
155+
send(message) {
156+
throw new Error("Method 'send()' must be implemented in this especific Notification Service.");
157+
}
158+
}
159+
160+
class EmailService extends INotificationService {
161+
send(message) {
162+
log(`Sending email: ${message}`);
163+
}
164+
}
165+
166+
class SMSService extends INotificationService {
167+
send(message) {
168+
log(`Sending SMS: ${message}`);
169+
}
170+
}
171+
172+
class PushService extends INotificationService {
173+
send(message) {
174+
log(`Sending PUSH notification: ${message}`);
175+
}
176+
}
177+
178+
class NotificationSystem {
179+
constructor(notificationService) {
180+
this.notificationService = notificationService;
181+
}
182+
183+
notify(message) {
184+
this.notificationService.send(message);
185+
}
186+
}
187+
188+
const emailService = new EmailService();
189+
const smsService = new SMSService();
190+
const pushService = new PushService();
191+
192+
const notificationSystemEmail = new NotificationSystem(emailService);
193+
const notificationSystemSMS = new NotificationSystem(smsService);
194+
const notificationSystemPush = new NotificationSystem(pushService);
195+
196+
notificationSystemEmail.notify("Testing sending a message via Email."); // Sending email: Testing sending a message via Email.
197+
notificationSystemSMS.notify("Testing sending a message via SMS."); // Sending SMS: Testing sending a message via SMS.
198+
notificationSystemPush.notify("Testing sending a message via PUSH."); // Sending PUSH notification: Testing sending a message via PUSH.

0 commit comments

Comments
 (0)