The Hidden Design Principle Behind Clean Code and Clean Queries

Kai Nguyen

Hatched by Kai Nguyen

Apr 22, 2026

10 min read

86%

0

What if the real job of a system is to make its rules impossible to forget?

Most software problems are not caused by a lack of power. They are caused by a lack of clarity. A class can do almost anything, a query can retrieve almost anything, and yet the hardest part of building reliable systems is not adding capability. It is making the right action the easiest one to perform.

That is why two ideas that seem unrelated at first, method types in Python and basic SQL retrieval, actually point toward the same design principle: good systems should communicate their intent in the shape of their interface. A method is not just code. A query is not just data access. Both are contracts. Both tell the next person, including your future self, what kind of operation belongs here and what kind does not.

The deeper question is not "How do I make this work?" It is "How do I make the right thing obvious and the wrong thing awkward?"


Intent is a feature, not decoration

In Python, the difference between an instance method, a class method, and a static method is not merely syntactic. Each one says something about where the responsibility lives.

An instance method says: this behavior belongs to a specific object, and it may depend on that object's state. A class method says: this behavior belongs to the class as a whole, often because it constructs, configures, or reasons about instances. A static method says: this behavior is related enough to live here, but it does not need access to either object state or class state.

That is not just a technical distinction. It is a design language. A well chosen method type helps prevent a subtle category of bugs: the ones caused by calling the right function in the wrong way. When the interface is expressive, it narrows the number of plausible mistakes.

Consider the difference between these two situations:

  • A utility function floats free in a module, where it can be used anywhere, including places where it may not belong.
  • The same function is placed as a static method on a class, signaling that it serves that class's domain, even if it does not need access to internal state.

The first choice optimizes for availability. The second optimizes for meaning. In mature codebases, meaning often matters more than convenience because meaning scales better than memory. People forget details. They forget edge cases. They forget conventions. They are far less likely to forget a structure that visibly encodes its purpose.

Design is successful when it moves knowledge out of human memory and into the interface itself.

That is the invisible advantage of method types. They are not just a programming feature. They are a memory aid for teams.


The constructor problem and the database problem are the same problem

Python classes have one __init__ method, which is excellent if every object should be born the same way and awkward if the same class needs multiple legitimate starting points. Class methods solve that by acting as alternative constructors. Instead of forcing a single path into object creation, they let the class express multiple entry points with names that describe what kind of object is being built.

Imagine a Pizza class. A from_margarita class method, a from_calzone class method, and a from_custom_order class method make the API self documenting. You do not need to inspect implementation details to know that different categories of pizzas exist, or that there are sanctioned ways to create them.

This is where the connection to SQL becomes surprisingly deep. A database query is also a constructor of meaning. When you write a WHERE clause, you are not merely filtering rows. You are specifying the criterion that defines relevance. When you add DISTINCT, you are not just removing duplicates. You are declaring that repeated values should be collapsed into a set of unique categories. When you use ORDER BY, you are imposing an interpretation on otherwise unordered data.

In other words, the query is not simply retrieving facts. It is shaping them into a usable form.

This matters because raw data is often ambiguous. A table does not promise an inherent order. Without ORDER BY, the database is free to return rows in any sequence. That is a small technical point with a large philosophical implication: if you do not state your intent, you do not own the outcome.

The same is true in class design. If you do not state whether behavior is instance-bound, class-bound, or independent, the code may still run, but it will be easier to misuse, harder to maintain, and more likely to surprise.

Both APIs and queries succeed when they reduce ambiguity before it becomes a bug.


The real power of restrictions: they make mistakes harder to write

At first glance, restrictions sound limiting. A class method cannot access instance state directly. A static method cannot access either instance state or class state unless it is passed something explicitly. A WHERE clause must evaluate to true or false. DISTINCT only returns unique values. ORDER BY creates a disciplined arrangement rather than an arbitrary one.

But the important insight is that these restrictions are not limitations in the ordinary sense. They are guardrails.

When a static method cannot accidentally mutate object state, it forces the programmer to be explicit about what the method is and is not allowed to do. When a class method receives cls, it has enough context to create or modify class-level behavior without pretending to be an instance method. When a WHERE condition must evaluate to a Boolean expression, it forces the retrieval logic to become precise. When rows are unordered by default, the query writer must declare a sorting rule if order matters.

This is a profound pattern: constraints sharpen intent.

Think about a kitchen with clearly labeled tools. A whisk is for mixing. A knife is for cutting. A scale is for measuring. If every tool could do every task, the kitchen would be more powerful on paper and more dangerous in practice. The same is true in code. A named method type or a well structured query clause is like a specialized tool. It narrows behavior enough that misuse becomes more obvious.

That is also why these features help with testing. A static method, because it behaves like a regular function but remains inside the class namespace, can be easier to test in isolation. A query whose filters are explicit can be reasoned about without mentally reconstructing implicit assumptions about ordering or uniqueness. In both cases, clarity is a form of testability.

The best abstractions do not give you more freedom. They give you less accidental freedom and more intentional freedom.

That distinction is everything. The goal is not maximum possibility. The goal is maximum reliability.


A mental model: three kinds of knowledge in every system

There is a useful way to think about clean software design: every operation should answer one of three questions.

  1. Does this depend on one object's state?
  2. Does this depend on the class as a whole?
  3. Does this depend on neither, but still belong conceptually in this domain?

Instance methods answer the first question. Class methods answer the second. Static methods often answer the third. SQL clauses add a parallel structure:

  1. Which rows matter? WHERE
  2. How should they be grouped or reduced conceptually? DISTINCT
  3. In what order should they appear? ORDER BY

This gives us a broader design principle: a good interface should separate identity, membership, and presentation.

  • Identity is about what an object or row is.
  • Membership is about whether it belongs in the current operation.
  • Presentation is about how it should be viewed or consumed.

Confusing these leads to messy code. For example, a method that both builds a new object and mutates existing instance state may hide two different responsibilities. A query that mixes filtering logic with presentation assumptions may be brittle when requirements change. If you sort only because a report happens to look nicer that way, you may accidentally bake UI preference into a data access layer.

A clean system keeps these concerns visible. It does not let a display requirement masquerade as a data requirement. It does not let a construction pathway masquerade as a mutation pathway.

That is why class methods are so useful as factories. They let the class own creation logic without blurring the line between constructing and modifying. And that is why ORDER BY belongs in the query, not in some later ad hoc processing step, if the order is semantically meaningful. The structure itself should carry the meaning.


From syntax to stewardship

There is a deeper organizational lesson here. The best APIs do more than reduce boilerplate. They create stewardship.

A class with a thoughtful mix of instance methods, class methods, and static methods communicates which parts of the system are stable, which parts vary per object, and which parts are domain helpers. A query written with explicit WHERE, ORDER BY, and DISTINCT communicates not only what data is needed, but how the data should be interpreted.

This matters because software lives longer than the assumptions of the person who wrote it. Future maintainers inherit code under conditions of uncertainty. They may not know why a function was made static. They may not know why duplicates matter. They may not know why a result set is sorted descending by publication year. The interface must answer those questions for them.

A strong interface is therefore a form of documentation that cannot drift as easily as comments. It is live documentation, embedded in usage rather than prose.

Here is the practical test:

  • If a behavior needs access to one object's internals, make that visible through an instance method.
  • If a behavior is about creating or configuring the class's products, make that visible through a class method.
  • If a behavior is related to the domain but independent of state, make that visible through a static method.
  • If a retrieval depends on relevance, say so with WHERE.
  • If uniqueness matters, say so with DISTINCT.
  • If order matters, say so with ORDER BY.

The goal is not rigidity. The goal is legibility.


Key Takeaways

  1. Use the interface to encode intent. Do not rely on comments or tribal knowledge when the language or query can express the rule directly.
  2. Choose the narrowest tool that fits the responsibility. Instance methods, class methods, static methods, WHERE, DISTINCT, and ORDER BY each narrow behavior in useful ways.
  3. Treat constraints as safeguards, not obstacles. Restrictions often prevent the kinds of mistakes that are hardest to detect later.
  4. Separate meaning from mechanics. Construction, filtering, uniqueness, and ordering are different concerns and should be made distinct in code and queries.
  5. Design for the next reader, not just the current writer. A clear API or query reduces the amount of hidden context future maintainers must reconstruct.

The surprising common thread: clarity is a form of power

We often praise software for being flexible, but flexibility without structure quickly turns into ambiguity. The more powerful a system becomes, the more important its boundaries are. Method types and SQL clauses are examples of a deeper rule: the best systems do not merely allow actions, they classify them.

That classification changes how humans think. It tells us what belongs to an object, what belongs to a class, what belongs to a domain helper, what belongs in a filtered result set, what must be unique, and what must appear first or last. In that sense, good design is not just about execution. It is about cognition.

So the next time you decide between an instance method, a class method, a static method, or a query clause, ask a better question than "Which one works?" Ask:

Which one teaches the codebase what kind of truth this is?

Because the cleanest systems are not the ones with the most features. They are the ones whose structure makes the right truth hard to misunderstand.

Sources

← Back to Library

Hatch New Ideas with Glasp AI 🐣

Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)

Start Hatching 🐣