Skip to content

Commit 27ed27b

Browse files
committed
#28 - javascript
1 parent 8e806c7 commit 27ed27b

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/**
2+
* Principio de sustitución de Liskov
3+
* puede definirse como: Cada clase que hereda de otra puede usarse como su padre sin necesidad de conocer las diferencias entre ellas.
4+
*
5+
* Fuente: https://es.wikipedia.org/wiki/Principio_de_sustituci%C3%B3n_de_Liskov
6+
*/
7+
8+
// Tenemos una clase Cocinero que prepara los diferentes platillos de un restaurante,
9+
// una clase Comida que sirve de base para todos los tipos de platillos,
10+
// una clase Pizza y Sopa que heredan de la clase Comida
11+
12+
// INCORRECTA
13+
class Comida{
14+
constructor(ingredientes){
15+
if(!Array.isArray(ingredientes)) throw new Error('ingredientes debe ser un arreglo de strings')
16+
17+
this.ingredientes = ingredientes
18+
}
19+
}
20+
21+
class Pizza extends Comida{
22+
hornear(){
23+
console.log('Horneando...');
24+
console.log('Horneado Terminado!')
25+
}
26+
}
27+
28+
class Sopa extends Comida{
29+
hervir(){
30+
console.log('Hirviendo...');
31+
console.log('Hervido Terminado!')
32+
}
33+
}
34+
35+
class Cocinero{
36+
hacerPlatillo(comida){
37+
// agregar ingredientes
38+
console.log(`Preparando ${comida.constructor.name}`);
39+
40+
41+
comida.ingredientes.forEach((ingrediente) => console.log(`añadir ${ingrediente}`))
42+
43+
/**
44+
* Al tener Pizza y Sopa métodos diferentes necesarios para su preparación
45+
* tenemos que rompemos el LSP debido a que no podemos usarlas indistintamente sino
46+
* que debemos diferenciarlas.
47+
*/
48+
if(comida instanceof Pizza) comida.hornear()
49+
50+
if(comida instanceof Sopa) comida.hervir()
51+
52+
console.log('Platillo listo!!!');
53+
}
54+
}
55+
56+
const cocinero = new Cocinero()
57+
58+
cocinero.hacerPlatillo(new Pizza(['harina', 'agua', 'queso', 'peperoni']))
59+
cocinero.hacerPlatillo(new Sopa(['agua', 'papa', 'zanahoria', 'sal']))
60+
61+
CORRECTA
62+
class Comida{
63+
constructor(ingredientes){
64+
if(!Array.isArray(ingredientes)) throw new Error('ingredientes debe ser un arreglo de strings')
65+
66+
this.ingredientes = ingredientes
67+
}
68+
69+
preparar(){ }
70+
}
71+
72+
class Pizza extends Comida{
73+
preparar() {
74+
this.hornear()
75+
}
76+
77+
hornear(){
78+
console.log('Horneando...');
79+
console.log('Horneado Terminado!')
80+
}
81+
}
82+
83+
class Sopa extends Comida{
84+
preparar(){
85+
this.hervir()
86+
}
87+
88+
hervir(){
89+
console.log('Hirviendo...');
90+
console.log('Hervido Terminado!')
91+
}
92+
}
93+
94+
class Cocinero{
95+
cocinarPlatillo(comida){
96+
// agregar ingredientes
97+
console.log(`Preparando ${comida.constructor.name}`);
98+
99+
100+
comida.ingredientes.forEach((ingrediente) => console.log(`añadir ${ingrediente}`))
101+
102+
/**
103+
* Agregando el método preparar en la clase Comida y abstrayendo el cómo se prepara la comida
104+
* podemos cumplir con el LSP, de modo de que no nos preocupamos por el tipo de la comida.
105+
*/
106+
comida.preparar()
107+
108+
console.log('Platillo listo!!!');
109+
}
110+
}
111+
112+
const cocinero = new Cocinero()
113+
114+
cocinero.hacerPlatillo(new Pizza(['harina', 'agua', 'queso', 'peperoni']))
115+
cocinero.hacerPlatillo(new Sopa(['agua', 'papa', 'zanahoria', 'sal']))
116+
117+
118+
// EXTRA
119+
120+
class Vehiculo {
121+
constructor({maxVelocidad, unidadVelocidad}){
122+
if(typeof(maxVelocidad) !== 'number') throw new Error('maxVelocidad debe ser un number')
123+
if(typeof(unidadVelocidad) !== 'string') throw new Error('unidadVelocidad debe ser un string')
124+
125+
this.maxVelocidad = maxVelocidad
126+
this.unidadVelocidad = unidadVelocidad
127+
this.velocidad = 0
128+
}
129+
130+
acelerar(aumento){
131+
if(this.velocidad + aumento > this.maxVelocidad){
132+
console.log('Velocidad Maxima alcanzada no se puede acelerar más')
133+
return
134+
}
135+
136+
this.velocidad += aumento
137+
console.log(`Velocidad actual ${this.velocidad} ${this.unidadVelocidad}`)
138+
}
139+
140+
frenar(){
141+
this.velocidad = 0
142+
console.log('Frenado Exitoso')
143+
}
144+
}
145+
146+
class NaveEspacial extends Vehiculo{
147+
constructor(props){
148+
super(props)
149+
}
150+
despegar(){
151+
console.log('Despegue')
152+
}
153+
}
154+
155+
class Automovil extends Vehiculo{
156+
constructor(props){
157+
super(props)
158+
}
159+
}
160+
161+
class Barco extends Vehiculo{
162+
constructor(props){
163+
super(props)
164+
}
165+
subirAncla(){
166+
console.log('Ancla subida')
167+
}
168+
bajarAncla(){
169+
console.log('Ancla bajada')
170+
}
171+
}
172+
173+
const vehiculos = []
174+
175+
vehiculos.push(new NaveEspacial({
176+
maxVelocidad: 10,
177+
unidadVelocidad: 'años luz'
178+
}))
179+
180+
vehiculos.push(new Automovil({
181+
maxVelocidad: 200,
182+
unidadVelocidad: 'kilomentos'
183+
}))
184+
185+
vehiculos.push(new NaveEspacial({
186+
maxVelocidad: 100,
187+
unidadVelocidad: 'milla nautica'
188+
}))
189+
190+
// Como se puede ver aunque cada subclase tiene suspropios metodos, todas pueden ser reemplazadas por su
191+
// clase base de ser necesario sin problemas.
192+
193+
vehiculos.forEach(vehiculo => {
194+
vehiculo.acelerar(10)
195+
vehiculo.frenar()
196+
vehiculo.acelerar(100)
197+
})

0 commit comments

Comments
 (0)