Name that pattern

1 view
Skip to first unread message

Moxley Stratton

unread,
Jun 14, 2008, 2:28:29 PM6/14/08
to PDX Ruby
Hi,

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

Igal Koshevoy

unread,
Jun 14, 2008, 4:39:09 PM6/14/08
to pdx...@googlegroups.com
Moxley Stratton wrote:
> 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:
>
In terms of the Gang of Four design patterns, this seems closest to
"Facade":

"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

Lennon Day-Reynolds

unread,
Jun 14, 2008, 6:24:11 PM6/14/08
to pdx...@googlegroups.com
I agree that the Gang of Four patterns don't really describe this
well, because it's closely tied to language semantics, and in
particular, semantics that don't exist in the C++ or Java worlds.

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

Jason LaPier

unread,
Jun 14, 2008, 9:21:01 PM6/14/08
to pdx...@googlegroups.com
On Sat, Jun 14, 2008 at 3:24 PM, Lennon Day-Reynolds <rco...@gmail.com> wrote:
>
> 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.
>


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

Bill Burcham

unread,
Jun 16, 2008, 3:58:09 PM6/16/08
to pdx...@googlegroups.com
Interfaces like the one you describe Moxley, are discussed in Gregor Kiczales' (father of CLOS, father of AOP) 1996, Open Implementation Design Guidelines er, password required, unff, sorry.

Anyhoo, Kiczales uses traditional operating systems problems like "how can you know when designing the OS, which cache policy will work best for all applications?". His answer was to answer "Mu" (unask the question) and instead let the application (client) decide. This involved letting policies be "open" in his parlance, and run in user space—with the (kernel) OS calling out to those when needed.

To me, the sort of extreme decomposition in the C++ Standard Template Library, in particular, the way it decouples algorithms from collections is an example of something similar. It's about separation of concerns, and separation in non-obvious ways.

Kiczales points out that without "open" interfaces, systems grow "hematomas" which are clumps of logic that embody inappropriate knowledge of foreign subsystems. These hematomas often result from folks "coding between the lines", that is, writing (client) code that does subtle, often hard to understand, often ineffective and brittle, stuff based on undocumented behavior of a foreign subsystem. So for example if you just know that on a particular OS, a certain cache is LRU and you optimize your code for that case, even though the policy is out of your control and not even documented, then he'd call that "coding between the lines" and the resultant code would be a "hematoma".

This thinking on Open Interfaces was the precursor to his work on Aspect-Oriented Programming.


Reply all
Reply to author
Forward
0 new messages