<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tien Do</title>
    <description>The latest articles on DEV Community by Tien Do (@foreverlovewisdom).</description>
    <link>https://dev.to/foreverlovewisdom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1022570%2F08b113a2-be0e-41c0-a15d-b878e2d282c1.png</url>
      <title>DEV Community: Tien Do</title>
      <link>https://dev.to/foreverlovewisdom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/foreverlovewisdom"/>
    <language>en</language>
    <item>
      <title>Discipline Can't Beat Environment — Design It Before Willpower</title>
      <dc:creator>Tien Do</dc:creator>
      <pubDate>Wed, 19 Aug 2026 21:58:02 +0000</pubDate>
      <link>https://dev.to/foreverlovewisdom/discipline-cant-beat-environment-design-it-before-willpower-3ame</link>
      <guid>https://dev.to/foreverlovewisdom/discipline-cant-beat-environment-design-it-before-willpower-3ame</guid>
      <description>&lt;p&gt;I used to think I had strong enough discipline to beat my environment. I don't. The evidence is mine: bring my phone into the bedroom, and I'll always find a reason to reach for it — reading about Buddhism, a programming concept, a podcast with some distinguished engineer. All good reasons on their face. All disturb my sleep and keep my mind in work mode instead of rest mode.&lt;/p&gt;

&lt;p&gt;Same pattern after work. I'd tell myself: stop learning at 9 pm, go to bed. One more hour creeps in, then another. Yes, that extra hour makes me more productive in terms of output. But I pay it back — always. The environment is part of me, and my habits just reflect that environment. Self-development books say this constantly. I read it, agreed with it, and still thought I was the exception — that my willpower could override it. I was wrong. This is not a fair game, and losing to it is just a matter of time.&lt;/p&gt;

&lt;p&gt;I did try changing the environment: phone further from the bed, hard stop at 9 pm, phone off during work. It didn't last — I got overconfident, decided I didn't need the guardrails anymore, and relapsed.&lt;/p&gt;

&lt;p&gt;What's helping me understand &lt;em&gt;why&lt;/em&gt; now comes from studying Buddhism seriously over the past three weeks — reading and working through difficult concepts with AI. I used to misread sīla (giới) as a negative constraint, a rule that forces you to fight and suppress your emotions. That's wrong. The reason the Buddha taught not to break sīla — to reduce the chances of breaking it — is that otherwise you spend significant time dwelling on it in your mind, and if your mind is dwelling on it, you can't meditate. If you can't meditate, you don't get to wisdom. That's why it's Giới, Định, Tuệ, in that order — Giới first.&lt;/p&gt;

&lt;p&gt;This applies to idle time too. When I have free time, and my mind gets bored, the default reflex is to reach for the phone, the laptop, the digital world. So now, instead of reaching, I ask: what's the simplest thing I can do right now to simplify my current environment, so this bad habit has less room to arise? I keep asking that question and acting on it — again and again — until the environment is shaped enough that the habit is almost impossible to trigger.&lt;/p&gt;

&lt;p&gt;It's the same with environment. The point isn't to build a stronger will to resist bad habits once they arise. It's to design the environment so those habits have less chance to arise in the first place.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>motivation</category>
      <category>worklifebalance</category>
      <category>psychology</category>
    </item>
    <item>
      <title>I stopped trying to be consistent</title>
      <dc:creator>Tien Do</dc:creator>
      <pubDate>Wed, 19 Aug 2026 17:34:26 +0000</pubDate>
      <link>https://dev.to/foreverlovewisdom/i-stopped-trying-to-be-consistent-m6o</link>
      <guid>https://dev.to/foreverlovewisdom/i-stopped-trying-to-be-consistent-m6o</guid>
      <description>&lt;p&gt;This isn't advice. I'm not saying anyone should agree with this or do it my way — just sharing where I landed.&lt;/p&gt;

&lt;p&gt;For a long time, when I thought about productivity, I thought about mastery. If I wanted to learn a functional programming language, I should become a master of it. Same for any other subject. That mindset did work, at first — it pushed me to actually start. But then I'd stop, long before reaching expert level, and feel like I'd failed.&lt;/p&gt;

&lt;p&gt;So I read productivity and self-development books. They all said the same thing: consistency is what matters. Show up daily. I got a new wave of motivation from that and tried it. I did it for a while. Then I stopped. I figured something was wrong with me — I was lazy, overwhelmed, trying to do too many things at once.&lt;/p&gt;

&lt;p&gt;Now I think it wasn't that simple. I don't think I need to be consistent. It's fine to follow my need and energy on a given day. Today I felt like writing and sharing on dev.to again, after a year away, so I just did it.&lt;/p&gt;

&lt;p&gt;I'm not worrying about whether I'll keep it up tomorrow, next week, or next month. Tomorrow hasn't happened yet. And if I stop sharing again for another year, or never write again — that's fine too. I'm not going to force myself into some unnatural commitment about what I must do in the future. We're not fixed. We change, things change, priorities shift.&lt;/p&gt;

&lt;p&gt;Same thing with learning anything — writing, a new programming language, whatever. I've stopped obsessing over becoming an expert. I learn because I need to, or because something triggers me to at that moment. And this time, I don't overwhelm myself by taking on many things at once, or reading multiple books on the same subject before I've even grasped the fundamentals. Learning only actually happens when I apply it and reflect on it in the real world.&lt;/p&gt;

&lt;p&gt;I do use an AI agent to help with the writing — it asks me questions and helps pull the ideas into something coherent. But the thoughts are mine.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>learning</category>
      <category>discuss</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Why Elm, and How I'm Learning It in the Age of AI Agents</title>
      <dc:creator>Tien Do</dc:creator>
      <pubDate>Wed, 19 Aug 2026 17:01:32 +0000</pubDate>
      <link>https://dev.to/foreverlovewisdom/why-elm-and-how-im-learning-it-in-the-age-of-ai-agents-1996</link>
      <guid>https://dev.to/foreverlovewisdom/why-elm-and-how-im-learning-it-in-the-age-of-ai-agents-1996</guid>
      <description>&lt;p&gt;I watched a JetBrains interview with Zig's founder. He talked about keeping the project to a small number of trusted contributors — fewer than ten — specifically because it's now easy for an open-source project to get flooded with low-quality AI-generated pull requests that waste a small team's review time. My first reaction was that this could tip into one person dictating the whole vision. But as I've grown as an engineer, I don't think that's necessarily bad — if the founder's instinct is toward simplicity and not bloated features, it can work well. I see the opposite every day in my Rails job: people over-engineering, abusing gems and metaprogramming to make simple problems complicated.&lt;/p&gt;

&lt;p&gt;I started learning Zig with Claude Code. Somehow, that reawakened my old attempts at learning functional programming — Haskell, Elixir, Clojure, Scala, all of which didn't stick — and I decided to stop Zig and go back to FP instead.&lt;/p&gt;

&lt;p&gt;This time I picked Elm. I looked for the simplest FP language with skills that transfer to my day job as a Rails engineer, and to other languages I want to learn later — Rust, Go, Zig, Odin. I was intrigued by Elm's famously good compiler errors and want to bring that lesson back to Rails. Elm's model-update-view architecture — the one Redux and other JS frameworks borrowed from — is interesting too, but not the main reason. The real reason: Elm's GitHub repo basically stopped growing years ago, because its founder decided it was enough. That resonates with the simplicity mindset I've grown into — knowing when to stop, remembering why you started, even if it upsets people who want more. That kind of restraint feels rare, and more valuable now, in the age of AI agents.&lt;/p&gt;

&lt;p&gt;How I'm learning it: not syntax first. I've loved video games since I was 18 or 19 — that's part of what got me into software in the first place — so I'm building a Space Invaders clone in Elm with Claude Code, no external assets, all of it generated as SVG by code, with interactive HTML explanations along the way to teach transferable concepts.&lt;/p&gt;

&lt;p&gt;After a while I felt I needed more grounding, so I went to Exercism — three or four Elm exercises in so far. It's good for strengthening a TDD mindset, the same mentality I already use at my Rails job. I built my own AI skill for it: the agent has to ask me questions instead of writing the solution, and I write the code myself to pass the spec — otherwise I don't actually learn anything. I baked "stay focused on transferable functional programming concepts" into the skill itself, so the agent doesn't drift from that. I'm not trying to solve all 100+ exercises — just enough to grasp it, then back to the game.&lt;/p&gt;

&lt;p&gt;One idea for later: clone a well-structured open-source Space Invaders repo, in any language, and have the AI agent extract the useful Elm/FP lessons from it — not copy everything, just enough.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>functional</category>
      <category>ai</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Going Back to Functional Programming, This Time on Purpose</title>
      <dc:creator>Tien Do</dc:creator>
      <pubDate>Wed, 19 Aug 2026 16:15:46 +0000</pubDate>
      <link>https://dev.to/foreverlovewisdom/going-back-to-functional-programming-this-time-on-purpose-2d57</link>
      <guid>https://dev.to/foreverlovewisdom/going-back-to-functional-programming-this-time-on-purpose-2d57</guid>
      <description>&lt;p&gt;I'm going back to learning functional programming. I've tried before — Haskell, Elixir, Clojure, Scala, books like &lt;em&gt;Grokking Simplicity&lt;/em&gt; — and it didn't go well.&lt;/p&gt;

&lt;p&gt;Looking back, I mostly read and jumped between resources instead of writing code and sticking with one language. I picked Haskell partly because it's hard, and some part of me wanted people to think I was a good engineer for understanding it. I kept looking for "exciting" projects instead of practicing on ordinary ones, because ordinary bored me — that was ego and dopamine chasing, not a learning plan. I also told myself functional programming had little value for a Rails engineer, which wasn't even true — Rails uses blocks and lambdas functionally all the time — though that wasn't the main reason I quit.&lt;/p&gt;

&lt;p&gt;Why now: AI can generate about 80% of my code quickly, and quite well — maybe partly because Ruby/Rails is well represented in AI training data compared to less popular languages. It's easy to lose touch with a codebase and stop knowing what you're actually doing as an engineer when that much of the writing happens for you. I've also reached a point with OOP where I don't think I can improve much further on my own right now — I'm still learning it, still far from expert, but the pace has slowed.&lt;/p&gt;

&lt;p&gt;This time the goal isn't to become an expert in functional programming. It's to actually understand what problems it solves and what problems it creates.&lt;/p&gt;

&lt;p&gt;I'm not against AI agentic coding — I spend real time daily improving my own agentic workflow. This is separate from that.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>learning</category>
    </item>
    <item>
      <title>When I Use AI — And When I Don’t</title>
      <dc:creator>Tien Do</dc:creator>
      <pubDate>Mon, 12 May 2025 12:44:20 +0000</pubDate>
      <link>https://dev.to/foreverlovewisdom/why-i-stopped-using-ai-for-coding-and-what-it-taught-me-about-simplicity-o4l</link>
      <guid>https://dev.to/foreverlovewisdom/why-i-stopped-using-ai-for-coding-and-what-it-taught-me-about-simplicity-o4l</guid>
      <description>&lt;p&gt;&lt;strong&gt;AI helped me ship faster, but it didn’t always allow me to ship better. Over time, I learned to separate speed from clarity and to use AI with more intention, not more dependence.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I started using ChatGPT in late 2022, right after getting laid off. With no job, I had time — so I talked to it constantly. Some days, I spent 5–6 hours experimenting. Ideas bounced back and forth.&lt;/p&gt;

&lt;p&gt;At first, everything felt smooth. No red flags yet.&lt;/p&gt;

&lt;p&gt;After landing a new job at another startup, I integrated AI into my coding workflow. It felt like magic. Snippets, tests, and scaffolds appeared instantly. I called it my tireless junior dev.&lt;/p&gt;

&lt;p&gt;But a few weeks in, I noticed something off: I was shipping more but thinking less. Worse — I felt detached from the codebase.&lt;/p&gt;

&lt;p&gt;I used AI to refactor code, build new features, generate controller logic, mock APIs, and especially write RSpec tests. It saved me hours. I enjoy TDD, so I didn’t want to outsource that part — but I had to admit, the output was decent. Part of that came from my prompting skill — I’d spent months sharpening it during unemployment.&lt;/p&gt;

&lt;p&gt;On the surface, things looked efficient. PRs moved quickly. I felt productive. But the longer I used it, the more invisible costs started to show.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚨 Problem 1: Fixing AI output took time
&lt;/h3&gt;

&lt;p&gt;When I used AI to generate logic-heavy code, I often spent more time fixing than writing. That’s not AI’s fault — it's about knowing when to use it, and where to trust my clarity instead. Even with multiple options, most suggestions weren’t up to my quality bar.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 Problem 2: I outsourced my thinking
&lt;/h3&gt;

&lt;p&gt;This one hit harder: critical thinking got slower. I realized I'd gradually handed over my problem-solving process to an assistant. It gave me the illusion that I don't have to think. I get paid to think. To solve real problems. Not to polish suggestions from a prediction engine.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚡ Problem 3: I became less patient
&lt;/h3&gt;

&lt;p&gt;AI gave me instant answers and I started expecting instant progress. I’ve never been perfectly patient. But, before AI, I at least respected the time it took to solve hard problems. With AI, I got frustrated faster. The illusion of speed trained my brain to expect shortcuts. And when the dopamine stopped, so did my tolerance for difficulty.&lt;/p&gt;




&lt;h3&gt;
  
  
  📉 Real-World Consequences
&lt;/h3&gt;

&lt;p&gt;When we use AI without thinking clearly, small problems pile up fast: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code looks like suggestions, not real decisions &lt;/li&gt;
&lt;li&gt;Debugging gets messy — nobody fully understands what the code is doing&lt;/li&gt;
&lt;li&gt;New teammates have to guess what’s going on&lt;/li&gt;
&lt;li&gt;You start to feel disconnected from the work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI helps move fast, yes. But if you're not careful, it also helps you get lost faster.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠 What I Do Now
&lt;/h3&gt;

&lt;p&gt;After another layoff (at the time of writing), I took a step back, not to quit AI, but to rebuild how I think with it.&lt;/p&gt;

&lt;p&gt;I went back to basics: pen, editor, whiteboard. Tools that slow me down just enough to reconnect with the thinking process itself.&lt;/p&gt;

&lt;p&gt;I still use AI — just differently now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dummy data &lt;/li&gt;
&lt;li&gt;JSON scaffolds&lt;/li&gt;
&lt;li&gt;Boilerplate test helpers&lt;/li&gt;
&lt;li&gt;... &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for core architecture, debugging, or solving hard logic, I slow down and use my brain first. If I bring AI in, it’s as a sparring partner, not the driver.&lt;/p&gt;




&lt;p&gt;🧭 Final Thoughts&lt;/p&gt;

&lt;p&gt;AI isn’t bad. But full dependence is.&lt;/p&gt;

&lt;p&gt;Google helped. Stack Overflow helped. Social media helped. But overused? They made us distracted. AI just scales that effect.&lt;/p&gt;

&lt;p&gt;So now, I ask myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does this tool increase clarity? &lt;/li&gt;
&lt;li&gt;Or does it let me avoid thinking?&lt;/li&gt;
&lt;li&gt;Could I still solve this without help?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try going AI-free for a week — not as a protest, but as a test.&lt;br&gt;
Watch how your brain responds. Track how often you revise AI output vs. your own. Is speed giving you clarity? Or just comfort?&lt;/p&gt;

&lt;p&gt;Tools will evolve. AI will stay. But clarity — that’s on us.&lt;/p&gt;

&lt;p&gt;I’ve made these mistakes too. That’s why I’m setting better boundaries. Still improving. Still figuring it out — like everyone else.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>3 Real-World Refactoring Principles That Help Me Tame Complexity in Startup Codebases</title>
      <dc:creator>Tien Do</dc:creator>
      <pubDate>Sun, 20 Apr 2025 07:41:54 +0000</pubDate>
      <link>https://dev.to/foreverlovewisdom/3-real-world-refactoring-principles-that-help-me-tame-complexity-in-startup-codebases-457n</link>
      <guid>https://dev.to/foreverlovewisdom/3-real-world-refactoring-principles-that-help-me-tame-complexity-in-startup-codebases-457n</guid>
      <description>&lt;p&gt;In my &lt;a href="https://dev.to/foreverlovewisdom/first-post-and-complexity-in-software-engineer-149m"&gt;previous post&lt;/a&gt;, I talked about &lt;strong&gt;software complexity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One principle&lt;/strong&gt; I &lt;strong&gt;consistently&lt;/strong&gt; follow is:&lt;br&gt;&lt;br&gt;
👉 &lt;em&gt;“The code I touch should be easier to understand and maintain than before—unless I’m writing it from scratch.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I always start with the &lt;strong&gt;smallest unit in OOP&lt;/strong&gt;—which, coming from a Ruby background, is the &lt;strong&gt;function&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To me, a &lt;strong&gt;function is the most fundamental building block of a class&lt;/strong&gt;. Even if a class is 1,000+ lines long, the codebase is still workable if its functions are clear and well-structured. At the very least, it becomes easier to refactor in the future.&lt;/p&gt;

&lt;p&gt;In this post, I want to share &lt;strong&gt;three principles&lt;/strong&gt; I use to write clean, maintainable functions:&lt;/p&gt;


&lt;h3&gt;
  
  
  1️⃣ &lt;code&gt;Keep It Short (Lines of Code)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In Ruby, it’s idiomatic to keep functions short.&lt;/p&gt;

&lt;p&gt;When I was a tech lead, I often set a soft limit of 10–12 lines per function. But &lt;strong&gt;depending on the team’s experience level&lt;/strong&gt;, that might be too strict and slow the team down.&lt;/p&gt;

&lt;p&gt;A practical compromise I’ve found:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;20 lines is a reasonable maximum.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
It keeps functions &lt;strong&gt;simple, readable, and maintainable—without introducing unnecessary friction for the team&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  📌 Example: Before &amp;amp; After
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;: A long, hard-to-scan function mixing multiple behaviors&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"Order not found"&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;

  &lt;span class="n"&gt;payment_gateway&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PaymentGateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;payment_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;payment_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;amount_cents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;payment_result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success?&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: :paid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;paid_at: &lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="no"&gt;AnalyticsLogger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log_payment_success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="no"&gt;NotificationService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_payment_confirmation_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;referral_code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
      &lt;span class="n"&gt;reward_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ReferralRewardService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;referral_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;reward_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process_reward_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="no"&gt;SendThankYouGiftJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform_later&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;amount_cents&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: :payment_failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;ErrorTracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Payment failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user_id: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;order_id: &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;: Refactored with clarity, separation, and single-purpose focus&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"Order not found"&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;charge_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;handle_successful_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;handle_failed_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;charge_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PaymentGateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;payment_token&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;amount_cents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success?&lt;/span&gt;

  &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: :paid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;paid_at: &lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_successful_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;log_payment_success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;notify_user_of_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;reward_referral_if_applicable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;send_thank_you_gift_if_high_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_failed_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: :payment_failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;ErrorTracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Payment failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user_id: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;order_id: &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_payment_success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;AnalyticsLogger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log_payment_success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;user_id: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;order_id: &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notify_user_of_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;NotificationService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_payment_confirmation_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reward_referral_if_applicable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;referral_code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;

  &lt;span class="n"&gt;reward_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ReferralRewardService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;referral_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;reward_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process_reward_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_thank_you_gift_if_high_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;amount_cents&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;

  &lt;span class="no"&gt;SendThankYouGiftJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform_later&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;2️⃣ &lt;code&gt;One Reason to Change&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A function should have only &lt;strong&gt;one reason to change&lt;/strong&gt;. This aligns with the &lt;strong&gt;Single Responsibility Principle&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A quick test:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ask yourself, “What does this function do?”
If the answer includes “and” (e.g., “It charges the user and sends a confirmation email”), it’s doing too much.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the original example, the &lt;strong&gt;process_payment&lt;/strong&gt; function had several reasons to change:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Payment logic

Logging behavior

Notification flow

Referral rewards

Async background jobs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, &lt;strong&gt;each function focuses on just one behavior&lt;/strong&gt;, making changes easier and less risky.&lt;/p&gt;




&lt;p&gt;3️⃣ &lt;code&gt;Consistent Level of Abstraction&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This one’s subtle but powerful.&lt;/p&gt;

&lt;p&gt;If &lt;strong&gt;a function mixes different levels of abstraction&lt;/strong&gt;, it becomes &lt;strong&gt;mentally exhausting to understand&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the original version, the function:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Accessed the database (low-level)

Called an external payment API (infrastructure)

Applied business rules (mid-level)

Sent notifications (I/O)

Triggered background jobs (infra)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That’s a &lt;strong&gt;lot of context-switching&lt;/strong&gt; in one place.&lt;/p&gt;

&lt;p&gt;In the refactored version:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The main function (process_payment) stays at the orchestration level

Each helper function stays at a consistent “altitude”, making the whole flow easier to follow and evolve.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I’d love to hear your thoughts.&lt;br&gt;
What principles do you follow to keep your functions clean and maintainable?&lt;br&gt;
Let’s discuss 👇&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>softwareengineering</category>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>First post and complexity in software engineer</title>
      <dc:creator>Tien Do</dc:creator>
      <pubDate>Sun, 23 Feb 2025 23:44:45 +0000</pubDate>
      <link>https://dev.to/foreverlovewisdom/first-post-and-complexity-in-software-engineer-149m</link>
      <guid>https://dev.to/foreverlovewisdom/first-post-and-complexity-in-software-engineer-149m</guid>
      <description>&lt;h1&gt;
  
  
  A Bit About Me 👋
&lt;/h1&gt;

&lt;p&gt;Welcome to my technical/non-technical sharing on Dev.to! I’ve been making a living as a &lt;strong&gt;software engineer&lt;/strong&gt; (with stints as a &lt;strong&gt;product owner&lt;/strong&gt; and &lt;strong&gt;tech lead&lt;/strong&gt;) since &lt;strong&gt;2016&lt;/strong&gt;. I gained most of my experience in &lt;strong&gt;startups&lt;/strong&gt;—full of challenges, but every struggle was worth it.  &lt;/p&gt;

&lt;p&gt;In this space, I'll share my &lt;strong&gt;thoughts on software engineering and the tech industry&lt;/strong&gt;—covering both &lt;strong&gt;technical insights&lt;/strong&gt; and the &lt;strong&gt;broader business aspects&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;This is my &lt;strong&gt;first&lt;/strong&gt; technical blog—or technically, my &lt;strong&gt;second&lt;/strong&gt;. I wrote one before but deleted it because I didn’t think it was good enough. 😅 I &lt;strong&gt;do use&lt;/strong&gt; &lt;strong&gt;AI tools&lt;/strong&gt; to help refine my writing—&lt;strong&gt;rephrasing, proofreading, and improving clarity&lt;/strong&gt;—since &lt;strong&gt;English is not my native language&lt;/strong&gt;. But the &lt;strong&gt;core ideas&lt;/strong&gt; in every post are &lt;strong&gt;mine&lt;/strong&gt;, based on &lt;strong&gt;real-world experience&lt;/strong&gt; in the tech industry.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Why I’m Writing on Dev.to ✍️
&lt;/h2&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;For my future self&lt;/strong&gt;—so I can look back and see how far I’ve come.  &lt;/p&gt;

&lt;p&gt;2️⃣ &lt;strong&gt;For others on a similar path&lt;/strong&gt;—sharing what I’ve learned along the way.  &lt;/p&gt;

&lt;p&gt;3️⃣ &lt;strong&gt;For my future colleagues/partners&lt;/strong&gt;—so they can understand how I think about software engineering.  &lt;/p&gt;

&lt;p&gt;That said, these are &lt;strong&gt;not my final opinions&lt;/strong&gt;. &lt;strong&gt;Ideas evolve&lt;/strong&gt;—especially in this AI-driven era—so my thoughts will too.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take everything with a grain of salt.&lt;/strong&gt; 🧂 If you have &lt;strong&gt;different opinions&lt;/strong&gt;, feel free to &lt;strong&gt;challenge them&lt;/strong&gt;! I don’t know how long or how often I’ll be sharing here, but for now, I have the motivation, so… I’m just going with the flow.  &lt;/p&gt;

&lt;p&gt;Alright, enough intro—let’s dive in. 🚀  &lt;/p&gt;




&lt;h2&gt;
  
  
  Complexity Enlightenment 🤯
&lt;/h2&gt;

&lt;p&gt;Today, I reread &lt;strong&gt;A Philosophy of Software Design&lt;/strong&gt; by &lt;strong&gt;John Ousterhout&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;Right in &lt;strong&gt;Chapter 1: Introduction (It’s All About Complexity)&lt;/strong&gt;, this paragraph hit me hard:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This means that the greatest limitation in writing software is our ability to understand the systems we are creating. As a program grows and adds new features, it can become complex. This complexity arises from the hidden connections between its parts. As systems grow, they become more complex. This makes it difficult for programmers to remember everything when making changes. This slows down development and leads to bugs, which slow development even more and add to its cost. Complexity increases inevitably over the life of any program. The larger the program, and the more people that work on it, the more difficult it is to manage complexity."  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reading this paragraph summed up &lt;strong&gt;all the struggles my past teams and I faced&lt;/strong&gt;. It captured the &lt;strong&gt;essence of our frustrations&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;When reading technical books, some sections we &lt;strong&gt;skim&lt;/strong&gt;, and some we &lt;strong&gt;digest slowly&lt;/strong&gt;. I’m sure I read this paragraph before, but &lt;strong&gt;this time, it hit differently&lt;/strong&gt;. Maybe &lt;strong&gt;some realizations only come with experience&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;The funny thing is, I’ve also read &lt;strong&gt;Sandi Metz’s books&lt;/strong&gt; (since my background is &lt;strong&gt;Ruby on Rails&lt;/strong&gt;). She frequently talks about &lt;strong&gt;complexity&lt;/strong&gt;. But &lt;strong&gt;truly understanding&lt;/strong&gt; complexity? That takes &lt;strong&gt;time and firsthand experience&lt;/strong&gt;.  &lt;/p&gt;




&lt;h2&gt;
  
  
  How I Experienced Complexity in Startups 🏗️
&lt;/h2&gt;

&lt;p&gt;The most common pattern I’ve seen in previous startups goes like this:  &lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;At the start, we ship code fast.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;2️⃣ &lt;strong&gt;Over time, things start slowing down.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;3️⃣ &lt;strong&gt;Adding new features takes longer and longer.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;4️⃣ &lt;strong&gt;We scale fast, but our codebase wasn’t built for change&lt;/strong&gt; (we wrote it just to &lt;strong&gt;“make things work”&lt;/strong&gt;).  &lt;/p&gt;

&lt;p&gt;5️⃣ &lt;strong&gt;We end up fixing more bugs than building new features.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;6️⃣ &lt;strong&gt;Business teams start asking:&lt;/strong&gt; “Why did things slow down? It was fast in the beginning!”  &lt;/p&gt;

&lt;p&gt;7️⃣ &lt;strong&gt;Guess who gets blamed?&lt;/strong&gt; Software engineers. 🙃  &lt;/p&gt;

&lt;p&gt;Yes, developers &lt;strong&gt;play a role&lt;/strong&gt;, but the real culprit is &lt;strong&gt;complexity and dependencies&lt;/strong&gt;. I’ve seen this pattern repeat in &lt;strong&gt;most startups&lt;/strong&gt; I’ve worked with. The only exceptions? &lt;strong&gt;Startups that failed too early—before complexity had time to emerge.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Of course, there are &lt;strong&gt;patterns, best practices, and conventions&lt;/strong&gt; to help control complexity, and I’ll share my experiences with them in future posts.  &lt;/p&gt;

&lt;p&gt;But here’s the catch: &lt;strong&gt;Tools alone don’t solve complexity.&lt;/strong&gt; Used &lt;strong&gt;blindly&lt;/strong&gt;, they can make things &lt;strong&gt;worse&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;One extra class, method, or design decision might add hidden complexity that bites us later.&lt;/strong&gt;  &lt;/p&gt;




&lt;h2&gt;
  
  
  The One Question I Now Ask Before Committing Code 🤔
&lt;/h2&gt;

&lt;p&gt;Before I commit my code, push it, and call it a day, I ask myself &lt;strong&gt;one question&lt;/strong&gt;:  &lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Am I reducing complexity for the codebase/team, or am I adding more complexity?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;This has become &lt;strong&gt;my main guiding principle&lt;/strong&gt; before even thinking about a solution.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts &amp;amp; What’s Next 🎯
&lt;/h2&gt;

&lt;p&gt;Additionally, &lt;strong&gt;technical decisions should align with business goals&lt;/strong&gt;. At the end of the day, &lt;strong&gt;what’s the point of a technical solution if it doesn’t solve a business problem?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;startups&lt;/strong&gt;, every decision &lt;strong&gt;directly&lt;/strong&gt; affects &lt;strong&gt;how fast we move, adapt, and survive&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;For my next posts, I’ll dive into &lt;strong&gt;how I handle complexity in real projects&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;I’d love to hear your thoughts—&lt;strong&gt;drop a comment below!&lt;/strong&gt; 👇 🚀  &lt;/p&gt;

</description>
      <category>programming</category>
      <category>softwareengineering</category>
      <category>softwarecomplexity</category>
    </item>
  </channel>
</rss>
