Article

Design Patterns, Without Pretending They Were Obvious

I read the famous book, took a university course, and was still confused. Then I noticed I had already used several patterns at work without knowing their formal names.

.NETDesign patternsSoftware designClean code
Published
24 May 2026
Reading time
5 minutes
Author
Aaryan Jha
01

The confusing part

I started with Design Patterns: Elements of Reusable Object-Oriented Software. It is an important book, but reading a catalogue of abstract collaborations did not make the patterns feel natural. I completed the University of Alberta design-patterns course afterwards and understood more of the vocabulary, but the ideas only settled once I compared them with code I had already shipped.

That changed the question from “Which pattern should I use?” to “What keeps changing here, and what relationship would make that change less expensive?” The second question is much harder to turn into interview trivia, which is probably why it is more useful.

02

A pattern is a reusable decision

A design pattern is not a finished block of code. It is a named shape for a problem that appears repeatedly. The name lets developers discuss the trade without drawing the entire object graph every time.

Think of a LEGO instruction manual

The instructions do not build your exact castle. They show a reliable way to connect pieces so the structure holds together. You still decide which pieces belong in your version and whether following the manual is worth it.

03

Three families, three questions

Creational

Who should create this object, and how much should the caller know?

Structural

How should these objects fit together without making every dependency permanent?

Behavioural

How should responsibility and communication move through the system?

The categories are useful for navigation, not as a checklist. A system does not improve because it contains one pattern from every column.

04

What they looked like in real code

Dependency injection had already separated creation from use in every ASP.NET Core service I wrote. Strategy appeared whenever multiple export formats shared one business operation but differed in how they produced bytes. Decorator appeared in pipeline behaviours that wrapped a request with validation or logging. Observer appeared in notifications pushed to clients after an asynchronous document job changed state.

I had learned each of those as a practical framework technique. The pattern name did not make the code work. It gave me a compact way to recognise the same pressure in another system.

05

When patterns make code worse

A pattern carries extra types, indirection and assumptions. Adding a factory around an object that has one constructor and one implementation does not create flexibility; it creates a second place to look. Adding a repository that only repeats Entity Framework methods can hide useful query capabilities without establishing a meaningful boundary.

The warning sign is explaining the pattern before explaining the problem.

Start with the pressure in the code. If implementations genuinely vary, Strategy may help. If creation is complex or environment-dependent, a factory may help. If events need several independent reactions, Observer may help. If none of those pressures exists, ordinary code is allowed.

06

How I learn them now

  1. 01Find a real piece of code that is becoming awkward
  2. 02Name the reason it is awkward: creation, structure, communication or change
  3. 03Study one pattern that addresses that pressure
  4. 04Implement the smallest version and compare it with the original
  5. 05Keep it only if the next change becomes easier to make and explain

Patterns became useful when I stopped treating them as designs to insert and started treating them as names for decisions I could defend.