in my project I am finding that I mix and match the following two patterns, when it comes to organizing classes in folders/namespaces:
Modularized MVC Blocks
module/Album/Feature/Controller/AlbumFeatureController.php
module/Album/Feature/Repository/AlbumFeatureRepository.php
module/Album/Feature/Form/AlbumFeatureForm.php
- - - -
module/Album/Feature2/Controller/AlbumFeature2Controller.php
module/Album/Feature2/Repository/AlbumFeature2Repository.php
module/Album/Feature2/Form/AlbumFeature2Form.php
- - - -
- - - -
module/Album/Feature100/Controller/AlbumFeature100Controller.php
module/Album/Feature100/Repository/AlbumFeature100Repository.php
module/Album/Feature100/Form/AlbumFeature100Form.php
- Pro: If I want to remove a Feature, I remove the folder called “Feature” and make a few adjustments
- Con: creates more folders
Community MVC Blocks
module/Album/Controller/AlbumFeatureController.php
module/Album/Controller/AlbumFeature2Controller.php
. . .
module/Album/Controller/AlbumFeature100Controller.php
- - - -
module/Album/Repository/AlbumFeatureRepository.php
module/Album/Repository/AlbumFeature2Repository.php
. . .
module/Album/Repository/AlbumFeature100Repository.php
- - - -
module/Album/Form/AlbumFeatureForm.php
module/Album/Form/AlbumFeature2Form.php
. . .
module/Album/Form/AlbumFeature100Form.php
- Pro: all
Controllers
are in “Controllers” folder - Con: here when I want to delete the feature, I need to individually go to folders
Controller, Form, Repository
, and seek classes that are named after my Feature and remove those.
I am beginning to favor the modular approach due to it’s compartmentalization as stored on the file system.
Question:
is one approach superior to another, or are both of the equally interchangeable according to one’s own needs, tastes, and preferences?
1
Actually this is matter of cohesion.
From wikipedia:
In computer programming, cohesion refers to the degree to which the elements of a module belong together.
You can check this article about cohesion: https://en.wikipedia.org/wiki/Cohesion_%28computer_science%29
For me the modular approach, as you call it is representation of functional cohesion, which is pointed as best typo of cohasion.
Functional cohesion is when parts of a module are grouped because they all contribute to a single well-defined task of the module
This is the question as I understand it:
Is there a superior way to classify files that contain code? Here are two example classifications.
Not really. In my experience, both approaches are valid. The “better approach” depends on the codebase, the organization and possibly personal preference.
Smaller/newer projects start off and benefit from the first “modular” approach. You add features that may or may not be maintained in the long term. Smaller, more dynamic codebases usually involve refactoring features, and not as often components or by function. The process of adding a feature is well defined and causes little impact to other areas of the codebase.
Larger, older and more complex codebase is generally better maintained based on the functionality and commonality of the code elements, rather than the features it supports. So the “community” version is a better approach. This helps with refactoring changes like new library versions, database upgrades, font changes, etc.
Organizations that have developers that work on single features can benefit from the “modularized” approach. Organizations that have several developers working on the same codebase probably will divide work based more on your “community” concept – one works on the controllers while another does UI.
Also consider that you are naming files that represent concepts that the code should contain. However, different developers will have different approaches and/or perspectives on the particular contents of each file. Which means you may consider some code to belong in the controller while another developer would see it as belonging in the form. Now what?
The more people you have involved in your project, the more important it is to divide by “function” rather than by “feature” to force the codebase with common functionality to be grouped together. The fewer people that you have, the more important it is to do the opposite in many cases, so that a developer tasked with changing a feature keeps the changes contained to that feature.
Your tendency to favor one approach over the other is probably due to the nature of your work and/or the organizational approach to developing and maintaining code, as opposed to one being innately superior to another.