|
1 |
| -/* |
2 |
| - * EJERCICIO: |
3 |
| - * Explora el "Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)" |
4 |
| - * y crea un ejemplo simple donde se muestre su funcionamiento |
5 |
| - * de forma correcta e incorrecta. |
6 |
| - * |
7 |
| - * DIFICULTAD EXTRA (opcional): |
8 |
| - * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como |
9 |
| - * cumplir el LSP. |
10 |
| - * Instrucciones: |
11 |
| - * 1. Crea la clase Vehículo. |
12 |
| - * 2. Añade tres subclases de Vehículo. |
13 |
| - * 3. Implementa las operaciones "acelerar" y "frenar" como corresponda. |
14 |
| - * 4. Desarrolla un código que compruebe que se cumple el LSP. |
15 |
| - */ |
16 | 1 | //EJERCICIO
|
| 2 | +console.log('\nSin LSP'); |
| 3 | +class RectangleNoLSP { |
| 4 | + constructor(height, width) { |
| 5 | + this.height = height; |
| 6 | + this.width = width; |
| 7 | + } |
17 | 8 |
|
18 |
| -/* |
| 9 | + getArea() { |
| 10 | + return this.height * this.width; |
| 11 | + } |
19 | 12 |
|
20 |
| -"Si S es un subtipo de T, entonces los objetos de tipo T en un programa de computadora pueden ser sustituidos por objetos de tipo S, sin alterar ninguna de las propiedades deseables de ese programa." |
| 13 | + rotateToVerticalPosition() { |
| 14 | + let changeValue = this.height; |
21 | 15 |
|
22 |
| -*/ |
23 |
| -class GeometricShape { |
24 |
| - constructor() { |
25 |
| - this.area = this.getArea(); |
| 16 | + if (this.width > this.height) { |
| 17 | + this.height = this.width; |
| 18 | + this.width = changeValue; |
| 19 | + } |
26 | 20 | }
|
27 | 21 |
|
28 |
| - getArea() { |
29 |
| - return 1; |
| 22 | + checkVerticalPosition() { |
| 23 | + if (this.height > this.width) { |
| 24 | + console.log('Está en posición vertical'); |
| 25 | + } else { |
| 26 | + console.log('No está en posición vertical'); |
| 27 | + } |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +class SquareNoLSP extends RectangleNoLSP { |
| 32 | + constructor(side) { |
| 33 | + super(side, side); |
30 | 34 | }
|
31 | 35 | }
|
32 | 36 |
|
33 |
| -class Rectangle extends GeometricShape { |
| 37 | +const rectangleNoLSP = new RectangleNoLSP(3, 4); |
| 38 | +const squareNoLSP = new SquareNoLSP(5); |
| 39 | + |
| 40 | +console.log('Área del círculo:', squareNoLSP.getArea()); |
| 41 | +console.log('Área del rectángulo:', rectangleNoLSP.getArea()); |
| 42 | + |
| 43 | +console.log(rectangleNoLSP.height); |
| 44 | +rectangleNoLSP.checkVerticalPosition(); |
| 45 | + |
| 46 | +rectangleNoLSP.rotateToVerticalPosition(); |
| 47 | + |
| 48 | +console.log(rectangleNoLSP.height); |
| 49 | +rectangleNoLSP.checkVerticalPosition(); |
| 50 | + |
| 51 | +console.log(squareNoLSP.height); |
| 52 | +squareNoLSP.checkVerticalPosition(); |
| 53 | + |
| 54 | +squareNoLSP.rotateToVerticalPosition(); |
| 55 | + |
| 56 | +console.log(squareNoLSP.height); |
| 57 | +squareNoLSP.checkVerticalPosition(); |
| 58 | + |
| 59 | +/* |
| 60 | +En el ejemplo anterior vemos que, si bien un cuadrado podría ser similar a un rectángulo, no son exactamente lo mismo y no se comportan igual. Como esto no se ha tenido en cuenta para el diseño de las clases, al invocar los métodos para ponerlo en posición vertical y verificar si ya lo está, el programa no funciona como debería, lo que en un caso más complejo acarrearía problemas para la reutilización del código y su mantenimiento. |
| 61 | +*/ |
| 62 | + |
| 63 | +console.log('\nCon LSP'); |
| 64 | +class Quadrilateral { |
34 | 65 | constructor(height, width) {
|
35 |
| - super(); |
36 | 66 | this.height = height;
|
37 | 67 | this.width = width;
|
38 |
| - this.area = this.getArea(); |
39 | 68 | }
|
40 | 69 |
|
41 | 70 | getArea() {
|
42 | 71 | return this.height * this.width;
|
43 | 72 | }
|
44 | 73 | }
|
45 | 74 |
|
46 |
| -class Square extends GeometricShape { |
47 |
| - constructor(height) { |
48 |
| - super(); |
49 |
| - this.height = height; |
50 |
| - this.area = this.getArea(); |
| 75 | +class Rectangle extends Quadrilateral { |
| 76 | + constructor(height, width) { |
| 77 | + super(height, width); |
51 | 78 | }
|
52 | 79 |
|
53 |
| - getArea() { |
54 |
| - return this.height ** 2; |
55 |
| - } |
56 |
| -} |
| 80 | + rotateToVerticalPosition() { |
| 81 | + let changeValue = this.height; |
57 | 82 |
|
58 |
| -class Circle extends GeometricShape { |
59 |
| - constructor(radius) { |
60 |
| - super(); |
61 |
| - this.radius = radius; |
62 |
| - this.area = this.getArea(); |
| 83 | + if (this.width > this.height) { |
| 84 | + this.height = this.width; |
| 85 | + this.width = changeValue; |
| 86 | + } |
63 | 87 | }
|
64 | 88 |
|
65 |
| - getArea() { |
66 |
| - return this.radius * 2 * Math.PI; |
| 89 | + checkVerticalPosition() { |
| 90 | + if (this.height > this.width) { |
| 91 | + console.log('Está en posición vertical'); |
| 92 | + } else { |
| 93 | + console.log('No está en posición vertical'); |
| 94 | + } |
67 | 95 | }
|
68 | 96 | }
|
69 | 97 |
|
70 |
| -function displayArea(shape) { |
71 |
| - console.log(shape.area); |
| 98 | +class Square extends Quadrilateral { |
| 99 | + constructor(side) { |
| 100 | + super(side, side); |
| 101 | + } |
72 | 102 | }
|
73 | 103 |
|
74 |
| -let square = new Square(12); |
| 104 | +const quadrilateral = new Quadrilateral(12, 10); |
| 105 | +const rectangle = new Rectangle(10, 23); |
| 106 | +const square = new Square(10); |
75 | 107 |
|
76 |
| -displayArea(square); |
| 108 | +console.log('Área de un cuadrilátero abstracto:', quadrilateral.getArea()); |
| 109 | +console.log('Área de un rectángulo:', rectangle.getArea()); |
| 110 | +console.log('Área de un cuadrado:', square.getArea()); |
| 111 | + |
| 112 | +/* |
| 113 | +"Si S es un subtipo de T, entonces los objetos de tipo T en un programa de computadora pueden ser sustituidos por objetos de tipo S, sin alterar ninguna de las propiedades deseables de ese programa." |
| 114 | +
|
| 115 | +En este caso, la capacidad de ponerse en posición vertical es única del rectángulo, y si fuera necesario sustituir un cuadrilátero cualquiera por un rectángulo, seguirán funcionando todos los métodos de la clase del cuadrilátero. Cierto que aquí solo se calcula el área de la figura, pero en un caso más complejo esto es de mucha ayuda y ahorra trabajo. |
| 116 | +*/ |
77 | 117 |
|
78 | 118 | //EXTRA
|
| 119 | +console.log('\nJerarquía de vehículos'); |
79 | 120 | class Vehicle {
|
80 | 121 | constructor() {
|
81 | 122 | this.speed = 0;
|
|
0 commit comments