WarsawJS Slides: Template

We talk about JavaScript. Each month in Warsaw, Poland.

Speaker

Artur Siery

Class Free OOP

2016-03-09

@dotintegral

favor composition over inheritance

My experience

  • 95% of code uses inheritance
  • Every tutorial about any language explains how to use inheritance
  • Most of developers usues inheritance as a default pattern of reusing the code

Problems with inheritance

  • Classes and objects tend to grow and grow
  • Long inheritance chains
  • Problem with function context (this is not what we expect)
  • The gorilla-banana problem

Maybe mixins? Not really...

  • There's still no agreement on how mixins should be implemented
  • Mixins introduce kind of a multi-inheritance
  • Mixins tend to add more state to your component

A great read Mixins Are Dead. Long Live Composition

Here comes the rescue!

The Good Parts

  • Chapter 1 Good Parts
  • Chapter 2 Grammar
  • Chapter 3 Objects
  • Chapter 4 Functions
  • Chapter 5 Inheritance
  • Chapter 6 Arrays
  • ...

The Better Parts

Class Free OOP

function createObj (spec) {








}
function createObj (spec) {
  let {member1, member2} = spec







}
function createObj (spec) {
  let {member1, member2} = spec
  let otherObj = createOther(spec)






}
function createObj (spec) {
  let {member1, member2} = spec
  let otherObj = createOther(spec)

  let method = () => {

  }


}
function createObj (spec) {
  let {member1, member2} = spec
  let otherObj = createOther(spec)

  let method = () => {
    otherObj.doSomething()
  }


}
function createObj (spec) {
  let {member1, member2} = spec
  let otherObj = createOther(spec)

  let method = () => {
    otherObj.doSomething()
  }

  return Object.freeze({method})
}
Classical OOP
Class
property1
property2
property3

method1()
method2()
method3()
Class Free OOP
Specification
property1
property2
property3
Operator
method1()
method2()
method3()

Application Structure

States
spec
spec
spec
spec
spec
Stateless Operators
ops
ops
ops
ops
ops

Redux-like Structure

States
Global Application State
Stateless Operators
ops
ops
ops
ops
ops

Reusing the code

function createObj (spec) {
  let obj1 = createObj1(spec)
  let obj2 = createObj2(spec)
  let obj3 = createObj3(spec)

}

Total API control

function createObj (spec) {
  let {fn1, fn2} = createObj1(spec)
  let {fn3} = createObj2(spec)
  let {fn4} = createObj3(spec)

  return Object.freeze({fn1, fn2, fn3, fn4})
}

Example

Create a Button component

Requirements
  • Can be rendered
  • Can perform action on click
  • On click - will resize with an animation

function createButton(spec) {
  let {render, isRendered} = renderable(spec)







  return Object.freeze({ render, isRendered })
}

function createButton(spec) {
  let {render, isRendered} = renderable(spec)
  let {onClick} = createLink(spec)






  return Object.freeze({ render, isRendered, onClick })
}

function createButton(spec) {
  let {render, isRendered} = renderable(spec)
  let {linkOnClick: onClick} = createLink(spec)
  let {resize} = animationHelper(spec)

  let onClick = (action) => {
    linkOnClick(action)
    resize(spec.newSize)
  }
  return Object.freeze({ render, isRendered, onClick })
}

Reuse everything

  • The type of objects we compose does not matter
  • We can reuse
    • Objects with basic set of methods (renderable)
    • Standalone components (link)
    • helper objects (animatable)

Cool Features

Functional Programming anyone?

Base assumptions of Functional Programming
  • Functions and object don't have internal states
  • Functions return modified state

Functional Programming anyone?

function createObj(spec) {

  let changeSomething = () => {
    spec.something = 'changed'
    return spec
  }

  return Object.freeze({ changeSomething })
}

It's easy to test

  • Stateless objects are very easy to test
  • Just provide initial state, run method, and check the state
  • No need for huge data mocks

Test example

let state = {value: 1}
let mathOperators = createMathOperators(state)

mathOperators.add(2)

assertEqual(state.value, 3)

Conclusion

Pros

  • Composition over inheritance!
  • Reuse everything everywhere
  • Stateless objects
  • Code portability
  • Can be used with Functional Programming and Object Programming
  • Easy testing

Cons

  • Hard to use with immutable data
  • A new convention to learn

Thanks!

Fork me on Github

Fullscreen