Separation of concerns is one of the first topics that comes up when we want to move from writing code that simply works to writing code that is structured well. At first, I thought it only meant splitting code into smaller functions so it looked cleaner, was easier to reuse, and had less duplication. If a function looked too long, I would cut some lines out and move them into another function. If a piece of code looked too complex, I would do the same.
For years, I wrote code mostly based on instinct and personal preference without really asking whether there was a better way to think about structure. I did not seriously question where a responsibility should live, what a function should truly own, or whether splitting code actually improved the design. Then I started my journey in LUR to rethink the way I write code, and relearning separation of concerns became one of the first things I focused on. From that learning process, i made an article series ”What I’m Learning About Writing Better Structured Code.” and this is the first part.
Seeing the Problem
Working code is not the same as well-structured code. A program can work correctly for the current problem, current input, and current environment, yet still become difficult to change later. As the app grows, the code also needs to grow without creating unnecessary friction for the programmer or the system itself.
To see that difference more clearly, let’s look at a small Todo CLI app. At first glance, nothing seems obviously wrong with it. It runs, it accepts input, and it performs the features it promises. But if we look past the result and inspect the structure, we can start to see the real problem.
import Foundation
struct TodoItem
var title: "String"
var isDone: Bool
var todos: [TodoItem] = []
func showMenu()
print("")
print("=== Todo App ===")
print("1. Show all todos")
print("2. Add todo")
print("3. Toggle todo")
print("4. Remove todo")
print("5. Exit")
print("Choose:")
func showTodos()
if todos.isEmpty
print("No todos yet.")
return
for (index, todo) in todos.enumerated()
let mark = todo.isDone ? "[x]" : "[ ]"
print("\(index + 1). \(mark) \(todo.title)")
func addTodo()
print("Enter todo title: "\")"
if let input = readLine(), !input.trimmingCharacters(in: .whitespaces).isEmpty
todos.append(TodoItem(title: "input, isDone: false))"
print("Todo added.")
else
print("Invalid title.")
func toggleTodo()
showTodos()
if todos.isEmpty
return
print("Enter todo number to toggle:")
if let input = readLine(), let number = Int(input)
let index = number - 1
if index >= 0 && index < todos.count
todos[index].isDone.toggle()
print("Todo updated.")
else
print("Invalid number.")
else
print("Please enter a valid number.")
func removeTodo()
showTodos()
if todos.isEmpty
return
print("Enter todo number to remove:")
if let input = readLine(), let number = Int(input)
let index = number - 1
if index >= 0 && index < todos.count
let removed = todos.remove(at: index)
print("Removed: \(removed.title)")
else
print("Invalid number.")
else
print("Please enter a valid number.")
func runApp()
var isRunning = true
while isRunning
showMenu()
let choice = readLine() ?? ""
switch choice
case "1":
showTodos()
case "2":
addTodo()
case "3":
toggleTodo()
case "4":
removeTodo()
case "5":
isRunning = false
print("Goodbye.")
default:
print("Unknown option.")
runApp()
At first, this code looked fine to me because it worked. But the point of the lesson was not just to check whether the program ran. The real goal was to inspect the structure behind it.
If you cannot spot the problem yet, that is completely fine. I also did not see it clearly at first. In the next part, I will break down what separation of concerns actually means and the lens I started using to notice where the boundaries in this code were mixed.
Introduction to Separation of Concern
Separation of concerns simply means different parts of a program should handle different responsibilities. Instead of letting one place do everything, we try to give each part a clearer job. This becomes important as an app grows, because code that feels manageable at the beginning can quickly become hard to understand and harder to change.
When responsibilities are mixed together, one part of the program starts doing too many things at once. A small change
Tags:
#0
Want to run a more efficient business?
Mewayz gives you CRM, HR, Accounting, Projects & eCommerce — all in one workspace. 14-day free trial, no credit card needed.
Try Mewayz Free →