<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Go on Lorbic</title><link>http://localhost:1313/tags/go/</link><description>Recent content in Go on Lorbic</description><generator>Hugo</generator><language>en</language><lastBuildDate>Thu, 13 Aug 2026 18:00:00 +0530</lastBuildDate><atom:link href="http://localhost:1313/tags/go/index.xml" rel="self" type="application/rss+xml"/><item><title>How Go Channels Actually Work</title><link>http://localhost:1313/go-channels-deep-dive/</link><pubDate>Thu, 13 Aug 2026 18:00:00 +0530</pubDate><guid>http://localhost:1313/go-channels-deep-dive/</guid><description>&lt;p>A single unbuffered channel send without an active receiver is enough to silently lock up a production worker pool, leaking memory until your service gets killed by the OS kernel.&lt;/p>
&lt;p>On the surface, Go channels look simple: they synchronize concurrent execution without manual mutex management. But under heavy load, a minor oversight in channel sizing or worker coordination blocks the scheduler, leaks memory, or crashes processes with runtime panics.&lt;/p>
&lt;p>&lt;picture class="optimized-image-container">&lt;source srcset="http://localhost:1313/go-channels-deep-dive/go-scheduler-meme_hu_524f15f4ab89fd6f.webp 480w, http://localhost:1313/go-channels-deep-dive/go-scheduler-meme_hu_50f95d885458376d.webp 646w" sizes="(max-width: 800px) 100vw, 800px" type="image/webp">&lt;img src="http://localhost:1313/go-channels-deep-dive/go-scheduler-meme_hu_50f95d885458376d.webp" width="646" height="797" alt="The Go scheduler coordinating 10,000 goroutines on a single-core CPU" loading="eager" decoding="async" fetchpriority="high" class="img-fluid" />
 &lt;/picture>&lt;/p></description></item><item><title>Part 6: Simulating a Living Facility: Room Derivation, Sunlight Spillover, and Positional SFX</title><link>http://localhost:1313/modular-missions-floodfill-audio-raylib/</link><pubDate>Mon, 10 Aug 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/modular-missions-floodfill-audio-raylib/</guid><description>&lt;p>Generating a raw matrix of integer tiles gives you a map layout, but it doesn&amp;rsquo;t give you a living environment. When I loaded my first level into &lt;em>Derelict Facility&lt;/em>, the engine had no concept of what a &amp;ldquo;Laboratory&amp;rdquo; or a &amp;ldquo;Reactor Room&amp;rdquo; was. It just saw a flat array of walls and floors.&lt;/p>
&lt;p>If a player flipped a power terminal inside a room, I had no clean way to know which room lights or doors to toggle without scanning the whole map grid on every frame. If an alarm fired down the hall, it played at full volume regardless of where the player was standing.&lt;/p></description></item><item><title>Designing a Distributed Job Scheduler in Go: Partitioning, Locking, and Backpressure</title><link>http://localhost:1313/designing-a-distributed-job-scheduler/</link><pubDate>Sun, 09 Aug 2026 14:00:00 +0530</pubDate><guid>http://localhost:1313/designing-a-distributed-job-scheduler/</guid><description>&lt;p>Linux &lt;code>crontab&lt;/code> is one of the most elegant pieces of software ever written for single-host automation. It is simple, clear, and has kept Unix systems running reliably since 1975.&lt;/p>
&lt;p>The problem starts when we take a single-host tool and deploy it across a multi-node cloud setup.&lt;/p>
&lt;p>In &lt;a href="http://localhost:1313/how-multi-tenant-saas-works/">Relay&lt;/a>, a multi-tenant AI API gateway system design, background jobs power core operations: every top of the hour, a job rolls up raw API usage tokens into tenant billing metrics; every 15 minutes, another job scans for expired API keys and purges them from cache; every 30 seconds, a health checker pings upstream LLM provider endpoints.&lt;/p></description></item><item><title>Part 5: From Terminal Cells to Sprite Maps: Font Fallbacks and Auto-Tiling</title><link>http://localhost:1313/autotiling-sprites-font-fallbacks-raylib/</link><pubDate>Sun, 09 Aug 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/autotiling-sprites-font-fallbacks-raylib/</guid><description>&lt;p>Building a terminal-based engine in pure ASCII looks cool for about five minutes. Then you try rendering a complex facility map with corners, T-junctions, and status icons, and raw character cells start feeling incredibly limiting.&lt;/p>
&lt;p>Two specific problems hit me immediately when I tried switching to Raylib for graphics. First, drawing wall tiles manually by hand in level files meant placing 16 different corner variations by hand. Second, when I tried rendering a 🚨 warning emoji alongside FiraCode monospace text, Raylib just rendered a missing glyph box (&lt;code>?&lt;/code> or &lt;code>□&lt;/code>).&lt;/p></description></item><item><title>Part 4: Refactoring to SoA ECS: Bitmasks and Flat Component Arrays</title><link>http://localhost:1313/structure-of-arrays-ecs-bitmasks-golang/</link><pubDate>Sat, 08 Aug 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/structure-of-arrays-ecs-bitmasks-golang/</guid><description>&lt;p>When I started building &lt;em>Derelict Facility&lt;/em>, my initial instinct for game actors was standard Object-Oriented design: create an &lt;code>Entity&lt;/code> struct, add pointers for position, sprite, and stats, and store them in a slice (&lt;code>[]*Entity&lt;/code>).&lt;/p>
&lt;p>It worked fine for five entities. But as soon as I added automated doors, save terminals, and active power grids across a 1000-tile map, keeping track of separate heap pointers became a headache. My Go profiler showed GC pauses spiking while the CPU spent more time chasing heap pointers across non-contiguous memory than actually updating game state.&lt;/p></description></item><item><title>Constructing Concurrent Inverted Indexes in Go</title><link>http://localhost:1313/constructing-concurrent-inverted-indexes-in-go/</link><pubDate>Tue, 16 Jun 2026 22:00:00 +0530</pubDate><guid>http://localhost:1313/constructing-concurrent-inverted-indexes-in-go/</guid><description>&lt;p>I spent a Saturday afternoon benchmarking a concurrent inverted index and discovered that a single &lt;code>sync.RWMutex&lt;/code> starts to break down at roughly 4 concurrent readers. The degradation is not linear. It is not graceful. It is a cliff.&lt;/p>
&lt;p>The inverted index is one of the oldest data structures in information retrieval. It maps terms to the documents that contain them, forming the backbone of every search engine from Elasticsearch to Lucene to Google&amp;rsquo;s earliest prototypes. The data structure itself is simple. Making it fast under concurrent load is not.&lt;/p></description></item><item><title>A Love Letter to the L1 Cache</title><link>http://localhost:1313/love-letter-to-the-l1-cache/</link><pubDate>Mon, 15 Jun 2026 19:00:00 +0530</pubDate><guid>http://localhost:1313/love-letter-to-the-l1-cache/</guid><description>&lt;p>I recently spent four hours staring at a benchmark that didn&amp;rsquo;t make sense.&lt;/p>
&lt;p>It started while working on &lt;a href="https://github.com/vikash-paf/derelict-facility" target="_blank" rel="noopener noreferrer">Derelict Facility&lt;/a>, my grid-based game engine in Go. I was trying to tighten the main update loop, specifically the part that iterates over every entity on the map each frame. I pulled out a small benchmark to isolate the cost, and something looked wrong.&lt;/p>
&lt;p>I had two Go structs. They held the exact same data: two booleans and a 64-bit integer. I was iterating over a slice of 10 million of these structs, doing a simple addition. They should have been identical in performance.&lt;/p></description></item><item><title>Why Your Goroutines Need a Speed Limit: Bounded Concurrency in Go</title><link>http://localhost:1313/bounded-concurrency-in-go/</link><pubDate>Fri, 10 Apr 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/bounded-concurrency-in-go/</guid><description>&lt;p>&lt;strong>TL;DR:&lt;/strong> Spawning &lt;code>go func()&lt;/code> without a limiter is a recipe for system collapse. This guide details how to use &lt;strong>Semaphores&lt;/strong> and &lt;strong>Worker Pools&lt;/strong> to prioritize predictable stability over absolute speed, protecting downstream dependencies from the thundering herd.&lt;/p>
&lt;hr>
&lt;p>It&amp;rsquo;s a rite of passage for every Go developer. You receive a list of 10,000 URLs to fetch or 50,000 rows to process. You wrap the workload in an unbounded &lt;code>go func()&lt;/code> loop, achieving maximum throughput in milliseconds.&lt;/p></description></item><item><title>Part 2: Decoupling the Renderer: Terminal to Raylib in One Interface</title><link>http://localhost:1313/decoupling-game-engine-renderer-raylib/</link><pubDate>Mon, 06 Apr 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/decoupling-game-engine-renderer-raylib/</guid><description>&lt;p>The biggest architectural mistake you can make when building a game engine is letting the game know how it is being drawn.&lt;/p>
&lt;p>When I started building the &lt;em>Derelict Facility&lt;/em> engine, the output target was a raw ANSI terminal. The engine calculated A* paths, resolved line-of-sight, and then spewed escape codes (&lt;code>\033[31m&lt;/code>) to &lt;code>os.Stdout&lt;/code>.&lt;/p>
&lt;p>Eventually, I hit the physical limits of terminal emulators: inconsistent character widths (especially for emojis), slow double-buffering, and a hard cap on frame rates. I needed to move to a real, hardware-accelerated graphics library like Raylib.&lt;/p></description></item><item><title>Part 1: Data-Oriented Design in Go: Why [][]Tile Destroyed My Game Engine</title><link>http://localhost:1313/data-oriented-design-go-contiguous-memory/</link><pubDate>Sun, 05 Apr 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/data-oriented-design-go-contiguous-memory/</guid><description>&lt;p>Most game development stories start the same way: install Unity, drag some sprites onto a canvas, and press Play.&lt;/p>
&lt;p>I wanted to understand the metal. I set out to build &lt;em>&lt;a href="https://github.com/vikash-paf/derelict-facility" target="_blank" rel="noopener noreferrer">Derelict Facility&lt;/a>&lt;/em>, a systems-level game engine from scratch in pure Go. No SDL, no OpenGL wrappers, no Ebiten. The goal wasn&amp;rsquo;t just to ship a game; the goal was to learn the memory layouts and I/O pipelines that modern engines hide behind friendly APIs.&lt;/p></description></item><item><title>Understanding CPU Caches in Go</title><link>http://localhost:1313/cpu-caches-in-go/</link><pubDate>Tue, 31 Mar 2026 22:15:00 +0530</pubDate><guid>http://localhost:1313/cpu-caches-in-go/</guid><description>&lt;p>When you&amp;rsquo;re building Go services that handle millions of operations per second, the hardware beneath your abstractions starts to matter. Specifically, the CPU cache hierarchy, and whether your data fits in it.&lt;/p>
&lt;hr>
&lt;h4 id="the-hardware-context-its-not-just-ram">The Hardware Context: It&amp;rsquo;s Not Just &amp;ldquo;RAM&amp;rdquo;&lt;a class="anchorjs-link" href="#the-hardware-context-its-not-just-ram" aria-label="Link to section: The Hardware Context: It&amp;rsquo;s Not Just &amp;ldquo;RAM&amp;rdquo;">&lt;/a>&lt;/h4>&lt;p>Your server has 32GB or 64GB of RAM, but the CPU avoids touching it whenever possible. Instead, it works through a chain of caches:&lt;/p></description></item><item><title>WSL2 Is Slow? Fix /mnt/c/ File System Performance &amp; Go Latency</title><link>http://localhost:1313/wsl2-performance-tax-go-windows/</link><pubDate>Sun, 29 Mar 2026 22:30:00 +0530</pubDate><guid>http://localhost:1313/wsl2-performance-tax-go-windows/</guid><description>&lt;p>WSL2 (Windows Subsystem for Linux) has been a godsend for developers who love Linux tools but need/have a Windows environment. But for Go developers, WSL2 isn&amp;rsquo;t just a &amp;ldquo;transparent layer&amp;rdquo;. If configured incorrectly, it becomes the bottleneck that can slow down builds by 3x and introduce mysterious latency in networked services.&lt;/p>
&lt;p>This isn&amp;rsquo;t a failure of WSL2; it&amp;rsquo;s a failure of understanding the &lt;strong>9p boundary&lt;/strong>.&lt;/p>
&lt;div class="details-block reveal-item">
 &lt;details>
 &lt;summary>
 &lt;div class="summary-inner">
 &lt;span class="details-label">Glossary //&lt;/span>
 &lt;span class="details-title">What is the 9P Boundary?&lt;/span>
 &lt;svg class="svg-icon icon-plus" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">&lt;path d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H192V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H256V80z"/>&lt;/svg>
 &lt;svg class="svg-icon icon-minus" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">&lt;path d="M432 256c0 17.7-14.3 32-32 32H48c-17.7 0-32-14.3-32-32s14.3-32 32-32H400c17.7 0 32 14.3 32 32z"/>&lt;/svg>
 &lt;/div>
 &lt;/summary>
 &lt;div class="details-content">
 &lt;p>WSL2 is a Virtual Machine. To let that VM see your Windows files, Microsoft uses the &lt;strong>9P protocol&lt;/strong> (Plan 9).&lt;/p></description></item><item><title>What is a Mutex?</title><link>http://localhost:1313/til/2026-03-30-what-is-a-mutex/</link><pubDate>Sun, 29 Mar 2026 11:18:00 +0000</pubDate><guid>http://localhost:1313/til/2026-03-30-what-is-a-mutex/</guid><description>&lt;p>Read more: &lt;a href="https://nrecursions.blogspot.com/2014/08/mutex-tutorial-and-example.html" target="_blank" rel="noopener noreferrer">https://nrecursions.blogspot.com/2014/08/mutex-tutorial-and-example.html&lt;/a>&lt;/p></description></item><item><title>Go Struct Field Alignment: How Memory Padding Wastes Your RAM</title><link>http://localhost:1313/go-struct-field-alignment/</link><pubDate>Sat, 24 Jan 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/go-struct-field-alignment/</guid><description>&lt;p>You write a struct to represent a database entity. Maybe 10 fields, maybe 20. What could possibly go wrong?&lt;/p>
&lt;p>Nothing, according to your tests. But somewhere in production, your heap is 30% larger than it should be, your Garbage Collector is working overtime, and your L1 cache is not used properly. The reason? &lt;strong>Invisible padding bytes&lt;/strong> silently inflating every instance of your struct.&lt;/p>
&lt;p>This is the story of struct field alignment: a memory optimization that costs nothing to implement but can significantly improve performance.&lt;/p></description></item><item><title>Memory Mechanics In Go - Stack vs Heap</title><link>http://localhost:1313/memory-mechanics-stack-vs-heap-in-go/</link><pubDate>Mon, 12 Jan 2026 00:10:00 +0530</pubDate><guid>http://localhost:1313/memory-mechanics-stack-vs-heap-in-go/</guid><description>&lt;p>We often talk about &amp;ldquo;fast&amp;rdquo; code in terms of Big O notation or algorithmic complexity. But in systems programming languages like Go, &amp;ldquo;fast&amp;rdquo; is often a function of &lt;em>where&lt;/em> your data lives in memory.&lt;/p>
&lt;p>When optimizing for high throughput, efficient loops and database indexes are only part of the story. Eventually, you have to talk about the Stack and the Heap.&lt;/p>
&lt;p>Understanding the difference isn&amp;rsquo;t just trivia. It is the difference between a service that hums along at 100k OPS with flat latency, and one that chokes on Garbage Collection (GC) pauses every few seconds.&lt;/p></description></item><item><title>Go Garbage Collector Mechanics: Pacer, GOGC, and Allocation Latency</title><link>http://localhost:1313/dont-take-out-the-garbage-go-gc-deep-dive/</link><pubDate>Wed, 07 Jan 2026 00:21:12 +0530</pubDate><guid>http://localhost:1313/dont-take-out-the-garbage-go-gc-deep-dive/</guid><description>&lt;p>In the world of high-throughput backend services, we often obsess over the usual suspects of performance: database indexing, network latency, and algorithmic complexity. But recently, while debugging our core gateway service (&lt;code>backend-gw&lt;/code>), I encountered a bottleneck that defied standard logic.&lt;/p>
&lt;p>The service was &lt;strong>CPU-bound&lt;/strong>, yet active heap usage was surprisingly low (~200MB). P99 latency was spiking at random intervals, but database queries were returning in milliseconds.&lt;/p>
&lt;p>The culprit was not the business logic. It was &lt;strong>memory management&lt;/strong>. I was effectively running a Denial-of-Service attack on my own runtime.&lt;/p></description></item><item><title>Bitmasking In Go</title><link>http://localhost:1313/bitmasking/</link><pubDate>Thu, 17 Apr 2025 02:20:00 +0000</pubDate><guid>http://localhost:1313/bitmasking/</guid><description>&lt;h1 id="bitmasking-in-go">Bitmasking in Go&lt;a class="anchorjs-link" href="#bitmasking-in-go" aria-label="Link to section: Bitmasking in Go">&lt;/a>&lt;/h1>&lt;p>Bitmasking is one of those computer science tricks that feels like wizardry, until you realize it&amp;rsquo;s just some clever shifting and binary math. This blog explores the idea, shows how we use it in Go, and why it&amp;rsquo;s surprisingly useful when working with databases like Couchbase.&lt;/p>
&lt;hr>
&lt;h2 id="whats-bitmasking">What&amp;rsquo;s Bitmasking?&lt;a class="anchorjs-link" href="#whats-bitmasking" aria-label="Link to section: What&amp;rsquo;s Bitmasking?">&lt;/a>&lt;/h2>&lt;p>A &lt;strong>bitmask&lt;/strong> is just an integer where each &lt;strong>bit&lt;/strong> (0 or 1) represents a flag or state. Instead of storing multiple booleans in a slice or map, you cram them into a single &lt;code>int&lt;/code>. Fast to compute, fast to store, and great for indexing.&lt;/p></description></item><item><title>Understanding T and *T method receivers in Go</title><link>http://localhost:1313/method-receivers-in-go/</link><pubDate>Sun, 23 Feb 2025 04:33:00 +0000</pubDate><guid>http://localhost:1313/method-receivers-in-go/</guid><description>&lt;p>In Go, method receivers determine whether a method acts on a copy of a value or a reference to it. This choice isn&amp;rsquo;t just about performance; it affects correctness and behavior, especially when dealing with synchronization primitives (mutex, wait group, etc), slices, and embedded types.&lt;/p>
&lt;p>In this post I explore when to use T (a value receiver) vs. *T (a pointer receiver) and why, in most cases, pointer receivers should be the default and preferred.&lt;/p></description></item><item><title>Go Clean Code Guidelines</title><link>http://localhost:1313/go-clean-code-guidelines/</link><pubDate>Sun, 22 Sep 2024 15:22:00 +0000</pubDate><guid>http://localhost:1313/go-clean-code-guidelines/</guid><description>&lt;h3 id="go-clean-code-guidelines-for-code-quality-and-maintainability">Go Clean Code Guidelines for Code Quality and Maintainability.&lt;a class="anchorjs-link" href="#go-clean-code-guidelines-for-code-quality-and-maintainability" aria-label="Link to section: Go Clean Code Guidelines for Code Quality and Maintainability.">&lt;/a>&lt;/h3>&lt;p>When it comes to writing clean, maintainable code, there are a few fundamental rules that can help improve the overall structure and quality of your codebase. As engineers, our goal should be to keep things simple, clear, and scalable. With this in mind, here are some guidelines which prioritize code readability, functional clarity, and the overall maintainability of a project.
These guidelines are based on principles from clean code, SOLID, and functional programming while emphasizing simplicity over unnecessary complexity.&lt;/p></description></item><item><title>SOLID and Functional Programming Principles in Go</title><link>http://localhost:1313/solid-and-functional-programming-principles-in-go/</link><pubDate>Sun, 22 Sep 2024 00:03:00 +0000</pubDate><guid>http://localhost:1313/solid-and-functional-programming-principles-in-go/</guid><description>&lt;p>Let&amp;rsquo;s go through the &lt;strong>SOLID principles&lt;/strong> and &lt;strong>functional programming principles&lt;/strong> that can apply to your Go codebase. I&amp;rsquo;ll provide simple Go examples along with brief explanations to show how each principle can improve code quality.&lt;/p>
&lt;hr>
&lt;h3 id="solid-principles">&lt;strong>SOLID Principles&lt;/strong>&lt;a class="anchorjs-link" href="#solid-principles" aria-label="Link to section: SOLID Principles">&lt;/a>&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>S&lt;/strong>ingle Responsibility Principle (SRP)&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Description:&lt;/strong> A class or function should have only one reason to change, meaning it should only have one job or responsibility.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Example:&lt;/strong>&lt;/p>
&lt;div class="code-block">
 &lt;div class="code-header">
 &lt;div class="header-left">
 &lt;span class="code-lang">go&lt;/span>
 &lt;/div>
 &lt;div class="header-right">
 &lt;button class="wrap-code-button" title="Toggle line wrap" aria-label="Toggle line wrap">
 &lt;svg class="svg-icon " aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">&lt;path d="M448 256c0-53-43-96-96-96H96c-17.7 0-32 14.3-32 32s14.3 32 32 32h256c17.7 0 32 14.3 32 32s-14.3 32-32 32H165.5l37.3-37.3c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-96 96c-12.5 12.5-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L165.5 352H352c53 0 96-43 96-96zM32 64C14.3 64 0 78.3 0 96s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zM32 384c-17.7 0-32 14.3-32 32s14.3 32 32 32H256c17.7 0 32-14.3 32-32s-14.3-32-32-32H32z"/>&lt;/svg>

 &lt;/button>
 &lt;button class="download-code-button" data-lang="go" title="Download Code" aria-label="Download Code">
 &lt;svg class="svg-icon " aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">&lt;path d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V274.7l-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7V32zM64 352c-35.3 0-64 28.7-64 64v32c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V416c0-35.3-28.7-64-64-64H346.5l-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352H64zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"/>&lt;/svg>

 &lt;/button>
 &lt;button class="copy-code-button" title="Copy Code" aria-label="Copy Code">
 &lt;svg class="svg-icon " aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">&lt;!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->&lt;path d="M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z"/>&lt;/svg>
 &lt;/button>
 &lt;/div>
 &lt;/div>
 &lt;div class="code-body">&lt;div class="highlight">&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 1&lt;/span>&lt;span>&lt;span style="color:#8b949e;font-style:italic">// Good: Separate responsibilities into two functions&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 2&lt;/span>&lt;span>&lt;span style="color:#ff7b72">type&lt;/span> EmailSender &lt;span style="color:#ff7b72">struct&lt;/span>{}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 3&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 4&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 5&lt;/span>&lt;span>&lt;span style="color:#ff7b72">func&lt;/span> (e &lt;span style="color:#ff7b72;font-weight:bold">*&lt;/span>EmailSender) &lt;span style="color:#d2a8ff;font-weight:bold">SendEmail&lt;/span>(to, subject, body &lt;span style="color:#ff7b72">string&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 6&lt;/span>&lt;span> &lt;span style="color:#8b949e;font-style:italic">// logic for sending email&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 7&lt;/span>&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 8&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681"> 9&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">10&lt;/span>&lt;span>&lt;span style="color:#ff7b72">func&lt;/span> &lt;span style="color:#d2a8ff;font-weight:bold">formatEmailBody&lt;/span>(template &lt;span style="color:#ff7b72">string&lt;/span>, data &lt;span style="color:#ff7b72">map&lt;/span>[&lt;span style="color:#ff7b72">string&lt;/span>]&lt;span style="color:#ff7b72">string&lt;/span>) &lt;span style="color:#ff7b72">string&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">11&lt;/span>&lt;span> &lt;span style="color:#8b949e;font-style:italic">// logic for formatting the email body&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">12&lt;/span>&lt;span> &lt;span style="color:#ff7b72">return&lt;/span> &lt;span style="color:#a5d6ff">&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">13&lt;/span>&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">14&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">15&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">16&lt;/span>&lt;span>&lt;span style="color:#8b949e;font-style:italic">// Avoid: Single function doing multiple jobs&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">17&lt;/span>&lt;span>&lt;span style="color:#ff7b72">func&lt;/span> &lt;span style="color:#d2a8ff;font-weight:bold">sendFormattedEmail&lt;/span>(to, subject, template &lt;span style="color:#ff7b72">string&lt;/span>, data &lt;span style="color:#ff7b72">map&lt;/span>[&lt;span style="color:#ff7b72">string&lt;/span>]&lt;span style="color:#ff7b72">string&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">18&lt;/span>&lt;span> body &lt;span style="color:#ff7b72;font-weight:bold">:=&lt;/span> &lt;span style="color:#d2a8ff;font-weight:bold">formatEmailBody&lt;/span>(template, data)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">19&lt;/span>&lt;span> &lt;span style="color:#8b949e;font-style:italic">// email sending logic mixed with formatting&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#6e7681">20&lt;/span>&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>
&lt;/div>&lt;/li>
&lt;/ol>
&lt;hr>
&lt;ol start="2">
&lt;li>
&lt;p>&lt;strong>O&lt;/strong>pen/Closed Principle (OCP)&lt;/p></description></item></channel></rss>