<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Priyank Chheda</title><link>https://priyankchheda.github.io/</link><description>Recent content on Priyank Chheda</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 18 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://priyankchheda.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>Chain of Responsibility Design Pattern in Go</title><link>https://priyankchheda.github.io/posts/chain-of-responsibility/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://priyankchheda.github.io/posts/chain-of-responsibility/</guid><description>&lt;p&gt;Think about an HTTP request hitting your API server. Before the actual business logic runs, several things need to happen: authentication verifies the token, authorization checks permissions, rate limiting ensures the client hasn&amp;rsquo;t exceeded their quota, request validation confirms the payload is well-formed, and logging records the request for observability. Each check can either pass the request along or reject it outright.&lt;/p&gt;
&lt;p&gt;The naive approach is a nested &lt;code&gt;if/else&lt;/code&gt; tree inside the handler. Authentication passes? Check authorization. Authorization passes? Check rate limit. Rate limit passes? Validate the payload. Each new concern adds another nesting level, and the handler becomes a 200-line function that does six different things.&lt;/p&gt;</description></item><item><title>Simple Factory Design Pattern in Go</title><link>https://priyankchheda.github.io/posts/simple-factory/</link><pubDate>Mon, 30 Jun 2025 00:00:00 +0000</pubDate><guid>https://priyankchheda.github.io/posts/simple-factory/</guid><description>&lt;p&gt;Think about a notification service. It needs to send messages through different channels &amp;ndash; email, SMS, push notifications, Slack. The channel is determined at runtime: a user&amp;rsquo;s preference, a config value, a feature flag. The sending logic differs per channel, but the caller just wants to say &amp;ldquo;send this message through the right channel&amp;rdquo; without knowing how each channel works internally.&lt;/p&gt;
&lt;p&gt;The naive approach scatters &lt;code&gt;if/else&lt;/code&gt; chains across every call site. Each function that needs to send a notification decides which struct to instantiate, how to configure it, and which method to call. Add a new channel &amp;ndash; webhook, for instance &amp;ndash; and you&amp;rsquo;re modifying five different files. Remove one and you&amp;rsquo;re grepping the codebase for direct references.&lt;/p&gt;</description></item><item><title>Builder Design Pattern in Go</title><link>https://priyankchheda.github.io/posts/builder/</link><pubDate>Wed, 18 Jun 2025 00:00:00 +0000</pubDate><guid>https://priyankchheda.github.io/posts/builder/</guid><description>&lt;p&gt;Think about constructing an HTTP client. It needs a base URL, a timeout, retry configuration, authentication headers, a transport with TLS settings, maybe a rate limiter, maybe a custom logger. Some of these are required. Most are optional. Many interact &amp;ndash; retries without a timeout is dangerous, TLS settings without HTTPS in the base URL is a misconfiguration.&lt;/p&gt;
&lt;p&gt;The straightforward approach is a constructor with twelve parameters. Nobody remembers parameter order. Half the call sites pass zero values for options they don&amp;rsquo;t care about. Changing the constructor signature breaks every caller. Adding validation means the constructor becomes a 50-line function that does too many things.&lt;/p&gt;</description></item></channel></rss>