For the last 20 years, the dogma of software engineering was simple: "Good code documents itself."
We were taught that comments are a "code smell" (Uncle Bob told us so). We were taught that if you need to explain it, you failed to name it properly. We were taught to DRY (Don't Repeat Yourself) everything into oblivion.
But in 2024, the game changed. You aren't just writing code for your future self or your colleagues anymore. You are writing code to be consumed, understood, and extended by an AI Agent.
The AI doesn't care about your clever one-liners. It cares about Context. Here is what you need to unlearn.
The Old Way: Comments explain why something happens because the how should be obvious. The AI Way: Comments are Prompts.
If you use GitHub Copilot or Cursor, you’ve realized that the comment is no longer passive text. It is a functional specification. Writing a detailed comment is the fastest way to get the AI to generate the implementation you want.
But there is a trap. AI tends to over-comment, generating noise like // increments i by 1. This is garbage.
The new best practice is Context Injection. You use comments to constrain the AI's probabilistic nature.
// BAD: The "Old School" minimalist style // Validates the user public boolean isValid(User u) { return u.getAge() > 18 && u.isActive(); } // GOOD: The "AI-Ready" style // Validates user for Premium Tier eligibility. // RULES: // 1. Must be 21+ (legal requirement for this feature) // 2. Account must be in 'ACTIVE' or 'GRACE_PERIOD' state // 3. Must not have any flagging history in the last 90 days. public boolean isEligibleForPremium(User user) { // If you type the comment above, Copilot will generate this accurately: if (user.getAge() < 21) return false; if (user.getStatus() != Status.ACTIVE && user.getStatus() != Status.GRACE_PERIOD) return false; return !auditService.hasFlags(user.getId(), Duration.ofDays(90)); }
The Takeaway: Don't delete comments. Upgrade them. A good comment defines the boundaries of the logic so the AI doesn't hallucinate edge cases.
The Old Way: Short is sweet. ctx, usr, repo. The AI Way: Semantic density wins.
LLMs work on probability. They guess the next token based on the previous ones. If you name a variable data, the AI has to guess what's inside. It might guess String, Map, or List.
If you name it pendingTransactionList, the AI knows exactly what methods to call on it (.stream().filter(Tx::isPending)...).
Ambiguous naming leads to AI Hallucinations. If you name a method process(), the AI will invent what "processing" means. If you name it validateAndPersistOrder(), the AI will likely generate validation logic followed by a database save.
The New Rule: optimize for Predictability, not Brevity.
The Old Way: DRY (Don't Repeat Yourself). Abstract everything into base classes and interfaces. The AI Way: AHA (Avoid Hasty Abstractions) / Locality of Behavior.
This is the biggest shift. Deep inheritance hierarchies and extreme modularity hurt AI performance.
Why? The Context Window.
When an AI agent tries to fix a bug in OrderService.java, it reads that file. If OrderService extends BaseService, which extends AbstractEntityService, which implements GenerericCrudInterface, the AI has to retrieve and reason about four different files just to understand one method.
If the logic is spread too thin, the AI loses the plot. It hallucinates methods that exist in the parent class but not the child.
The Shift: It is better to have 50 lines of explicit, slightly repetitive code in one file (Locality of Behavior) than to hide that logic behind three layers of abstraction.
// BAD for AI: Deep Inheritance // The AI has to "know" what AbstractProcessor does to understand this. public class PaymentProcessor extends AbstractProcessor { @Override protected void doExecute(Context ctx) { // Logic hidden in parent methods super.validate(ctx); this.charge(ctx); } } // GOOD for AI: Explicit Composition // Everything the AI needs to know is visible in THIS file. public class PaymentProcessor { private final Validator validator; private final Gateway gateway; public void process(PaymentContext ctx) { // AI can see the flow clearly if (!validator.isValid(ctx)) { throw new ValidationException("Invalid context"); } gateway.charge(ctx.getAmount()); } }
The danger of the AI era is the Flood of Mediocrity.
Because generating code is free, developers will produce 10x more of it. We are seeing PRs explode in size. The "Clean Code" principle that is suffering most is conciseness.
AI is verbose. It loves to generate boilerplate. It loves to write 20 lines where 3 would do.
The danger: You stop reading the code. You see a generated block, it looks shaped like code, so you accept it. This is how subtle bugs—security vulnerabilities, logic errors, and tech debt—creep in.
Clean Code isn't dead, but "Clever Code" is.
The code that survives in the AI era is Explicit, Semantically Rich, and Locally Contextual.
Stop trying to impress the compiler. Start trying to guide the Agent.
\


