Hacker News new | ask | show | jobs
by tomblomfield 4476 days ago
I agree with this. Statements like "you can only have one line per controller action" are just dogma. What's the point of a controller?

I also don't like ceding control-flow from the controller into the application by injecting the controller context in the form of "rails_adapter", in the name of "Tell, don't ask". It seems like a misunderstanding of the principle.

"As the caller, you should not be making decisions based on the state of the called object that result in you then changing the state of the object. The logic you are implementing is probably the called object’s responsibility, not yours."[1]

Say you have a module that performs some complex business logic: ShipOrder.perform(args). It's responsibility might be to ensure the right items are combined into a package and shipped. It might write some logging data to an injected logging object. It might tell a label-printing to output the right address label. Ultimately, it should succeed or fail, and pass that information back to the caller.

The controller's responsibility, on the other hand, is to direct the control-flow of the request and pass data between models & views (and your other non-model POROs). That's its core responsibility. Passing the controller context into your application object so the application can call-back methods on the controller just seems like a recipe for spaghetti code.

It also means you can't use this object on its own, or composed with other objects, without implementing a complex caller-object that you can pass in to receive the callbacks. If the object just returns success/failure, and exposes a limited API so you can access its internal state if required, it becomes straightforward to re-use & compose the object in places outside the confines of your controller.

1. http://pragprog.com/articles/tell-dont-ask

2 comments

Yeah I agree. I'd be interested to see what that `rails_adapter` implementation looks like. In my experience, this sort of design often just moves a lot of the tricky questions about how to pass data around to the adapter instead of the controller.

Doing rendering based on the application telling the adapter what happened does seem to work pretty well though.

Hi Tom

I have to disagree, by returning a value and switching on it, not only are you querying state but you risk repeating the query code all over the place.

My approach allows you to write a small adapter for your delivery mechanism and use polymorphism to eliminate conditions and duplication.

Most objects cannot be used on their own as they have collaborators. My design allows me to write a trivial console adapter that can puts the results of my service object / interactor.