OOP is very hard. If you think that this is simple - then you are writing not too much code ;) Naming and organizing code is a complicated thing, but the main cause of that is the absence of strategy. When you will find your oop wave, you will surf like a pro. Classes will be created in seconds without any dump questions: where should I put my class and how to name it? I have a few recepts for you, on how to deal with some obstacles in that object-oriented world.

The core idea of oop is Object. This is the main thing that you should care about.
I want to add some more layers and describe connections between objects.

So we have an object (entity or item) also we have a list of items. To do some work we need to have Action (or Command). With these three sticks (Item, ItemsLIst, Action) you can beat a lot of business problems.

Imagine we need to build a task tracker. We will have the following structures

  • Items : Task, Date,
  • Lists : TaskList,
  • Actions : Notify, Create, Update, Delete

Each of the items can be expanded to a more specific area. If we need to add tasks via API - then we can have TasksListFromJson. All implementation of transforming data from one format (JSON) to another (Task) will be there. No extractors or hydrators are needed.

class TaskListFromJson(input:JSON ) {
 fun all() : Sequence<Tasks> {
  // .. iterate over input and transform it into the tasks

The same story goes with the database or other sources that can be used to retrieve Tasks. You can have TasksFromDb, TasksFromFile, NullableTasksList or InMemoryTasks, and they will have one type to follow.

Now we need to do something with our task - maybe notify example is the best for our case.

// some cron job file 
val tasks = TasksForNotify(date)
val action = NotifyAction(emailAPI)
tasks.forEach{ action.execute(it) }

We are dealing with the same layers and asking the same questions. What abstractions we need to do the job? We need items and actions that can be executed.

If we need to find tasks with another strategy or source - we can rewrite task list (or introduce a new one). The same goes for the action. When we need to change the algorithm - just change the action and gommit the code.

The main questions that you should ask yourself:

  1. What Item I need?
  2. What Action I need?

Try to use this technique in small projects. You will see how this strategy can reduce complexity and increase the speed of the coding: you already know where your classes are located and what names they will have. During my coding life, I have extended these layers: Cachabel<Item>Lists, Sortable<Item>List, <Item>ListFrom<SourceName>, Actions: Composite<Item>Action, Loggable<Item>Action, Fallback<Item>Action, Nullable<Item>Action. All these structures fit in the same area. Complexity just decreasing even if we crearte more and more classes.

In the next OOP episode, I will introduce more layers like Modifier, Constraint. Have fun, write simple code at the start and then add more and more layers.