How to Define and Evaluate Good Code: Practical Standards for Developers
This article explores what constitutes good code, presenting objective and subjective criteria—from logical clarity and minimal dependencies to readability, documentation, testing, concurrency handling, performance, and maintainability—while offering concrete guidelines and recommended reading for developers seeking to improve code quality.
Although recent graduates often care about code quality, their output rarely reaches an "excellent" level because they lack a clear understanding of what good code should look like.
What Is Good Code
The first step in writing code is understanding what good code means. While preparing a bootcamp curriculum, I struggled to define "excellent", "good", and "poor" code in a way that is actionable.
1. Definition of Good Code
Searching online for "elegant code" yields definitions such as the one from Bjarne Stroustrup, the father of C++:
Logic is clear and bugs are hard to hide.
Dependencies are minimal, making maintenance easy.
Error handling follows a clear strategy.
Performance is near optimal, avoiding chaotic or unprincipled optimizations.
Clean code does one thing.
Grady Booch, author of *Object‑Oriented Analysis and Design*, adds:
Clean code is simple and direct.
It reads like well‑written prose.
It never obscures the designer’s intent, using only a small amount of abstraction and clear control flow.
Michael Feathers, author of *Working Effectively with Legacy Code*, says:
Clean code looks like it was written by someone who cares about quality.
There are no obvious places that need improvement.
The author appears to have considered all aspects.
These viewpoints make sense, but they are hard to apply in practice, especially for newcomers who struggle to interpret vague notions like “simple and direct”.
In many code‑review discussions, developers cannot agree on a single standard for good code, leading to prolonged debates.
After countless code reviews, I found the following diagram helpful:
Code‑quality evaluation is somewhat similar to literary criticism: readers subjectively assess a work, forming a relatively objective judgment. However, code has two readers—the computer and the programmer. Even if programmers cannot understand a snippet, the computer can still execute it.
Therefore, code quality should be analyzed from two dimensions: the subjective, human‑readable aspect, and the objective, machine‑executable aspect.
2. Readable Code
I prioritize readability because a programmer would rather inherit buggy but understandable code than flawless code that is unreadable.
2.1. Literal Translation
Many books stress that code is first for people, then for machines. I ask authors to translate code line‑by‑line into natural language, read the translation aloud to someone unfamiliar with the code, and consider it readable if they understand it.
This method reveals hidden assumptions and readability traps that only the author knows.
2.2. Follow Conventions
Conventions cover code organization, comment style, and coding standards. Aligning with open‑source project styles or company guidelines reduces maintenance cost; creating ad‑hoc rules often signals limited exposure to quality code.
2.3. Documentation and Comments
Documentation should be discoverable and understandable. Typical docs include project overviews, quick‑start guides, and detailed API specifications.
Project overview: readers should grasp the purpose within three minutes.
Quick‑start: readers should build and run a simple example within an hour.
Detailed usage: readers should understand interfaces, parameters, and design.
Javadoc‑style comments serve as both code and documentation, keeping information close to the source.
Internal comments should explain decisions that the code itself cannot convey, such as “why this branch is omitted”. The quantity of comments matters: too few may hide hidden logic, too many may indicate unreadable code.
2.4. Recommended Reading
《代码整洁之道》 (Clean Code)
3. Deployable Code
Newcomers often write code that works in tests but fails in production, lacking proper exception handling, concurrency control, and performance awareness.
3.1. Exception Handling
Most junior developers ignore exceptions, yet production environments encounter crashes, timeouts, and malicious inputs. Unit‑test coverage is a good proxy for exception‑handling awareness.
3.2. Concurrency Handling
Resumes often claim expertise in multithreading, but practical tasks reveal a steep learning curve. Key concurrency risks include:
Any non‑local memory access (e.g., object fields, static variables) is a concurrency risk.
Shared resources such as caches or databases are risky.
Calling non‑thread‑safe APIs (e.g., Java’s HashMap) can cause issues.
Even ordered operations can be unsafe if they depend on timing (e.g., delete then decrement count).
Detecting the first three risks is straightforward; the fourth often requires deeper analysis across system boundaries.
3.3. Performance Optimization
Performance is a key metric but hard to judge from code alone. Two practical indicators are algorithmic time complexity and the cost of individual operations (e.g., database or I/O calls).
High‑complexity algorithms inevitably run slower.
Expensive single‑step operations should be minimized.
Over‑optimizing can hurt readability and increase complexity; performance should be validated with data, not speculation.
3.4. Logging
Good logs make troubleshooting easier. Effective logs should:
Cover all exceptions and external calls, with entry, exit, and key points logged.
Be clear and consistent, mirroring code readability standards.
Include sufficient context (e.g., request IDs, returned values) for analysis.
Adjusting log levels in production allows control over volume without sacrificing usefulness.
3.5. Further Reading
Release It!: Design and Deploy Production‑Ready Software
Numbers Everyone Should Know
4. Maintainable Code
Maintainability is harder to quantify because it concerns future evolution. Two guiding questions help:
What happens if the original author leaves?
What if the author does not follow best practices?
4.1. Avoid Duplication
Code duplication—both module‑internal and module‑external—signals poor design. IDEs can detect duplicate code automatically.
if (memberList.size() > 0 && memberList.size() < 200) {
// return current member list
return memberList;
}Over time, duplicated or overly commented code can become unreadable.
4.2. Module Partitioning
High cohesion within modules and low coupling between them is a standard design goal. Large classes (>2000 lines) or functions (>two screens) are warning signs. Excessive dependencies or circular dependencies indicate poor modularization.
4.3. Simplicity and Abstraction
Clean, simple code avoids unnecessary complexity. Experienced developers abstract essential concepts while keeping implementations straightforward.
4.4. Recommended Reading
《重构-改善既有代码的设计》 (Refactoring)
《设计模式-可复用面向对象软件的基础》 (Design Patterns)
Software Architecture Patterns – Understanding Common Architecture Patterns and When to Use Them
Conclusion
This article outlines various subjective and objective methods for assessing code quality. While no single metric fits all scenarios, developing a personal “taste” for code improves with experience, encouraging continuous learning and critical thinking.
Author: 蛋疼的axb Source: http://blog.2baxb.me/archives/1378
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
