Composition: The essence of Software Development

ref: https://medium.com/javascript-scene/composing-software-an-introduction-27b72500d6ea

  • What is function composition?
  • What is object composition?

You Compose Software Every Day

If you’re a software developer, you compose functions and data structures every day, whether you know it or not. You can do it consciously (and better), or you can do it accidentally, with duct-tape and crazy glue.

The process of software development is breaking down large problems into smaller problems, building components that solve those smaller problems, then composing those components together to form a complete application.

Composing Functions

Function composition is the process of applying a function to the output of another function. In algebra, given two functions, fand g, (f ∘ g)(x) = f(g(x)). The circle is the composition operator. It’s commonly pronounced “composed with” or “after”.

Every time you write a promise chain, you’re composing functions. Likewise, every time you chain array method calls, lodash methods, observables (RxJS, etc…) you’re composing functions. If you’re chaining, you’re composing. If you’re passing return values into other functions, you’re composing. If you call two methods in a sequence, you’re composing using this as input data.

Popular functional programming libraries like Lodash and Ramda include utilities to make function composition easier. You can rewrite the above function like this:

import pipe from 'lodash/fp/flow';
const doStuffBetter = pipe(
  g,
  trace('after g'),
  f,
  trace('after f')
);
doStuffBetter(20); // =>
/*
"after g: 21"
"after f: 42"
*/

If you want to try this code without importing something, you can define pipe like this:

// pipe(...fns: [...Function]) => x => y
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);

Composing Objects

“Favor object composition over class inheritance” the Gang of Four, “Design Patterns: Elements of Reusable Object Oriented Software”

“In computer science, a composite data type or compound data type is any data type which can be constructed in a program using the programming language’s primitive data types and other composite types. […] The act of constructing a composite type is known as composition.” ~ Wikipedia

Likewise, all Arrays, Sets, Maps, WeakMaps, TypedArrays, etc… are composite datatypes. Any time you build any non-primitive data structure, you’re performing some kind of object composition.

Note that the Gang of Four defines a pattern called the composite pattern which is a type of composite such that each component becomes a self-contained property of a container component.

Class inheritance can be used to construct composite objects, but it’s a restrictive and brittle way to do it. When the Gang of Four says “favor object composition over class inheritance”, they’re advising you to use flexible approaches to composite object building, rather than the rigid, tightly-coupled approach of class inheritance.

The Gang of Four also defines other composite design patterns, including the flyweight pattern, the delegate pattern, the aggregate pattern, and so on.

We’ll use a more general definition of object composition from “Categorical Methods in Computer Science: With Aspects from Topology” (1989):

“Composite objects are formed by putting objects together such that each of the latter is ‘part of’ the former.”

“Favor object composition over class inheritance” means that you should form composite objects from small component parts, rather than inheriting all properties from an ancestor in a class hierarchy.

The most common form of object composition is known as mixin composition. It works like ice-cream. You start with an object (like vanilla ice-cream), and then mix in the features you want. Add some nuts, caramel, chocolate swirl, and you wind up with nutty caramel chocolate swirl ice cream.

Building composites with mixin composition:

const a = {
  a: 'a'
};
const b = {
  b: 'b'
};
const c = {...a, ...b}; // {a: 'a', b: 'b'}

We’ll use object composition to produce datatypes for functional programming, and functional programming to produce objects for OOP.

No matter how you write software, you should compose it well.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s