DEV Community

Cover image for #1 - Spot problems before reading any code
Benjamin Savoy
Benjamin Savoy

Posted on

#1 - Spot problems before reading any code

Last week we started with a strong claim: You don't need to read every line. But now we've got to substantiate it. So, today, I'll show you a few ways to spot issues without even looking at the code. That's particularly interesting with LLMs as you might want to try coding in a language that you don't even know yet. I do believe that it's entirely possible, as long as you have an adequate amount of software engineering experience. I have myself experimented with game development in Rust (assisted by Claude), but more on that later with a practical example...

Structure is documentation

You've probably already heard of MVC (model, view, controller) which is a popular way to organise web applications. It does separate the concerns in three distinct buckets. There are of course many more approaches, all with different advantages for different kinds of software. The goal here isn't for me to preach what the best approach is, but that whatever approach is used should be obvious from looking at the file tree.

For example, let's take a basic MVC webapp filetree:

MyApp/
├── src/
│   └── MyApp.Web/
│       ├── Controllers/
│       │   ├── HomeController.cs
│       │   ├── OrdersController.cs
│       │   └── UsersController.cs
│       ├── Models/
│       │   ├── Order.cs
│       │   ├── User.cs
│       │   └── ViewModels/
│       │       ├── OrderSummaryViewModel.cs
│       │       └── UserProfileViewModel.cs
│       ├── Views/
│       │   ├── Home/
│       │   │   └── Index.cshtml
│       │   ├── Orders/
│       │   │   ├── Index.cshtml
│       │   │   └── Details.cshtml
│       │   ├── Users/
│       │   │   └── Profile.cshtml
│       │   └── Shared/
│       │       ├── _Layout.cshtml
│       │       └── _ValidationScripts.cshtml
│       ├── Services/
│       │   ├── IOrderService.cs
│       │   ├── OrderService.cs
│       │   ├── IUserService.cs
│       │   └── UserService.cs
│       ├── Data/
│       │   ├── AppDbContext.cs
│       │   └── Repositories/
│       │       ├── IOrderRepository.cs
│       │       └── OrderRepository.cs
│       ├── wwwroot/
│       │   ├── css/
│       │   ├── js/
│       │   └── images/
│       ├── Program.cs
│       ├── appsettings.json
│       └── MyApp.Web.csproj
├── tests/
│   └── MyApp.Tests/
│       ├── Controllers/
│       ├── Services/
│       └── MyApp.Tests.csproj
├── README.md
├── Makefile
├── docker-compose.yml
└── MyApp.sln
Enter fullscreen mode Exit fullscreen mode

How much can you infer from just the file tree? Hopefully a fair bit already. Requests likely come from Controllers. The state should hopefully be self-contained in Data. Services handle the business logic - hopefully in a stateless manner since we have a separate Data directory. Views are the glue between the Controllers and the rest, indeed they map 1:1 so it's easy to track what goes where.

Now you could decide that things that map 1:1 with each other should be in the same folder, and you wouldn't be wrong. The main point here is that structure should make it obvious where to look at the very least.

So, it runs on your machine, but what about mine?

You may have noticed a few more things at the root of this folder, which are quite helpful here.

Seeing a Makefile makes me hope that I might find a way to build, test, and deploy this application. And hopefully the README.md file would provide the rest of the context needed for those tasks. It gives me hope that this repository might be self-contained and have all the instructions that I need to run it. However, remove the Makefile, and it's starting to look dicey. At best it seems like I'd have to read the whole README and copy paste commands from there. It does seem like a bit of a hassle.

Structure is documentation, but what about documentation?

Okay - I have a chip on my shoulder here. I hate to repeat myself. However, some people (including most LLMs) love to write a lot of documentation, and there might even be some people who enjoy reading it! Reality is, though, that if your file tree doesn't make sense, and then you have to look at documentation, you've already lost a fair chunk of time figuring how things are supposed to work. You're losing a lot of clarity about where you should store new code. And that does compound quite quickly, every new hire, every time you forget about an old legacy repository, the process repeats itself.

Moving and restructuring files around is usually the first step I take when faced with a complex legacy codebase, because it lets me tackle self-contained problems one by one. You're then no longer dealing with spaghetti, but small self-contained problems. And if you're not, the (hopefully) few files that really don't fit might well be the main problem you've got to tackle... leaving the rest mostly as-is.

Debugging without reading, really?

I've tried some game development in Rust, without knowing anything about the language. Claude Code did most of the work and as I troubleshoot things, I kept noticing that my previous engineering experience was applicable even if I didn't read any code. I was merely looking at the file tree, Claude Code, and launching the game every now and then.

But what I found out is that most bugs that arose as the game became a bit more complex were simply due to a lack of separation of concerns.

Every iteration, I'm adding a new UI element, a new kind of object in the game, a new mechanic, but it seems that LLMs are not that great at designing things iteratively like that with an eye for the future. And then, boom, I could click on things in game but the map would jitter all around the place, pop ups wouldn't be displayed, and some buttons I just implemented were not working anymore. It was a nightmare, but then I looked at the file structure.

Odd, I have a new file for the game settings panel I just added. I have a file for the map generation... but it's all in the same folder and there's no UI module. Let alone multiple UI modules. Every file was trying to define a bit of the UI and ultimately ended up being inconsistent.

A simple prompt to modularise the game, including a UI module with several files each dealing with a separate part of the UI and a reminder to check for inconsistencies quickly dealt with the buggy UI and Claude went on implementing many more features with way fewer bugs from that point on.

Structure is your map (and a few red flags)

Before I leave you for today, let me give you a few red flags that you can quickly check and apply to your output, and see if it helps you iterate faster with LLMs! Here's what could be a sign for concern:

  • No clear separation of concerns
  • Inconsistent names
  • Large files (500+ lines)
  • Missing/mismatched directories (for tests and others)
  • Lack of build/run automation and instructions
  • No clear entry points (APIs, CLI, DBs)

If you can't see the architecture from the file tree, something's wrong! Until next week...

~ Ben

Top comments (0)