The Art of Clean Code: Lessons from 10 Years of Programming

4 min read
best practicessoftware engineering

After a decade of writing code professionally, I've learned that the difference between good code and great code often comes down to a few fundamental principles. Clean code isn't about being clever—it's about being clear.

The Foundation: Readability Above All

The most important lesson I've learned is that code is read far more often than it's written. Every line you write will be read dozens, maybe hundreds of times by you and your teammates.

Names Matter More Than You Think

Early in my career, I wrote code like this:

func calc(_ a: Double, _ b: Double, _ t: String) -> Double {
    return t == "add" ? a + b : a - b
}

Today, I write:

func calculateTotal(basePrice: Double, discount: Double, operationType: String) -> Double {
    return operationType == "add" 
        ? basePrice + discount 
        : basePrice - discount
}

The difference? The second version tells you a story. You don't need to guess what a, b, or t mean.

Functions Should Do One Thing

This principle from "Clean Code" by Robert Martin has saved me countless hours of debugging:

// Bad: Function doing too many things
func processUser(_ user: User) {
    validateUser(user)
    saveToDatabase(user)
    sendWelcomeEmail(user)
    logUserActivity(user)
    updateCache(user)
}

// Good: Each function has a single responsibility
func registerUser(_ user: User) -> User {
    let validatedUser = validateUser(user)
    let savedUser = saveToDatabase(validatedUser)
    
    sendWelcomeEmail(savedUser)
    logUserActivity(savedUser)
    updateCache(savedUser)
    
    return savedUser
}

The second version is easier to test, easier to debug, and easier to modify.

Early Returns Keep Code Flat

One of the simplest ways to improve readability is to avoid deep nesting:

// Bad: Deep nesting
func processOrder(_ order: Order?) -> Bool {
    if let order = order {
        if order.items.count > 0 {
            if let user = order.user {
                if user.hasPaymentMethod {
                    // Process order
                    return true
                }
            }
        }
    }
    return false
}

// Good: Early returns
func processOrder(_ order: Order?) -> Bool {
    guard let order = order else { return false }
    guard order.items.count > 0 else { return false }
    guard let user = order.user else { return false }
    guard user.hasPaymentMethod else { return false }
    
    // Process order
    return true
}

The second version reads like a checklist. Each condition is clear and at the same indentation level.

Comments Should Explain Why, Not What

Your code should be self-documenting for the "what." Comments should explain the "why":

// Bad comment
// Multiply price by 1.2
let finalPrice = price * 1.2

// Good comment
// Apply 20% luxury tax as required by local regulations
let finalPrice = price * 1.2

// Even better: Make it self-documenting
let luxuryTaxRate = 1.2
let finalPrice = price * luxuryTaxRate

The Boy Scout Rule

Always leave the code better than you found it. This doesn't mean rewriting entire modules—sometimes it's just renaming a variable or extracting a function.

// Found in codebase
let x = users.filter { $0.age >= 18 }

// After applying Boy Scout Rule
let adultUsers = users.filter { user in user.age >= legalAdultAge }

Small improvements compound over time.

Testing Makes You Write Better Code

When I started writing tests first (TDD), my code naturally became more modular and easier to understand:

// Hard to test (coupled to implementation)
class UserService {
    func createUser(data: UserData) {
        let user = User(data: data)
        let db = Database()
        db.save(user)
        EmailService.send(user.email)
    }
}

// Easy to test (dependency injection)
class UserService {
    let database: DatabaseProtocol
    let emailService: EmailServiceProtocol
    
    init(database: DatabaseProtocol, emailService: EmailServiceProtocol) {
        self.database = database
        self.emailService = emailService
    }
    
    func createUser(data: UserData) async throws -> User {
        let user = User(data: data)
        try await database.save(user)
        try await emailService.send(user.email)
        return user
    }
}

Conclusion

Clean code isn't about following rules dogmatically—it's about making life easier for your future self and your teammates. These principles have guided me through countless projects, and they continue to evolve as I learn.

The best code is code that disappears. It does its job so clearly and simply that you barely notice it's there. That's the art of clean code.