The source tree layout should reflect the architecture; as a corollary, a well-structured architecture can lead to a well-structured source tree layout. I suggest reading up on the POSA1 Layers pattern, attempting to fit your architecture into a layered structure, then naming each of the resulting layers, and using that as a basis for your source hierarchy. Taking a common three-tier architecture as a baseline:
- presentation/webService (present a web-service interface to our business logic)
- logic/* (business logic modules go in here)
- storage/sql (back-end storage APIs here - this uses a SQL interface to store to a database)
- util/* (utility code - usable by all other layers, but that does not refer outside util, goes here)
Note that the layers do not contain code directly, but rather are strictly used to organize modules.
Within a module, I use the following sort of layout:
<module>(path to module directly; defines modular interface)<module>/impl/<implName>(a specific implementation of the modular interface)<module>/doc(Documentation for using the module)<module>/tb(unit-test code for the module)
where the <module> is located in the repository according to the layer to which it belongs.
The source tree layout should reflect the architecture; as a corollary, a well-structured architecture can lead to a well-structured source tree layout. I suggest reading up on the POSA1 Layers pattern, attempting to fit your architecture into a layered structure, then naming each of the resulting layers, and using that as a basis for your source hierarchy. Taking a common three-tier architecture as a baseline:
- presentation/webService (present a web-service interface to our business logic)
- logic/* (business logic modules go in here)
- storage/sql (back-end storage APIs here - this uses a SQL interface to store to a database)
- util/* (utility code - usable by all other layers, but that does not refer outside util, goes here)
Note that the layers do not contain code directly, but rather are strictly used to organize modules.
Within a module, I use the following sort of layout:
<module>(path to module directly; defines modular interface)<module>/impl/<implName>(a specific implementation of the modular interface)<module>/doc(Documentation for using the module)<module>/tb(unit-test code for the module)
where the <module> is located in the repository according to the layer to which it belongs.
I can't really give you much advice related to webprojects, but here's how I structure my tree in a programming project (mainly from a C/C++ perspective):
- /
- src — Source files written by myself
- ext — Contains third-party libraries
- libname-1.2.8
- include — Headers
- lib — Compiled lib files
- Donwload.txt — Contains link to download the version used
- libname-1.2.8
- ide — I store project files in here
- vc10 — I arrange project files depending on the IDE
- bin — Compiled exe goes here
- build — The compiler's build files
- doc — Documentation of any kind
- README
- INSTALL
- COPYING
A few notes:
If I'm writing a library (and I'm using C/C++) I'm going to organize my source files first in two folders called "include" and "src" and then by module. If it's an application, then I'm going to organize them just by module (headers and sources will go in the same folder).
Files and directories that I listed above in italics I won't add to the code repository.
Videos
For Java, packages are the unit of reuse.
For Python, modules (as well as packages) are the unit(s) of reuse.
The package should be a stand-alone thing.
If you put all data transfer objects into one big package, you don't have something terribly reusable. You might not want all those data transfer object definitions.
If you put things together by "entity" -- the model, the views, the controls, the data access, etc. -- then you have a reusable module that can be shared in other applications.
The 'Package-by-Feature' approach seems sensible and works for me, certainly for Java... how often do you want to pack up your data access layer, vs. that nifty new feature?
I thought the analysis "Package by feature, not layer" at javapractises.com was pretty easy to read, and covered a couple of angles I'd not thought about, like how package by feature works in other domains than programming, too.