

I have a question about organizing projects - raganwald
http://github.com/raganwald/homoiconic/blob/master/2009-03-12/another_question.md#readme

======
jamesbritt
In Monkeybars we decided to group all parts of the MVC tuple under the same
directory because we mainly work with them as a set. It's too annoying to have
to bounce around from a model dir to a controller dir to a view dir.

MVC|MVC|MVC is more natural grouping than MMM|VVV|CCC.

------
raganwald
I ask myself "What does the each patten make easy? What does each pattern make
difficult?" The standard or "verb-oriented" organization makes it easy to
manage cross-cutting concerns, like rewriting all of your views in HAML
instead of in erb, or adding a "created_at column to every model table. The
refactored, or "noun-oriented" organization makes it easy to manage model
concerns, like adding a new controller action with its associated views, model
changes, tests, and migrations.

I find the latter happens far more often than the former for me, so it feels
like a win even if I have no interest in sharing a model between applications.

~~~
gamache
Perhaps both schemes could be supported, using a system of symbolic links, or
in its most elite case maybe even a specialized user-space filesystem. Now you
have me thinking...

~~~
alain94040
That's a classic matrix problem. Information fits nicely in two categories.
How do you organize it? Choosing one or the other is mostly arbitrary. But
current file systems force you to make a choice. BeOS a long time ago sort of
wanted to fix that...

------
tjic
I actually do organize my plugins as raganwald suggests...and, as we've rolled
out more products, and I'm seeing increasing commonality in pieces between
then, am thinking more and more than 90+% of every one of our projects should
be all plugin code.

~~~
zcrar70
Raganwald is also mentioning refactoring the code so that the data objects
become responsible for persisting and displaying themselves though.

I don't necessarily have any problems with the persisting (that's how
ActiveRecord works out of the box), but I'm not sure about the displaying,
because I sometimes want to display things differently depending on the
context.

~~~
raganwald
Well, I gave a very trivial example showing that, but I don't necessarily
believe it should always work that way. Let me be more specific: _If_ you have
a Persistanceamajig that know the difference between an account and a
customer, then you might want to break it up. On the other hand, if the
Persistancamajig can do its job by inspecting the things you pass to it, then
it may be a very good idea to keep its implementation separate.

Likewise if you want a separate Displaythingie that can work out how to
display an account or a customer on its own, great. If it needs to know a lot
about accounst and custoemrs to do its job, but you want to swap it out or
paramaterize it (e.g. one set of views for iPhone, one set for Safari), the
classic organization makes a certain amount of sense.

All that being said, I have built a large, public-facing app with multiple
views for multiple devices, and my experience is still that we did
modifications across all of the things related to a model much more often than
doing modifications to all of the views across all of the application.

JM2C.

------
swombat
Actually, I would say that the very first example is the correct organisation
with proper separation of concerns. The reason they are often merged into the
form of the second code sample is for convenience rather than for
organisation. From a code design perspective, this is not a good thing (and I
know many people who complain that Rails made a mistake with that). From a
testing perspective, for instance, the coupling between the User object, the
methods that save and load that object from the db, and the validation code,
make it much harder to write cleanly isolated tests.

There are plenty of architectures where "data objects" are dumb and are passed
to more intelligent objects that can save them, serialize them, etc.

MMM|VVV|CCC is a better system than MVC|MVC|MVC because it encourages
separation of concerns, and loose coupling between concerns. Tight coupling
between mostly unrelated pieces of functionality (why should the persistence
code know anything about the controller?) is a very nasty code smell.

~~~
raganwald
> why should the persistence code know anything about the controller?

They don't know anything about each other. The question is not whether M,V,
and C should be the same entity. The question is why they are scattered all
over an application, such that adding a single field to a model involves going
to one place to add a migration, another place to add validations and other
model logic, a third place to change controller logic, a fourth place to
change one or more views, and so forth.

Should they be separate files? Perhaps yes. Should they be far away from each
other? That is what I am questioning. The "Separation of Concerns" you are
describing is not a very persuasive argument in Rails apps, IMO, because I
often have a concern like "add a field to this model" and I rarely have a
concern like "Change from HTML 4.0 to XHTML" or "Add a created_at column to
all tables."

~~~
swombat
In "separation of concerns" I'm talking about functionality, not human
concerns. See: <http://en.wikipedia.org/wiki/Separation_of_concerns>

Separation of concerns aims to produce modular, loosely coupled code.

Now, if we start from the point of view that they should be in separate files
anyway (in the ruby way, each file should contain one class rather than many -
and I don't think it's helpful to change that), then I don't see what
difference it makes whether the files are in the same directory or in separate
directories.

If you have any sort of decent editor, opening the file you seek should be a
matter of pressing a shortcut and typing part of the filename... Certainly, I
rarely use the mouse to open files - except when i'm browsing through a new
project, but that's a fairly rare use case.

Now, there's another problem I can see with your proposed organisation:
although in some cases (even many) applications are built around resource
objects, almost every non-trivial application has many edge cases of
functionalities that are not directly attached to objects, or are attached to
multiple kinds of objects, or are attached to objects but in a way that could
be mapped to one object or to another, and is actually best thought of as
being linked to something else.

Forcing the file system to be organised around resources like users, projects,
items, etc would coerce us into trying to fit functions onto specific objects
- and, importantly, it would remove the flexibility of being able to _not_ tie
a function to an object.

As such, I think the current model is more flexible and offers something that
your proposed model doesn't support and which is useful on most projects.

------
lucasvo
Django useses this Approach: app/ \---- models.py \---- views.py \---- urls.py
\---- admin.py etc.

etc. I think it does indeed make more sense. Though the difference is not that
big except for one case: Reusability of the code, that way you can easily just
copy the directory to another site.

------
codeodor
Almost. I wouldn't keep the extra cruft of vendor, plugin, app and controllers
for the simpler divisions of object (say those that are just 1 model,
controller, and views), but I've often wondered about that in Rails.

------
twashing
I would not give the refactoring recommendation you suggest. I would make both
Account and Customer 'Displayable' and 'Persistable' ( still thinking in Java
:( ). Then implement a kind of Strategy pattern to take a Displayable object.
Same goes for Persistable.

That way you can focus on the domain objects as data, and how they are related
to each other. You can also come up with cleaner (and more orthogonal)
patterns of how to display, persist, or otherwise handle that data.

------
dreur
Interesting, reminds me of the HMVC pattern (Hiearchical MVC) or the
Presentation abstraction control

PAC : [http://en.wikipedia.org/wiki/Presentation-abstraction-
contro...](http://en.wikipedia.org/wiki/Presentation-abstraction-control) HMVC
:
[http://www.javaworld.com/javaworld/jw-07-2000/jw-0721-hmvc.h...](http://www.javaworld.com/javaworld/jw-07-2000/jw-0721-hmvc.html)

------
omouse
Switch to an image-based system like Smalltalk or hybrid image/file-based
system like Common Lisp. Seriously, a lot of the headaches of organization
would go away if dev environments were more like Smalltalk.

------
gills
Visitor Pattern. To me it really depends on the context and how many "majigs"
you're going to have, how flexible your application needs to be -- do you need
to leave layers open to other implementations (different view, different
transport, different persistence strategy)? I've gone both ways in the past
with different projects, but if I were identify a rule for myself it would be
that frameworks go the first way (easier to extend or swap components) while
plugins go the second way (self-contained functionality).

If you can handle a larger number of classes you can sort of get around the
question by using a good plugin loader that can associate the proper
Persistamajig or Displayamajig with a particular object at run time.

------
codahale
Oh, and for double-extra bonus points add in the fact that you might have more
than one presenter for a single model -- content type negotiation,
don'tchaknow.

------
triplefox
I can make no conclusive judgement in the example scenario until we're talking
about specific algorithms and data.

