File Structure

There are two widely used types of source code organization and I will explain why one of these should be avoided.

As an example, let's take a look at the Model-View-Controller (MVC) pattern. In MVC, every user interface has three components:

  • Model
  • View
  • Controller

An inexperienced programmer will often create this file structure when asked to create an MVC project:

.
├── controllers
│   ├── Post.controller
│   └── User.controller
├── models
│   ├── Post.model
│   └── User.model
└── views
    ├── Post.view
    └── User.view

We call this "by type" organization and it should be avoided like the devil.

First of all, it violates the software principle that closely related things should always stay close to each other.

It becomes extremely annoying to find all the files related to one component. Nowadays fuzzy finders can help offset this problem, but it's nonetheless a problem that could have been avoided in the first place instead of requiring extra tooling.

Secondly, the most important problem: Deletion.

If a component is no longer needed, then you need to delete it from your repository. This should be a trivial task, ideally one rmdir and you're done. If your component, however, happens to be spread out over 30 different folders, then the deletion process is very complex and you're gonna have to list all these 30 folders in your source code if you ever want to automate that process.

Organize "by concept"

There is a very simple solution to all of these problems and it's called "by concept" or "by feature" organization:

.
├── Post
│   ├── Post.controller
│   ├── Post.model
│   └── Post.view
└── User
    ├── User.controller
    ├── User.model
    └── User.view

With this file structure:

  • All related code is closely grouped together
  • Deleting a component is very easy

Depending on the style regulations, you might encounter Posts and Users, but it's the same principle. I prefer singular because plurals aren't consistent. You can't build a plural path with a simple s suffix, so if your code uses type names via reflection to build the paths, you're better off with singular names.

Conclusion

  • Don't organize files by their file type
  • Organize files by concept
  • Make deletion simple