Skip to main content
raceychan
View all authors

Encapsulation Beyond Syntax: Do Access Modifiers Still Matter?

· 12 min read
raceychan

gears

Access modifiers are ubiquitous across programming languages, yet they've become increasingly controversial in modern development. Through my experience with software development and technical discussions, I've observed a troubling pattern: many developers either treat access modifiers as meaningless ceremony or dismiss them entirely as outdated relics.

This dismissive attitude stems from a fundamental misunderstanding of their purpose. Access modifiers aren't just syntactic decorations: they're essential tools for implementing encapsulation, one of object-oriented programming's core principles. When used properly, they significantly enhance code maintainability and enable effective team collaboration. Conversely, their absence or misuse leads to fragile, tightly coupled systems that become maintenance nightmares.

Consider the typical enterprise codebase that has grown unwieldy over time. While poor encapsulation isn't the only culprit, it's often a primary factor in creating systems where simple changes ripple unpredictably throughout the application. This problem is particularly evident in Python projects, where the language's flexibility can mask structural issues until they become critical.

Rather than contributing to the abundance of tutorials on how to use access modifiers, this article explores the deeper question: why should we use them? We'll examine their role in creating maintainable software from multiple perspectives, from individual classes to entire system architectures.

Design Patterns You Should Unlearn in Python-Part2

· 11 min read
raceychan

image-1.jpg

Ever since the Gang of Four released their legendary Design Patterns book in the 90s, "design patterns" have been a cornerstone of how developers talk about software architecture. Over time, though, the term itself has grown fuzzier. When someone mentions a pattern today, they might be referring to:

  • The intent behind the pattern: the problem it's trying to solve.
  • The implementation: the exact class structure or code to achieve it.

When we talk about “design patterns you should unlearn in Python,” we’re talking about the second kind: the implementation. These patterns still solve real problems. But in Python, the way you solve them often looks nothing like the solutions shown in C++ or Java.

That’s the key idea behind this series. The moral is simple:

Bears learn to climb trees to reach food. But Eagles do not climb, they fly.

In Part 1, we took apart the Builder and Singleton patterns, showing how Python’s features (like default arguments or modules) make many “classic” implementations unnecessary or even counterproductive.

Now, let’s move on to two more patterns: Flyweight and Prototype. Both solve real problems. But as you'll see, Python gives us simpler, more natural ways to solve them.

Design Patterns You Should Unlearn in Python-Part1

· 9 min read
raceychan

image-1.jpg

Search for “design patterns in Python” and you’ll be rewarded with a parade of tutorials showing off how to faithfully re-implement Gang of Four patterns — complete with class diagrams, factory hierarchies, and enough boilerplate to heat a small village. They’ll make you feel like you’re writing “serious” code. Smart. Professional. Enterprise-ready.

But here’s the problem: most of these patterns solve problems Python doesn’t have. They were designed for languages like Java and C++, where you have to jump through hoops just to get basic things done — no first-class functions, no dynamic typing, no modules as namespaces. Of course you’d need a Factory or a Singleton if your language gives you nothing else to work with.

Blindly copying those patterns into Python doesn’t make you clever. It makes your code harder to read, harder to test, and harder to explain to the next poor soul who has to maintain it — possibly you, three months from now.

In this post, we’ll go over a few classic GOF patterns that you should unlearn as a Python developer. For each one, we’ll look at:

  1. How it’s usually (and badly) implemented in Python,
  2. Why it actually made sense back when people were writing Java in 2001,
  3. And what the Pythonic alternative looks like — because yes, there’s almost always a simpler way.

Let’s start with the biggest offender: Creational Patterns — aka, a whole category of solutions to problems Python already solved.

Decorators and Functional programming

· 10 min read
raceychan

lego

I often see people ask how to "do functional programming in Python"—as if it requires special tools or libraries.

But the truth is, many Python developers are already using functional programming techniques without realizing it. One of the clearest examples is the use of decorators.

Decorators are not only a staple of modern Python codebases but also a practical bridge between traditional imperative programming and the functional programming paradigm.

Set Up User Authentication in Minutes — With or Without a Standalone Database Using lihil-auth

· 5 min read
raceychan

security

As someone who has worked on multiple web projects, I’ve found user authentication to be a recurring pain point. Whether I was integrating a third-party auth provider like Supabase, or worse — rolling my own auth system — I often found myself rewriting the same boilerplate:

  • Configuring JWTs

  • Decoding tokens from headers

  • Serializing them back

  • Hashing passwords

  • Validating login credentials

And that’s not even touching error handling, route wiring, or OpenAPI documentation.

So I built lihil-auth, a plugin system that makes user authentication a breeze. It supports both third-party platforms like Supabase and self-hosted solutions using JWT — with minimal effort.

Enter your email to subscribe.
Subscribe to receive original, unique insights on OOP, web development and AI.

No spam, unsubscribe anytime.

Enter your email to subscribe.
Subscribe to receive original, unique insights on OOP, web development and AI.

No spam, unsubscribe anytime.