4

Let's say I have three classes: A, B, and C. All of these classes are simple and they create a cohesive unit. In addition, B depends on C and C depends on A.

Most people would put these classes into one directory:

java
├── A.java
├── B.java
├── C.java

It's simple, but it's difficult to tell where the logic starts. You have no idea that B is at the root of the dependency chain. You would have to open up the files to understand the architecture.

Instead, you could use this directory structure:

java
├── B.java
├── C
│   ├── C.java
│   ├── A
│   │   └── A.java

With this directory structure, you can easily tell that logic begins in B and ends in A. But it's more complicated. You might have a single file in a folder. You might have to duplicate the file name in the directory name. You also may quickly create a highly nested directory structure. But I think the advantages could outweigh the disadvantages.

I haven't seen this idea discussed anywhere, so I feel like it might be a bad idea. Would this over-complicate a project structure? Would others be able to follow along? If applying this idea to a language like Java/Python/C#, would this create too many packages/modules/namespaces and make importing too difficult? Is this a bad idea?

  • 3
    You determine the logic by looking at the code, not at the file names or folder structure. – Robert Harvey May 20 at 21:37
  • 1
    Dependecies usually take the form of an acyclic directed graph rather than a tree. – Jared Goguen May 21 at 3:54
6

This approach is not as good as good as it might appear. Directory structures are not as flexible as programming languages expressivity.

Let's look at some problems you have to think of in your structure:

  • what if you have a circular dependency ?
  • what if I had multiple dependencies, as it often appear in real life ? For example if I'd have a class X that is a dependent of B and A ?
  • what if you'd refactor some code in a clever way and would change the existing dependencies ?

Your approach has also consequences on the development process:

  • making change in code might require to change the directory structure as well. This is an overhead for the developers. And sooner or later someone will forget, making the structure out of sync.
  • getting used to this structure and relying on it would prove to be error prone, some dependencies might be overlooked in the code if you'd expect the directory structure to be a reliable indicator. Otherwise stated, this practice might lead to the habit of not reading the code to understand how it's structured.
  • worse of all, moving files across the directory structure makes it very difficult to follow up the history in GIT (or any other SCM tool), since the file would look like a new file after every move, and to get older verions, you'd need to know where to search. (Ok, there are some tricks to reduce the risk, but again, it needs some extra caution).
  • finally, it might backfire on reusability, since the structure makes it difficult to cope with multiple dependencies.

So in conclusion, don't go for that ! If you want separate directories, consider packages as potential candidate. And keep the structure as flat as possible. Directory structure should help developers to easily navigate in the source, and find the stuff they are looking for, where they expect it to be. It shall not be misused to replace code analysis tools.

2

First it's best to use the correct terminology for Java and explain how it is differs from what you have described. Java has a concept of 'packages' that are implemented using directories but are not equivalent to directories. The package that a class sits in is part of the unique name of the class. The package is declared in the class but must also align with the location of the source file relative to the classpath. That is, you can have classes in the same package from source in different directories. For example, most projects put unit test classes in the same package as the classes they test but in a different folder hierarchy.

So your proposal is, I think to have the following classes:

B.B
B.C.C
B.C.A.A

I don't think this is good idea. Personally I would find it confusing and not helpful at all. Folder hierarchies are also pretty one-dimensional. What does this look like when you have a class that depends on multiple classes? I think you'd be spending a lot of effort trying to arrange the classes in folders and aligning their package declarations. Inevitably, it will stop aligning with reality and you'll just have a convoluted mess of package names.

I also don't think this is a big problem. One of the advantages of using a language like Java is that as long as you aren't using lots of magic (and people do) the dependencies within a project are known at compile time. You can simply select a class in an IDE and get a listing of what depends on it.

You might also want to look at modules and see if there are features that might help with the issue you wish to solve.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.