Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …[Therefore,] making it easy to read makes it easier to write.
— Robert C. Martin
Functions for logic and objects for modularity
One of the main advantages of FP is providing a clean and concise way to represent business logic. Pure functions are easily tested and organized. Thus in the programming languages that support both FP and OOP, the main mean to tackle business puzzles should primarily be functions.
When the complexity of software grows to a certain level, it is absolutely crucial to structure your functions in a way that most developers can read and understand the codebase with ease. In my opinion, the best tool to do that is OOP. Using OOP with thorought domain knowledge will help you modularize functions effectively and enhance the transparency of business logic.
import of ES6 module. By way of example, in JS one could write:
import defaultExport from "module-name"; import * as name from "module-name";
As we can see, JS not only allows functions to import single functions and objects, but also can import all into namespace object e.g
name in the example. This flexibility often makes it harder to modularize functions because developers do not need to think very hard on the suitable files to put their functions. As a consequence, some functions that handle business logic could end up residing in random places. Based on my experience, to tackle the above issue in JS, developers have to learn and understand domain knowledge in details, then they may be able to organize functions in appropriate objects.
Separating domain models and business logic
One feature I am very fond of while working in Scala language is the use of
case class. In my view, this feature is the culmination of years of experience in software development. The simple of act of separating domains models from business objects help simplify implementation vastly. Scala’s
case class provides simple, yet powerful built-in functions, e.g.
apply … for handling and manipulating domain data. Scala developers also get a better sense of
case class objects when reading code as they immediately know what those objects are for.
After isolating domain models, what left in business objects are mostly pure functions. This benefits testing greatly as pure functions have less dependencies and can be independently tested. In OOP, it is not unusual to have objects that includes data and methods. However, to make the best use of programming languages like Scala, developers should adhere to the principle of dividing business and pure domain objects.
pure UI components from
business components, or in other words, dumb components and smart components. The
pure UI components are shared and reused across projects because they are only responsible for rendering and displaying correct UI representations. All logic related to handling data, validations, mappings should be done in
Immutability in pure functions
An important principal in FP that we must strictly follow is immutability of objects. Pure functions ensure the returned value or output is deterministic. Functions without side effects also increase testability of the application.
case class has this principle built inside the language. Properties in
case class objects are immutable, i.e developers are unable to change property values of existed objects, they can only create new one.
The reason functions need to be pure and values should be immutable is because functions can be composed and chained together, an example in JS:
const numbers = [2,5,6,8]; const plusOne = (a) => a + 2; const sum = (acc, current) => acc + current // first operation console.log(numbers.map(plusOne).reduce(sum,0)); ... // second operation console.log(numbers.map(minusTwo).reduce(sum,0))
We see the
const are the newly added features of the language, to encourage the usage of immutable value objects.
Good code structure increases development velocity, reduces the amount of bugs and prevent application growth of complexity. Understanding all aspects of business domain is a prerequisite for well-organized codebase. Thus investing time to learn about the domain you are working on will certainly bring great benefits.
Happy learning :)