Refactoring to preserve Liskov's Substitution Principle.
Note: Due "super" is a reserved word, "soper" is its replacement.
/* IShape -- abstract class */
function IShape(obj) {
if(obj.area && obj.perimeter) return obj;
else return undefined;
};
/* Circle constructor */
function circle(radius) {
return IShape( {
"area": function() {
return Math.PI * radius * radius;
},
"perimeter": function() {
return 2 * Math.PI * radius;
}
});
};
/* Rectangle constructor */
function rectangle(length, width) {
return IShape( {
"area": function() {
return length * width;
},
"perimeter": function() {
return (2 * length) + (2 * width);
}
});
};
/* Triangle constructor */
function triangle(base, height) {
return IShape( {
"area": function() {
return base * height;
},
"perimeter": function() {
return undefined;
}
});
};
/* Square -- child class -- constructor */
function square(side) {
return IShape( {
"soper": rectangle(side, side),
"area": function() {
return this.soper.area();
},
"perimeter": function() {
return this.soper.perimeter(side, side);
}
});
};
/* Shapes factory */
function shapesFactory(shapeId) {
switch (shapeId.toLowerCase()) {
case "circle":
return circle;
case "rectangle":
return rectangle;
case "triangle":
return triangle;
case "square":
return square;
default:
return undefined;
}
};
// TESTS
var shape1 = shapesFactory("circle")(1);
console.log("Circle(radius=1)."+
" Area: " + shape1.area() +
" Perimeter: " + shape1.perimeter());
// output:
// Circle(radius=1). Area: 3.141592653589793 Perimeter: 6.283185307179586
var shape2 = shapesFactory("rectangle")(2,3);
console.log("Rectangle(length=2, width=3)."+
" Area: " + shape2.area() +
" Perimeter: " + shape2.perimeter());
// output:
// Rectangle(length=2, width=3). Area: 6 Perimeter: 10
var shape3 = shapesFactory("triangle")(2,3);
console.log("Triangle(base=2, height=3)."+
" Area: " + shape3.area() +
" Perimeter: " + shape3.perimeter());
// output:
// Triangle(base=2, height=3). Area: 6 Perimeter: undefined
var shape4 = shapesFactory("square")(1);
console.log("Square(radius=1)."+
" Area: " + shape4.area() +
" Perimeter: " + shape4.perimeter());
// output:
// Square(radius=1). Area: 1 Perimeter: 4
