sábado, 7 de junio de 2014

Javascript OOP, Visual Method - Part II

Previous post: Javascript OOP, Visual Method




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

No hay comentarios: