I like using command objects as the ‘crux’ of my controllers. They encapsulate behavior without making models or controllers thick.
I think of commands as reactions to a signal (event). To produce a command I think first of the signal it is responding to. Let’s use an example:
class WidgetController < ApplicationController
# We're assuming there's sufficient complexity in publishing
# a widget to warrant a command.
def update
publish_command.execute(params[:widget]) if params[:publish]
end
private
def publish_command
Widget::PublishCommand.new(WidgetParamsParser.new)
end
end
The ‘signal’ that WidgetController emits is ‘Publish the widget’. It sends the only thing which is topical to this signal, the widget in question. This is a contextual dependency.
The command inverts control, passing it a parameter parser that knows how to deal with the representation used. This is a constructional dependency. In this particular case, I think it would be preferable to extract the builder for the PublishCommand because it’s no concern of the controller’s. Constructional dependencies have nothing to do with the signal.
I make the distinction between constructional and contextual dependencies so that I can communicate the intent of the command more clearly. By default I place constructional dependencies in the initialize method, or I define getter/setter dependencies, often with a clear default.
Another approach to construction injection defaults is highlighted here.
If we used some kind of orthogonal dependency injection framework, we could define a container that configures the common constructional dependencies for us. But that’s a topic of another post 😀
For completeness, here’s a stub of Widget::PublishCommand
module Widget
class PublishCommand
def initialize(representation_parser)
@representation_parser = representation_parser
end
def execute(widget_representation)
normalized_widget =
@representation_parser.parse(widget_representation)
# complex stuff with widgets here
end
end