1
+ /* 🔥 EJERCICIO:
2
+ Explora el "Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)"
3
+ y crea un ejemplo simple donde se muestre su funcionamiento
4
+ de forma correcta e incorrecta.
5
+ */
6
+
7
+ console . log ( "----- EJEMPLO SIMPLE -----" ) ;
8
+
9
+ // * Ejemplo Incorrecto (viola LSP)
10
+ // --------------------------------------------------------------------------------------------------------------
11
+ class Rectangle {
12
+ constructor ( width , height ) {
13
+ this . width = width ;
14
+ this . height = height ;
15
+ }
16
+
17
+ setWidth ( width ) {
18
+ this . width = width ;
19
+ }
20
+
21
+ setHeight ( height ) {
22
+ this . height = height ;
23
+ }
24
+
25
+ area ( ) {
26
+ return this . width * this . height ;
27
+ }
28
+ }
29
+
30
+ class Square extends Rectangle {
31
+ constructor ( side ) {
32
+ super ( side , side ) ;
33
+ }
34
+
35
+ // Override que rompe el comportamiento esperado
36
+ setWidth ( side ) {
37
+ this . width = side ;
38
+ this . height = side ; // Modifica ambos lados
39
+ }
40
+
41
+ setHeight ( side ) {
42
+ this . width = side ;
43
+ this . height = side ; // Modifica ambos lados
44
+ }
45
+ }
46
+
47
+ // Función que espera un Rectangle (pero falla con Square)
48
+ function printArea ( rectangle ) {
49
+ rectangle . setWidth ( 5 ) ;
50
+ rectangle . setHeight ( 4 ) ;
51
+ console . log ( `Área esperada: 20, Área real: ${ rectangle . area ( ) } ` ) ;
52
+ }
53
+
54
+ // Violación de LSP: El cuadrado no se comporta como un rectángulo
55
+ const rect = new Rectangle ( 5 , 5 ) ;
56
+ const square = new Square ( 5 ) ;
57
+ printArea ( rect ) ; // Área: 20 (correcto)
58
+ printArea ( square ) ; // Área: 16 (incorrecto, viola LSP)
59
+
60
+ // * Ejemplo Correcto (cumple LSP)
61
+ // --------------------------------------------------------------------------------------------------------------
62
+ class Shape {
63
+ area ( ) {
64
+ throw new Error ( "Método no implementado." ) ;
65
+ }
66
+ }
67
+
68
+ class RectangleCorrecto extends Shape {
69
+ constructor ( width , height ) {
70
+ super ( ) ;
71
+ this . width = width ;
72
+ this . height = height ;
73
+ }
74
+
75
+ setWidth ( width ) {
76
+ this . width = width ;
77
+ }
78
+
79
+ setHeight ( height ) {
80
+ this . height = height ;
81
+ }
82
+
83
+ area ( ) {
84
+ return this . width * this . height ;
85
+ }
86
+ }
87
+
88
+ class SquareCorrecto extends Shape {
89
+ constructor ( side ) {
90
+ super ( ) ;
91
+ this . side = side ;
92
+ }
93
+
94
+ setSide ( side ) {
95
+ this . side = side ;
96
+ }
97
+
98
+ area ( ) {
99
+ return this . side * this . side ;
100
+ }
101
+ }
102
+
103
+ // Función que cumple LSP
104
+ function printAreaLSP ( shape ) {
105
+ console . log ( `Área: ${ shape . area ( ) } ` ) ;
106
+ }
107
+
108
+ // Uso correcto
109
+ const rectLSP = new RectangleCorrecto ( 5 , 4 ) ;
110
+ const squareLSP = new SquareCorrecto ( 5 ) ;
111
+ printAreaLSP ( rectLSP ) ; // Área: 20
112
+ printAreaLSP ( squareLSP ) ; // Área: 25
113
+
114
+ // --------------------------------------------------------------------------------------------------------------
115
+ /* 🔥 DIFICULTAD EXTRA (opcional):
116
+ Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como
117
+ cumplir el LSP.
118
+ Instrucciones:
119
+ 1. Crea la clase Vehículo.
120
+ 2. Añade tres subclases de Vehículo.
121
+ 3. Implementa las operaciones "acelerar" y "frenar" como corresponda.
122
+ 4. Desarrolla un código que compruebe que se cumple el LSP.
123
+ */
124
+ console . log ( "\n----- JERARQUÍA DE VEHÍCULOS (LSP) -----" ) ;
125
+
126
+ // Clase base: Vehículo
127
+ class Vehiculo {
128
+ constructor ( ) {
129
+ this . velocidad = 0 ;
130
+ }
131
+
132
+ acelerar ( ) {
133
+ throw new Error ( "Método no implementado." ) ;
134
+ }
135
+
136
+ frenar ( ) {
137
+ throw new Error ( "Método no implementado." ) ;
138
+ }
139
+
140
+ mostrarVelocidad ( ) {
141
+ return `Velocidad: ${ this . velocidad } km/h` ;
142
+ }
143
+ }
144
+
145
+ // Subclase 1: Coche
146
+ class Coche extends Vehiculo {
147
+ acelerar ( ) {
148
+ this . velocidad += 10 ;
149
+ console . log ( "Coche acelerando..." ) ;
150
+ }
151
+
152
+ frenar ( ) {
153
+ this . velocidad -= 5 ;
154
+ if ( this . velocidad < 0 ) this . velocidad = 0 ;
155
+ console . log ( "Coche frenando..." ) ;
156
+ }
157
+ }
158
+
159
+ // Subclase 2: Bicicleta
160
+ class Bicicleta extends Vehiculo {
161
+ acelerar ( ) {
162
+ this . velocidad += 3 ;
163
+ console . log ( "Bicicleta pedaleando..." ) ;
164
+ }
165
+
166
+ frenar ( ) {
167
+ this . velocidad -= 2 ;
168
+ if ( this . velocidad < 0 ) this . velocidad = 0 ;
169
+ console . log ( "Bicicleta frenando..." ) ;
170
+ }
171
+ }
172
+
173
+ // Subclase 3: Motocicleta
174
+ class Motocicleta extends Vehiculo {
175
+ acelerar ( ) {
176
+ this . velocidad += 15 ;
177
+ console . log ( "Motocicleta acelerando..." ) ;
178
+ }
179
+
180
+ frenar ( ) {
181
+ this . velocidad -= 7 ;
182
+ if ( this . velocidad < 0 ) this . velocidad = 0 ;
183
+ console . log ( "Motocicleta frenando..." ) ;
184
+ }
185
+ }
186
+
187
+ // Función que cumple LSP: Trabaja con cualquier vehículo
188
+ function probarVehiculo ( vehiculo ) {
189
+ console . log ( `Probando ${ vehiculo . constructor . name } :` ) ;
190
+ vehiculo . acelerar ( ) ;
191
+ vehiculo . acelerar ( ) ;
192
+ vehiculo . frenar ( ) ;
193
+ console . log ( vehiculo . mostrarVelocidad ( ) ) ;
194
+ }
195
+
196
+ // Crear vehículos
197
+ const coche = new Coche ( ) ;
198
+ const bicicleta = new Bicicleta ( ) ;
199
+ const moto = new Motocicleta ( ) ;
200
+
201
+ // Probar cada vehículo (sin errores)
202
+ probarVehiculo ( coche ) ; // Velocidad: 15 km/h
203
+ probarVehiculo ( bicicleta ) ; // Velocidad: 4 km/h
204
+ probarVehiculo ( moto ) ; // Velocidad: 23 km/h
205
+
206
+ // * Comprobación de LSP
207
+ // --------------------------------------------------------------------------------------------------------------
208
+ // Si sustituimos Vehiculo por cualquier subclase, el comportamiento es consistente
209
+ const vehiculos = [ coche , bicicleta , moto ] ;
210
+ vehiculos . forEach ( vehiculo => {
211
+ probarVehiculo ( vehiculo ) ;
212
+ console . log ( "-----" ) ;
213
+ } ) ;
0 commit comments