5

In most of the MVC / MV* type frameworks I've played with they want you to have your source organized something like this:

model/
    FooModel.xyz
    BarModel.xyz
view/
    FooView.xyz
    BarView.xyz
controller/
    FooController.xyz
    BarController.xyz

organizing into directories based on the MVC elements rather than by the applications object types. Some part of me always feels like life would be easier if the code was organized like so:

Foo/
    FooModel.xyz
    FooView.xyz
    FooController.xyz
Bar/
    BarModel.xyz
    BarView.xyz
    BarController.xyz

Because in general, if I'm working on Foo (adding a new field for instance), I am often opening up all the Foo* files, which is tedious (first world problems) because all the Foo files are in different directories.

Is that a code smell that there is too tight of coupling between the Foo sources?

And of course, this alternative gets less appealing when we have models, views or controllers that don't have corresponding views, controllers and models. Which is often (usually?) the case...

So why is the standard organization for MV* frameworks actually better than my proposed straw man alternative?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
jwl
  • 10,268
  • 14
  • 53
  • 91
  • 1
    Unless some framework has a technical reason for its organización, this feels Not-constructive. – madth3 Jan 28 '13 at 19:32

2 Answers2

1

I've been in the same dilemma myself. Looking in StackOverflow, What strategy do you use for package naming in Java projects and why? have some interesting insights, specially Uncle Bob's design principles for granularity. In the Common Reuse Principle he says:

THE CLASSES IN A PACKAGE ARE REUSED TOGETHER. IF YOU REUSE ONE OF THE CLASSES IN A PACKAGE, YOU REUSE THEM ALL.

In the design package you mention, it makes perfect sense to have a model package, as is very common to reuse several Model classes through Controller and View Layers. On the other side, foo package can be hardly reused as is an application module itself. Also, according to the Common Closure Principle:

THE CLASSES IN A PACKAGE SHOULD BE CLOSED TOGETHER AGAINST THE SAME KINDS OF CHANGES. A CHANGE THAT AFFECTS A PACKAGE AFFECTS ALL THE CLASSES IN THAT PACKAGE.

Several technlogy-related changes -like changing the JavaScript Library or the Dependency Injection Framework- will have minimum impact in model-view-controller packages (only one package should change) than in functional ones (the changes will span in all packages).

Community
  • 1
  • 1
Carlos Gavidia-Calderon
  • 7,145
  • 9
  • 34
  • 59
  • But adding/removing/changing the nature of Foo's elements exactly matches "A CHANGE THAT AFFECTS A PACKAGE AFFECTS ALL THE CLASSES IN THAT PACKAGE.", which argues for the alternative layout. And those kinds of changes are far more frequent than changing dependencies. – jwl Jan 28 '13 at 20:03
  • But Foo being a model element, it's expected to impact several Controller and View classes. Being the model associated to the application domain, it's expected to be consumed by several other components. – Carlos Gavidia-Calderon Jan 28 '13 at 20:11
1

Not sure about other MVC frameworks, but for ASP.NET MVC specifically, the views should be in the Views/ folder.

One of the principles behind ASP.NET MVC is Convention over configuation. The view engine expects to find the views in a certain location. I believe you can override that, but it's generally better not to. (Use the convention)

I think the biggest problem with this file organization is cascading changes. If I need to add a field, I need to update 5 places (the model, the view, the viewmodel, the controller, the unit test). If you're digging around in folder trees to find these things, it can be tedious.

Maybe the question behind the question is 'How can I navigate through my solution artifacts more efficiently?' Again not sure about other IDE's, but since I use Visual Studio I've got my own set of preferences to help with that task.

In Visual Studio ctrl+, (control comma) is great for navigating to types/files/artifacts within a solution. Also I use F12 and Shift+F12 for 'goto definition' and 'find all references'. Also I customized the 'Find in Files' button to display image and text in the toolbar to make the button easier to hit.

Matt Brunell
  • 10,141
  • 3
  • 34
  • 46
  • If an MVC framework expects to find things in certain locations, that's fine... but we can still argue over where those locations should be. Meanwhile, in terms of IDEs making it easier, that's not a bad idea. But it can't provide the full answer since in general you should not have a code organization that only works for a certain IDE -- other developers in the project may want to use something different. Heavyweight IDEs like Visual Studio and so on of course have the opposite opinion and do everything to make that difficult for you... – jwl Jan 28 '13 at 20:15