Skip to content

Instantly share code, notes, and snippets.

@crizstian
Last active March 15, 2023 02:40
Show Gist options
  • Save crizstian/ba39c6fdbb30a40c738e3c07ea83b5c1 to your computer and use it in GitHub Desktop.
Save crizstian/ba39c6fdbb30a40c738e3c07ea83b5c1 to your computer and use it in GitHub Desktop.
Code examples of SOLID principles for JavaScript
/*
Code examples from the article: S.O.L.I.D The first 5 priciples of Object Oriented Design with JavaScript
https://medium.com/@cramirez92/s-o-l-i-d-the-first-5-priciples-of-object-oriented-design-with-javascript-790f6ac9b9fa#.7uj4n7rsa
*/
const shapeInterface = (state) => ({
type: 'shapeInterface',
area: () => state.area(state)
})
const solidShapeInterface = (state) => ({
type: 'solidShapeInterface',
volume: () => state.volume(state)
})
const manageShapeInterface = (fn) => ({
type: 'manageShapeInterface',
calculate: () => fn()
})
const square = (length) => {
const proto = {
length,
type : 'Square',
area : (args) => Math.pow(args.length, 2)
}
const basics = shapeInterface(proto)
const abstraccion = manageShapeInterface(() => basics.area())
const composite = Object.assign({}, basics, abstraccion)
return Object.assign(Object.create(composite), {length})
}
const circle = (radius) => {
const proto = {
radius,
type: 'Circle',
area: (args) => Math.PI * Math.pow(args.radius, 2)
}
const basics = shapeInterface(proto)
const abstraccion = manageShapeInterface(() => basics.area())
const composite = Object.assign({}, basics, abstraccion)
return Object.assign(Object.create(composite), {radius})
}
const cubo = (length) => {
const proto = {
length,
type : 'Cubo',
area : (args) => Math.pow(args.length, 2),
volume : (args) => Math.pow(args.length, 3)
}
const basics = shapeInterface(proto)
const complex = solidShapeInterface(proto)
const abstraccion = manageShapeInterface(() => basics.area() + complex.volume())
const composite = Object.assign({}, basics, abstraccion)
return Object.assign(Object.create(composite), {length})
}
const areaCalculator = (s) => {
const proto = {
type: 'areaCalculator',
sum() {
const area = []
for (shape of this.shapes) {
area.push(shape.calculate())
}
return area.reduce((v, c) => c += v, 0)
}
}
return Object.assign(Object.create(proto), {shapes: s})
}
const volumeCalculator = (s) => {
const proto = {
type: 'volumeCalculator'
}
const areaCalProto = Object.getPrototypeOf(areaCalculator())
const inherit = Object.assign({}, areaCalProto, proto)
return Object.assign(Object.create(inherit), {shapes: s})
}
const sumCalculatorOputter = (a) => {
const proto = {
JSON() {
return JSON.stringify(this.calculator.sum())
},
HAML() {
return `HAML format output`
},
HTML() {
return `
<h1>
Sum of the areas of provided shapes:
${this.calculator.sum()}
</h1>`
},
JADE() {
return `JADE format output`
}
}
return Object.assign(Object.create(proto), {calculator: a})
}
const shapes = [
circle(2),
square(5),
square(6)
]
const solids = [
cubo(4)
]
const areas = areaCalculator(shapes)
const volume = volumeCalculator(solids)
const output = sumCalculatorOputter(areas)
const output2 = sumCalculatorOputter(volume)
console.log(output.JSON())
console.log(output.HAML())
console.log(output.HTML())
console.log(output2.HTML())
console.log(output.JADE())
@MHerszak
Copy link

MHerszak commented May 2, 2018

Great article! I was just experimenting with Object.freeze and noticed that this setup would not work with Object.freeze. However, freeze is new to me and I wonder if freeze would make sense in a factory pattern? Do you have an opinion about that, @crizstian? Thanks!

@feynon
Copy link

feynon commented Aug 24, 2019

Great article Cristian ^, this article made me believe that I can code solutions to problem one day myself. Thanks for providing the code as a separate gist.

@damiancipolat
Copy link

Thanks for share the article, I feel that applying solid in javascript does not have the same effect as in a poo language, the use of the object.assign does not convince m at all I would have expected to see "class". I think that the best way in js to make a robust and solid code is to aim at functional programming.

@FemiOfficial
Copy link

Great article!

@Baraiboapex
Copy link

Hi @crizstian This is kind of a silly question, probably and You most likely already touched on this in the article, but how would you handle multiple interfaces similar to the example found here for c#

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/how-to-explicitly-implement-members-of-two-interfaces

If you don't mind clarifying this that would be great. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment