Does anybody know if there is a name for this "pattern" where the
caller of a method can modify the algorithm contained by the method by
passing a set of options? Here's a rough example:
class MyModelTest < Test::Unit::TestCase
def test_default
do_save
end
def test_with_valid_foo
do_save :foo => 'valid_value'
end
def test_with_invalid_foo
do_save :foo => 'invalid_value', :should_fail => true
end
# This method contains a composite algorithm where the caller
# can switch the components on or off
def do_save(options={})
# Set up
model = MyModel.new
if options[:foo]
model.foo = options[:foo]
end
# Call the method
result = model.save()
# Assertions
if options[:should_fail]
assert !result
else
assert result
end
end
end
I see this kind of pattern in Rails for instance, like ActiveRecord's
find() method. It would be nice if there was a name for this so it
could be communicated more effectively.
Moxley
"A facade [..] provides a simplified interface to a larger body of
code [...]" http://en.wikipedia.org/wiki/Facade_pattern
For instance, the Rails "render" method acts as a facade to a bunch of
specialized "render_SOMETHING" methods that may be in totally different
classes than the high-level "render" method.
However, I may be pushing the limits of how facade is defined because
it's supposed to refer to the object, not the method. The trouble is
that the classic patterns were written for languages with limitations
and practices different than those of dynamic languages, and thus don't
necessarily apply very well.
For example, the classic patterns weren't meant to cope with languages
where you would want to pass arbitrary parameters to a method like that.
For example, it's considered reasonable to pass a hash of options to a
Ruby method (e.g., "def render(opts={})", such as "render :partial =>
'thingy'") and let it figure out what to do with them, whereas you'll
likely get fired for doing that if you're a Java programmer because all
arguments must be positional and well-typed (e.g., "public String
render(int type, source String)", used as "String html =
RenderManager.render(RENDER_PARTIAL, 'thingy');").
Anyone else have a better suggestion?
-igal
If you want a term from the traditions of CS to describe it, you might
call it a "poor-man's dynamic dispatch." Of course, multiple dispatch
isn't terribly compatible with "duck typing," and seems to have pretty
much been an evolutionary dead-end from a language design POV -- the
newest language I'm aware of which supported it extensively was Dylan,
which is a perfect example of a language with really sweet ideas,
clean syntax, plenty of corporate support, and absolutely zero change
of succeeding, because it had no "killer app" to drive adoption.
Personally, I find this kind of highly-conditional method to be an
irritation a lot of the time, because it collapses many different
potential behaviors into a single method without the natural
documentation that named parameters provide. The Rails APIs are
especially prone to this model, which is part of the reason I find
myself easily getting lost in Rails code.
<rant>
Eventually, I imagine the entire Rails API will be reduced to a single
method named "run", which accepts a "params" hash supporting nearly
2000 optional key/value pairs, which then dynamically generates and
evaluates all the code for your application from a giant 'case'
statement based on the parameters passed.
</rant>
-Lennon
I feel the same way - which is why I think I may be taking a long look
at merb this summer (I hear the source is a bit easier to digest...)
--
My Rails and Linux Blog: http://offtheline.net