The problem with controllers
karmajunkie.com
karmajunkie.com
The way I've been thinking about it for myself is to imagine your Domain Objects as this 3D space of object relationships and interactions. So a Presenter cuts a 2D plane through that space and let's you view from a certain perspective.
In the case of Commands, you're taking a certain perspective and mutating that 3D space through it.
Not sure if that helps anyone else :-)
Also the focused_controller project looks really interesting as well. I was working on my own web framework, that made Actions first class objects as well. And since it was built on this slick IoC library, your Actions could just declare they need this Command, or these two Services to complete the request and they would automagically get them. I really like the idea of "one object(graph) to represent accomplishing a task", and then just having that object(graph) go do the work.
Complex logic interacts with complex object graphs, not individual models. Therefore, complex logic does not belong in models or controllers (or views). Complex logic belongs in instantated objects (not modules) that represent complex logic. This style may also be known as the "Strategy" Design Pattern.
Strategy objects can have state during their activities, this is why they should be instantiated.
Strategy objects simplify testing because they can be connected with any object graph that presents the same interfaces as the target object graphs.
This leads to interchangable Strategy objects that represent generic behavior which can be applied to actual, simulated or speculative object graphs.
Also check out the DDD/CQRS google group: http://groups.google.com/group/dddcqrs
MVC is a triangle, rails style frameworks are a line. This is called MVA (Model-View-Adapter). The "adapter" being in between the view and the model who can only interact with the adapter and not each other. The second issue is that in adapting MVC to the web, many frameworks continued with the "one controller per view" notion, despite that being done because of the limitations imposed when creating GUI apps. There is no need for multiple controllers in a web app, all input comes in the same way no matter what view the user is seeing. In fact, the user doesn't even need to be seeing a view, there is nothing tying a view to what actions are possible, you can always submit any http request you want. Your "routes" are your controller, there is no need for a second level of controllers on top of that.
The goal of MVC was to expose model functionality to the user directly so they could understand and work with the domain model clearly and easily. Controller meant "controls the input and output" not "controls the users experience". The guy who created MVC considers naked objects style frameworks to be the closest thing to MVC for the web, not rails style MVA frameworks.
And there is something very weird about this statement:
>On top of that, it’s very common to see logic pushed down into the model
Of course that is common, that is what is supposed to happen. Models are not "stupid containers to pretend to kinda represent my DB sorta but not really". Models are the business logic. Models are the actual application. You are modelling the domain, not modelling the database. The model is the domain, it is all the business logic. The view is the way we present information to the user. The controller is the part that handles input and output. Very simple and effective system, but very poorly understood and virtually never used any more.
I'm in 100% agreement WRT to MVC—Rails' idea of MVC was never really MVC as MVC was originally envisioned.
Part of the problem with speaking about domains here (aside from being nonspecific about something that is by its very nature quite specific) is that Rails has an extraordinariliy half-assed approach to domain oriented design (I don't want to use 'DDD' here just to avoid buzzwords). Developers have been told for years to just push it into the model because all the work belongs there, but that's BS. a LOT of the work has no business being there.
Its not a part of your application. You have to connect to facebook over a network to get to it. That data is very clearly NOT a part of your application. Now if a facebook profile is actually a part of your domain in some way, you're going to have a class specifically to manage that. Connecting to the network to update that still isn't a part of that class's responsibility. Look at it this way: if there were someone who knew everything about your problem area, would their knowledge of the behavior of the data include reaching out to facebook and pulling it in over a network connection? almost certainly not, unless your domain is that of a browser. If your domain is something like klout, for example, your domain is going to include concepts like profiles, connections, posts, etc. Its not going to include anything involving Net::HTTP.
As I describe in more detail in my other post, but will put more succinctly and from a different standpoint here: you are confusing the conversation by treating "model" vs. "domain" as if they were equivalent concerns (then to rely on arguments that things outside the domain must be outside the model), while the (possibly quite valuable) school of thought you are invoking puts the "domain" as only part of the model and defines other components that happily include your connections to external state.
The goal of the "model" in MVC is to build an in-application model of outside-application (possibly "real world") state, whether it be a tree of browser bookmarks in folders or a tree of files in filesystem folders or a tree of reports in a command hierarchy; as your application needs to be able to understand these things, it needs to model them.
In an ideal world, your model presents a reasonably abstract rendition of the thing that you are modeling (so that you will be able to reuse views and controllers for anything that is sort of tree-like), however you may also be modeling something very particular to your application, in which case you will have a rather convoluted one-off model.
Now, to be clear, I'm not disagreeing with your suggestion of how to structure the logic of your application: having a bunch of data that is manipulated by connections to external systems can make a lot of sense; however, when "domain oriented design" is talked about, AFAIK the entire purpose is to decide how to internally structure your model, taking it as a given that, from an MVC perspective, that is where all of these behaviors and state are supposed to be kept.
http://blog.fedecarg.com/2009/03/11/domain-driven-design-and...
> Domain-driven design separates the model layer “M” of MVC into an application, domain and infrastructure layer. The infrastructure layer is used to retrieve and store data. The domain layer is where the business knowledge or expertise is. The application layer is responsible for coordinating the infrastructure and domain layers to make a useful application.
It's worth noting that as originally envisioned, the controller directly dealt with the keyboard and mouse. I would argue that not only is Rails not MVC as originally envisioned, something that reanimated the original controller would probably suck.
MVC as done in Cocoa on the other hand, is really good. Stock, reusable controllers that simply mediate communication between models and views. If any MVC-style web framework had something like this, it would be pretty amazing.