DEV Community

Cover image for Readable codebase: extract conditions / predicates
le0nidas
le0nidas

Posted on • Originally published at le0nidas.gr on

2 1

Readable codebase: extract conditions / predicates

A quick way to make a codebase more readable is to extract long or complex conditions / predicates to their own functions. The function’s name will explain to the reader what is being checked allowing her to move forward instead of trying to figure out the context or the calculations that are taking place.

The task

enum class Status {
NotStarted,
InProgress,
Resolved,
Cancelled
}
class Task(
val id: Int,
val description: String,
val status: Status,
val createdAt: LocalDateTime
)

Completed tasks of the last two days

Lets assume that we have a piece of code that prints all tasks that were created in the last two days and are, as the business experts calls them, completed. Which means that are either Resolved or Cancelled.

val yesterdayAtStartOfDay = LocalDate.now().minusDays(1).atStartOfDay()
val todayAtEndOfDay = LocalDate.now().atTime(23, 59)
allTasks
.filter { task ->
(task.createdAt > yesterdayAtStartOfDay && task.createdAt < todayAtEndOfDay)
&& (task.status == Resolved || task.status == Cancelled)
}
.forEach { task -> println(task.description) }

We have two distinct concepts that can be extracted. One that will explain the date calculations and one that will force the business knowledge behind those two statuses.

createdInTheLastTwoDays()

The calculations can be extracted to a private function but since we are using Kotlin we will extract them to an extension function to make the code even more readable:

allTasks
.filter { task ->
task.createdInTheLastTwoDays()
&& (task.status == Resolved || task.status == Cancelled)
}
.forEach { task -> println(task.description) }
// extracted code:
private fun Task.createdInTheLastTwoDays(): Boolean {
val yesterdayAtStartOfDay = LocalDate.now().minusDays(1).atStartOfDay()
val todayAtEndOfDay = LocalDate.now().atTime(23, 59)
return this.createdAt > yesterdayAtStartOfDay && this.createdAt < todayAtEndOfDay
}

isCompleted()

Another benefit of having “the mentality of extraction” (yep, I just made it up) is that eventually we will come across a case like the completed which is a business term that has not been transferred to the codebase!

So we don’t just make the code more readable but we improve our domain representation and force a rule that until now was known through documentations or, even worse, through conversations only.

allTasks
.filter { task -> task.createdInTheLastTwoDays() && task.isCompleted() }
.forEach { task -> println(task.description) }
//extracted code:
class Task(
val id: Int,
val description: String,
val status: Status,
val createdAt: LocalDateTime
) {
fun isCompleted(): Boolean {
return status == Resolved
|| status == Cancelled
}
}

The reader will not have to make any calculations while reading this code or trying to understand why only those statuses are being checked.

The code speaks for itself!

Sentry mobile image

App store rankings love fast apps - mobile vitals can help you get there

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read full post →

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay