Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Inheritance vs. Composition
/**
* position trait
*/
const position = (state) => ({
setPosition (x, y) {
state.x = x
state.y = y
}
})
/**
* size trait
*/
const size = (state) => ({
setSize (length, width) {
state.length = length
state.width = width
}
})
/**
* radius trait
*/
const radius = (state) => ({
setRadius (radius) {
state.radius = radius
}
})
/**
* Shape factory
* has traits: position
*/
const createShape = (x, y) => {
const shape = {}
Object.assign(
shape,
position(shape)
)
shape.setPosition(x, y)
return shape
}
// or
const createShape = (x, y) => {
const shape = {
x,
y
}
return Object.assign(
shape,
position(shape)
)
}
/**
* Rectangle factory
* has traits: position, size
*/
const createRectangle = (x, y, length, width) => {
const rectangle = {}
Object.assign(
rectangle,
position(rectangle),
size(rectangle)
)
rectangle.setPosition(x, y)
rectangle.setSize(length, width)
return rectangle
}
// or
const createRectangle = (x, y, length, width) => {
const rectangle = {
x,
y,
length,
width
}
return Object.assign(
rectangle,
position(rectangle),
size(rectangle)
)
}
/**
* Circle factory
* has traits: position, radius
*/
const createCircle = (x, y, r) => {
const circle = {}
Object.assign(
circle,
position(circle),
radius(circle)
)
circle.setPosition(x, y)
circle.setRadius(r)
return circle
}
// or
const createCircle = (x, y, radius) => {
const circle = {
x,
y,
radius
}
return Object.assign(
circle,
position(circle),
radius(circle)
)
}
/**
* Usage
*/
const s1 = createShape(10, 20) //=> { x: 10, y: 20 }
const s2 = createShape(50, 60) //=> { x: 50, y: 60 }
s2.setPosition(30, 40) //=> { x: 30, y: 40 }
const r1 = createRectangle(20, 10, 30, 40) //=> { x: 20, y: 10, length: 30, width: 40 }
r1.setPosition(30, 40) //=> { x: 30, y: 40, length: 30, width: 40 }
r1.setSize(60, 80) //=> { x: 30, y: 40, length: 60, width: 80 }
const c1 = createCircle(20, 10, 30) //=> { x: 20, y: 10, r: 30 }
c1.setPosition(30, 40) //=> { x: 30, y: 40, r: 30 }
c1.setRadius(80) //=> { x: 30, y: 40, r: 80 }
/**
* Shape class
*/
class Shape {
constructor (x, y) {
this.setPosition(x, y)
}
setPosition (x, y) {
this.x = x
this.y = y
}
}
/**
* Rectangle class
*/
class Rectangle extends Shape {
constructor (x, y, length, width) {
super(x, y)
this.setSize(length, width)
}
setSize (length, width) {
this.length = length
this.width = width
}
}
/**
* Circle class
*/
class Circle extends Shape {
constructor (x, y, radius) {
super(x, y)
this.setRadius(radius)
}
setRadius (radius) {
this.radius = radius
}
}
/**
* Usage
*/
const s1 = new Shape(10, 20) //=> { x: 10, y: 20 }
const s2 = new Shape(50, 60) //=> { x: 50, y: 60 }
s2.setPosition(30, 40) //=> { x: 30, y: 40 }
const r1 = new Rectangle(20, 10, 30, 40) //=> { x: 20, y: 10, length: 30, width: 40 }
r1.setPosition(30, 40) //=> { x: 30, y: 40, length: 30, width: 40 }
r1.setSize(60, 80) //=> { x: 30, y: 40, length: 60, width: 80 }
const c1 = new Circle(20, 10, 30) //=> { x: 20, y: 10, radius: 30 }
c1.setPosition(30, 40) //=> { x: 30, y: 40, radius: 30 }
c1.setRadius(80) //=> { x: 30, y: 40, radius: 80 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment