class Shape { constructor (type, ...args) { super(); switch (type) { case 'rect': return new Rectangle(...args); case 'circle': return new Circle(...args); } } } class Circle extends Shape { constructor (radius) { this.radius = radius; } surface () { return Math.PI * this.radius ** 2; } } class Rect extends Shape { constructor (width, height) { this.width = width; this.height = height; } surface () { return this.width * this.height; } } // factory method (Static Factory) Shape.create('circle', [4]); // abstract factory new Shape.CircleFactory().create(4); new Shape.RectFactory().create(5, 3); new Shape('circle', 4); new Shape('rect', 5, 3);