DEV Community

Cover image for Refactoring: Polymorphic Composition
John Peters
John Peters

Posted on • Edited on

Refactoring: Polymorphic Composition

Image: A diamond showing many facets producing different colors. One Diamond many colors. Our code is like a diamond that shows different perspectives.

Definition of Terms
We see a lot of words in IT such as Composition, Polymorphism, Functional Programming.

The most fundamental part of web based programming is the JavaScript Function, which may be collected into a module of related JavaScript Functions. The module allows using each function individually without having to import the entire file.

This is not true with Class objects. Where the entire file must be imported to use anything within.

Here are the definitions we use in this article.

Functions

  • Functions are atomic
  • Functions may or may not have parameters.
  • Function parameters are the implicit interface.
  • Functions may or may not return values.
  • Functions may or may not mutate values.
  • Functions may or may not be Pure.
  • Functions may or may not be Asynchronous.
  • Functions may or may not be Reactive (Observables)
  • Functions should each follow only one single concern.
  • Functions should be bullet proof.
  • Functions are the smallest part of creating reusable libraries.
  • Functions are true first class citizens.

Containers and Composition

Containers are made to aggregate other code parts. They are often another function or class object, which contain one or more other class or function objects.

Composition is the activity of joining functions together in a Container in order to create a workflow. We "compose" our code using reusable function or class objects and are free to have both parent containers, and child containers each doing a very specific thing.

Polymorphism

Polymorphism is the same concept as a single diamond being able to look like it has different colors. Depending on how the diamond's light source is applied, we see different colors.

Objects have properties based on the JavaScript intrinsic types.
They are : Array, Boolean, Date, Error, Function, Global, JSON, Math, Number, Object, RegExp, and String. Each property of any given object allows focus on only that "color" of the object.

JavaScript objects may be simple or complex objects. A simple object would for example be a Person.

let thomas = new Person("Thomas", "Edison");
Enter fullscreen mode Exit fullscreen mode

A complex object would look like this:

let employee = new Employee();
employee.person = 
new Person("Thomas","Edison");
employee.address =
 new Address("123 Main", "New York", "NY");
employee.payroll=
getPayrollInfo(employee.id);
employee.family=
getArrayOfPersons(employee.id);
Enter fullscreen mode Exit fullscreen mode

Polymorphic behavior is instantly spotted anytime we see a "." (dot) in our code. We can see the employee object has attributes of which we can see the values of any property using a dot or [index].

employee.person;
employee.address.street;
employee
  .address
  .proiorAddress;
Enter fullscreen mode Exit fullscreen mode

We also see the Employee object contains other objects of which we can traverse to get more information. Such as:

let address = employee.address;
let street = employee.address.street;
let state = employee.address.state;
Enter fullscreen mode Exit fullscreen mode

Notice the "horizontal" nature of gaining addressibility to values? This is the pattern of "Composition" or "horizontal inheritance", we are simply adding more properties as is needed without impacting any other property directly.

Polymorphism Implies a Starting State

If the address above returns null or undefined we know that the address has not been initialized. If it returns a value we assume it is the correct value and move on. Either way there is an associated state with respect to entry into any function.

Polymorphic Composition

Is simply joining one or more objects together and being able to see only one specific "color" of the contained object. The power of this is that each property is fully atomic and changing that property will have zero impact on any other property of the object. If the address were to change, it would not directly change the person or payroll facets of the employee object.

function changeAddress(employee,  newAddress){
  if(valid(address)){
   employee.address = newAddress;
   this.service.SaveAddress(employee.address);
  }   
}
Enter fullscreen mode Exit fullscreen mode

Polymorphic Composition

Is simply one or more parts which are controlled by a container. All of the parts should be reusable where needed and all parts should expose the interface. If all the parts follow single responsibilities and are bullet proof, we are easily able to pull parts off the shelf and integrate them at any time, anywhere, and at any place in our code. Our lives become simplified.

Polymorphic Composition is not a synonym for a Pure Function. It may contain Pure Functions, but is more than that, as it can contain any type of function, Pure or not.

Summary:

Our code is like the diamond image above, ultimately one object with many facets. Each facet is a function which changes the color in only one way without impact to other facets.

Our container is like a diamond mount to hold the diamond and ensure the same light source is applied. The colors remain constant when the container doesn't change.

Unlike the diamond comparison, we have the ability to add new facets without affecting existing code. In a sense we are enlarging the diamond to contain the new code.

// properties are facets
employee.vacation.daysLeft = 50;
employee.bonus = "5000";
// Some Properties contain other properties
employee
 .DevToArticles
 .Add("polymorphic-composition-494k");
employee
 .DevToArticles
 .ArticleName
 .Title
Enter fullscreen mode Exit fullscreen mode

Note: this article was written as a response to other articles with titles similar to these:

  • "OOP is not for JavaScript or Typescript",
  • "Polymorphism is dated",
  • "OOP was for a handicapped language",
  • "Functional Programming is better",
  • "Functional Programming is only about Pure Functions",
  • "Immutability is everything"
  • "Typescript is a crutch, it helps the OOPers to learn JavaScript"

Or articles like these?

  • "We don't need the Class",
  • "We don't need the "New" Keyword.
  • "SOLID is not for JavaScript"
  • "It's all syntactic sugar"
  • "OOP is dead"

Articles which bash OOP because it's not Pure Function like, are disingenuous and filled with half-truths. The reason is that there's nothing that stops OOP from including Pure Functions. Good OOP arrives to the functional front door just by following the Single Responsibility Principal. Everything in good OOP should be functional in nature where each function does only one thing and those parts are composed by a container.

Good programming is Polymorphic Composition.

Top comments (0)