It Ain't Broke: Why Software Fundamentals Matter More Than Ever — Matt Pocock, AI Hero @mattpocockuk

AI coding tools are powerful but can quickly create unmanageable code if used without discipline. Matt Pocock argues that success with AI in software development comes not from delegating everything, but from applying decades-old engineering fundamentals like TDD, Domain-Driven Design, and creating deep, testable modules. The developer's role shifts from a tactical coder to a strategic system designer.

4 min read
It Ain't Broke: Why Software Fundamentals Matter More Than Ever — Matt Pocock, AI Hero @mattpocockuk
source: https://www.youtube.com/watch?v=v4F1gFy-hqg

In the age of AI-driven development, fundamental software engineering principles are more critical than ever. The promise of “specs to code”—where developers only write specifications and let AI handle the implementation—often fails in practice. This approach frequently leads to a decline in code quality with each iteration, a phenomenon akin to software entropy, where the system devolves into unmanageable garbage.

The core issue is the misconception that “code is cheap.” In reality, bad code is more expensive than ever because a complex, hard-to-change codebase prevents developers from leveraging the full potential of AI. A good codebase, however, allows AI to be extraordinarily effective. This means software fundamentals are paramount.

From Miscommunication to Shared Understanding

A common failure mode is the AI not building what the developer intended. This stems from a lack of a shared “design concept” between the human and the AI.

  • Problem: The developer and the AI lack a mutual understanding of the project’s goals and constraints.
  • Solution: Implement a “Grill Me” skill. This prompts the AI to act as an adversary, relentlessly asking questions to explore every branch of the design tree. This process forces a deep dialogue, ensuring both parties reach a shared understanding before any code is written. The resulting conversation can serve as a detailed product requirements document.

The Power of a Ubiquitous Language

Another challenge is when the AI is overly verbose or seems to be “talking across purposes.” This is a language barrier issue.

  • Problem: The developer and the AI don’t share a common vocabulary, leading to misinterpretations and inefficient communication.
  • Solution: Adopt the Domain-Driven Design (DDD) concept of a “Ubiquitous Language.” Create a central document (e.g., a Markdown file) that defines the core terminology of the project. By training the AI on this glossary, its planning becomes less verbose, its thinking becomes more aligned with the domain, and the resulting implementation is more accurate.

Enforcing Quality with TDD and Feedback Loops

Even when the AI understands the goal, it can produce code that simply doesn’t work. This happens when it moves too quickly without verification.

  • Problem: The AI generates large amounts of code at once without checking its work, essentially “outrunning its headlights.” The rate of feedback is your speed limit.
  • Solution: Use Test-Driven Development (TDD). TDD forces the AI to take small, deliberate steps: write a failing test, write the code to make it pass, and then refactor. This iterative process, supported by feedback loops like static typing and automated tests, dramatically improves the reliability of the generated code.

Architectural Integrity: Deep vs. Shallow Modules

The effectiveness of TDD is directly tied to the system’s architecture.

  • Problem: AI has a tendency to create “shallow modules”—numerous small files with complex interfaces. This structure is difficult for both humans and AI to navigate, understand, and test effectively.
  • Solution: Refactor the codebase towards “deep modules,” as described by John Ousterhout in “A Philosophy of Software Design.” Deep modules hide significant functionality behind a simple, well-designed interface. This architecture is inherently more testable, providing clearer boundaries for verification. A codebase with deep modules rewards TDD and provides better feedback to the AI.

The Developer’s New Role: Strategic System Designer

The cognitive load of managing AI-generated code can lead to burnout. A well-structured codebase mitigates this.

  • Principle: “Design the interface, delegate the implementation.”
  • Application: By focusing on creating robust, well-tested interfaces for deep modules, developers can confidently delegate the internal implementation details to the AI. This allows you to treat modules as “gray boxes,” understanding their purpose and contract without needing to scrutinize every line of internal code.

Your role shifts from a tactical programmer to a strategic designer. You are responsible for the high-level architecture and investing in the design of the system every day. The AI serves as a powerful tactical implementer, but it requires your strategic guidance to build high-quality, maintainable software.

Share post

Stay In The Loop! Subscribe to Our Newsletter.

Get updates straight to your inbox. No spam, just useful content.

Recommended for You

Clean Architecture with Python • Sam Keen & Max Kirchoff • GOTO 2025

Clean Architecture with Python • Sam Keen & Max Kirchoff • GOTO 2025

Sam Keen discusses his book “Clean Architecture with Python,” explaining how to apply architectural principles in a pragmatic, Pythonic way. The conversation covers thoughtful dependency management, the onion model, and the crucial link between good architecture and testability. Sam also explores how these principles provide a robust foundation for AI-assisted coding by creating well-defined, scoped problems for AI agents, ultimately leading to more maintainable and resilient software.

Architecture for Flow • Susanne Kaiser & James Lewis

Architecture for Flow • Susanne Kaiser & James Lewis

In an interview with James Lewis, Susanne Kaiser discusses her book "Architecture for Flow," which synthesizes Domain-Driven Design, Wardley Mapping, and Team Topologies. She explains how this holistic approach helps design adaptive socio-technical systems by starting with the problem space, visualizing the value chain, and aligning team structures to the software architecture, all guided by her practical "Architecture for Flow Canvas."