Yehuda Katz is a member of the Ember.js, Ruby on Rails and jQuery Core Teams; his 9-to-5 home is at the startup he founded, Tilde Inc.. There he works on Skylight, the smart profiler for Rails, and does Ember.js consulting. He is best known for his open source work, which also includes Thor and Handlebars. He travels the world doing open source evangelism and web standards work.

AbstractQueryFactoryFactories and alias_method_chain: The Ruby Way

In the past week, I read a couple of posts that made me really want to respond with a coherent explanation of how I build modular Ruby code.

The first post, by Nick Kallen of Twitter, gushed about the benefits of PerQueryTimingOutQueryFactory and called out Ruby (and a slew of other “hipster” languages) for using language features (like my “favorite” alias_method_chain) and leveraging dynamicism to solve problems that he argues are more appropriately solved with laugh-inducing pattern names:

In a very dynamic language like Ruby, open classes and method aliasing (e.g., alias_method_chain) mitigate this problem, but they don’t solve it. If you manipulate a class to add logging, all instances of that class will have logging; you can’t take a surgical approach and say “just objects instantiated in this context”.

If you haven’t read it yet, you should probably read it now (at least skim it).

As if on cue, a post by Pivot Rob Olson demonstrated the lengths some Rubyists will go to torture alias_method_chain to solve essentially the same problem that Nick addressed.

In short, while I agree in principle with Nick, his examples and the jargon he used demonstrated exactly why so few Rubyists take his point seriously. It is possible to write modular code in Ruby with the same level of flexibility but with far less code and fewer concept hoops to jump through.

Let’s take a look at the problem Rob was trying to solve:

module Teacher
  def initialize
    puts "initializing teacher"
  end
end
 
class Person
  include Teacher
 
  def initialize
    puts "initializing person"
  end
end
 
# Desired output:
# > Person.new
# initializing teacher
# initializing person

This is a classic problem involving modularity. In essence, Rob wants to be able to “decorate” the Person class to include teacher traits.

Nick’s response would have been to create a factory that creates a Person proxy decorated with Teacher properties. And he would have been technically correct, but that description obscures the Ruby implementation, and makes it sound like we need new “Factory” and “Decorator” objects, as we do, in fact, need when programming in Java.

In Ruby, you’d solve this problem thusly:

# The base person implementation. Never instantiate this.
# Instead, create a subclass that mixes in appropriate modules.
class AbstractPerson
  def initialize
    puts "Initializing person"
  end
end
 
# Provide additional "teacher" functionality as a module. This can be
# mixed into subclasses of AbstractPerson, giving super access to
# methods on AbstractPerson
module Teacher
  def initialize
    puts "Initializing teacher"
    super
  end
end
 
# Our actual Person class. Mix in whatever modules you want to
# add new functionality.
class Person < AbstractPerson
  include Teacher
end
 
# > Person.new
# Initializing teacher
# Initializing person

Including modules essentially decorates existing classes with additional functionality. You can include multiple modules to layer on existing functionality, but you don’t need to create special factory or decorator objects to make this work.

For those following along, the classes used here are “factories”, and the modules are “decorators”. But just as it’s not useful to constantly think about classes as “structs with function pointers” because that’s historically how they were implemented, I’d argue it’s not useful to constantly think about classes and modules as factories and decorators, simply because they’re analogous to those concepts in languages like Java.

The Case of the PerQueryTimingFactoryFactory

Nick’s example is actually a great example of a case where modularity is important. In this case, he has a base Query class that he wants to extend to add support for timeouts. He wrote his solution in Scala; I’ll transcode it into Ruby.

Feel free to skim the examples that follow. I’m transcoding the Scala into Ruby to demonstrate something which you will be able to understand without fully understanding the examples.

class QueryProxy
  def initialize(query)
    @query = query
  end
 
  def select
    delegate { @query.select { yield } }
  end
 
  def execute
    delegate { @query.execute }
  end
 
  def cancel
    @query.cancel
  end  
 
  def delegate
    yield
  end
end

Then, in order to add support for Timeouts, he creates a new subclass of QueryProxy:

class TimingOutQuery < QueryProxy
  def initialize(query, timeout)
    @timeout = timeout
    @query   = query
  end
 
  def delegate
    begin
      Timeout.timeout(@timeout) do
        yield
      end
    rescue Timeout::Error
      cancel
      raise SqlTimeoutException
    end
  end
end

Next, in order to instantiate a TimingOutQuery, he creates a TimingOutQueryFactory:

class TimingOutQueryFactory
  def initialize(query_factory, timeout)
    @query_factory = query_factory
    @timeout = timeout
  end
 
  def self.call(connection, query, *args)
    TimingOutQuery.new(@query_factory.call(connection, query, *args), timeout)
  end
end

As his coup de grâce, he shows how, now that everything is so modular, it is trivial to extend this system to support timeouts that were per-query.

class PerQueryTimingOutQueryFactory
  def initialize(query_factory, timeouts)
    @query_factory = query_factory
    @timeouts = timeouts
  end
 
  def self.call(connection, query, *args)
    TimingOutQuery.new(@query_factory.call(connection, query, *args), @timeouts[query])
  end
end

This is all true. By using factories and proxies, as you would in Java, this Ruby code is modular. It is possible to create a new kind of QueryFactory trivially.

However, this code, by tacking close to vocabulary created to describe Java patterns, rebuilds functionality that exists natively in Ruby. It would be equivalent to creating a Hash of Procs in Ruby when a Class would do.

The Case: Solved

Ruby natively provides factories, proxies and decorators via language features. In fact, that vocabulary obscures the obvious solution to Nick’s problem.

# No need for a proxy at all, so we skip it
 
module Timeout
  # super allows us to delegate to the Query this
  # module is included into, even inside a block
  def select
    timeout { super }
  end
 
  def execute
    timeout { super }
  end
 
  # We get the cancel delegation natively, because
  # we can use subclasses, rather than separate
  # proxy object, to implement the proxy
 
private
  # Since we're not using a proxy, we'll just implement
  # the timeout method directly, and skip "delegate"
  def timeout
    # The Timeout module expects a duration method
    # which classes that include Timeout should provide
    Timeout.timeout(duration) do
      yield
    end
  rescue Timeout::Error
    cancel
    raise SqlTimeoutException
  end
end
 
# Classes in Ruby serve double duty as "proxies" and
# "factories". This behavior is part of Ruby semantics.
class TimingOutQuery < Query
  include Timeout
 
private
  # implement duration to hardcode the value of 1
  def duration
    1
  end
end
 
# Creating a second subclass of Query, this time with
# per-query timeout semantics.
class PerQueryTimingOutQuery < Query
  TIMEOUTS = Hash.new(0.5).merge("query1" => 1, "query2" => 3)
 
  include Timeout
 
private
  def duration
    TIMEOUTS[query]
  end
end

As Nick would point out, what we’re doing here, from a very abstract perspective, isn’t all that different from his example. Our subclasses are proxies, our modules are decorators, and our classes are serving as factories. However, forcing that verbiage on built-in Ruby language features, in my opinion, only serves to complicate matters. More importantly, by starting to think about the problem in terms of the Java-inspired patterns, it’s easy to end up building code that looks more like Nick’s example than my solution above.

For the record, I think that designing modularly is very important, and while Ruby provides built-in support for these modular patterns, we don’t see enough usage of them. However, we should not assume that the reason for the overuse of poor modularity patterns (like alias_method_chain) result from a lack of discussion around proxies, decorators, and factories.

By the way, ActionController in Rails 3 provides an abstract superclass called ActionController::Metal, a series of modules that users can mix in to subclasses however they like, and a pre-built ActionController::Base with all the modules mixed in (to provide the convenient “default” experience). Additionally, users or extensions can easily provide additional modules to mix in to ActionController::Metal subclasses. This is precisely the pattern I am describing here, and I strongly recommend that Rubyists use it more when writing code they wish to be modular.

Postscript: Scala

When researching for this article, I wondered why Nick hadn’t used Ruby’s equivalent to modules (traits) in his examples. It would be possible to write Scala code that was extremely similar to my preferred solution to the problem. I asked both Nick and the guys in #scala. Both said that while traits could solve this problem in Scala, they could not be used flexibly enough at runtime.

In particular, Nick wanted to be able to read the list of “decorators” to use at runtime, and compose something that could create queries with the appropriate elements. According to the guys in #scala, it’s a well-understood issue, and Kevin Wright has a compiler plugin to solve this exact problem.

Finally, the guys there seemed to generally agree with my central thesis: that thinking about problems in terms of patterns originally devised for Java can leave a better, more implementation-appropriate solution sitting on the table, even when the better solution can be thought of in terms of the older pattern (with some contortions).

44 Responses to “AbstractQueryFactoryFactories and alias_method_chain: The Ruby Way”

This is kind of exactly what we described in a paper recently: http://github.com/rkh/papers/blob/master/bithug/bithug.tex#L134

interesting post, i’ve never really done a lot of java, but from what i have seen/done, factories have always seemed like a bit of overengineering to me.

i’m curious, in the first section, what are the benefits of using “include Teacher” in a Person object instead of creating a full-fledged Teacher object that inherits from a Person? i know it’s just an example, but with those nouns, i would have assumed an implementation like:

class Person
def initialize
puts “person initialization”
end
end

class Teacher < Person
def initialize
super
puts "teacher initialization"
end
end

perhaps it's just the nouns, but the first section kind of obscures the benefit of modules to me.

thanks for all the food for thought!

I made a similar argument in my response to Nick’s article. Although I still advocate using decorators over module inclusion in most scenarios in Ruby. Decorators in Ruby are absurdly simply with the standard SimpleDelegator/DelegateClass bases, and they have a couple of advantages. They are completely noninvasive – I can wrap an object in a decorator for my own use, without changing the object for any other clients which might have a reference to it. And Decorators get their own instance variable namespace, which means less opportunity for accidentally stomping on the decorated class’s variables.

Excellent, Yehuda. The language of OOP can be intimidating to the novice; it’s great to see examples of big concepts described and implemented in straightforward ways.

The patterns you are using here and in Rails 3 will be reflected in the code of the next generation of Rubists.

The problem with delegators is that they aren’t transparent, and coercion semantics wrt method_missing aren’t clearly defined, so I tend to shy away from using them. Maybe if there was a TransparentProxy class that shipped with Ruby I’d feel better about it.

@Avdi Unless I’m mistaken it is because DelegateClass uses an anonymous Class.new that breaks anywhere someone is using #is_a?() instead of #responds_to?() to check for behavior? Tempfile not being an IO or File subclass probably causes confusion from time to time.

Modules are fine for extending functionality though I do think a a delegate class would work well in Wycats example unless AbstractPerson truly is abstract without the Teacher functionality.

@moonmaster9000 I agree with you in this example. I was using the example from Rob’s original post. It would be more reasonable if the module was called Teacherish, and there were other modules like Athletic, Speedreads, and so on.

Well posted, sir!

I think I learn more from reading your blog than the rest of my rss aggregator as a whole. Keep up the good work, it’s posts like this that keep me ambitious about improving my own code.

~Ethan

I agree with you that Ruby is much more flexible than java and some of the patterns are kinda built-in on the language. Module as decorators, classes as factories, etc.

But I also understand Nick Kallen because patterns are at concept level and not at implementation level. A factory doesn’t need to have the same implementation than Java requires, it needs to creates objects easily and in a way that can be customized and enhanced through other techniques such as decoration or inheritance. Design patterns originally didn’t come from Java. Conceptually, they came from Smalltalk and evolved through the years and literature started focusing on Java because of it’s large adoption.

So I don’t feel like using the patterns name is wrong at all. Of course, people that are not used with patterns would not really know what you’re referring to and some people that did Java all their life will probably try to code Java in Ruby. But doesn’t that already happen? At least you would be requiring people to learn something ;)

I’m not saying that every pattern applicable to Java is or should be applicable to Ruby. But I do think that if most of the Rubyists were familiar with patterns and how to do it properly in Ruby, taking the most out of the language, we would probably have a lot of more good modular software out there.

Anyway, I certainly understand your point of view too so don’t take this as I’m opposing to you. It’s just my 2 cents :)

In my opinion, Ruby (and other languages like Scala in some cases) exposes some new patterns that are worth evaluating on their own. For instance, traits are different enough from the generic idea of decorators that they deserve their own name. Similarly, a class object that serves as its own factory is different enough from the general idea of abstract factories that it deserves its own name. Once these things are in the repertoire, it becomes significantly easier to think about these problems in terms of the more powerful features available.

Ok, I agree. I don’t think people should start calling Ruby classes as Factories ;)

What I meant is that even though we don’t need factories, or decorators, etc., people should learn and know they are equivalent, meaning they can achieve the same thing with similar or better quality/modularity.

Also, aside these patterns in specific, there are a lot of other interesting patterns that can be used in Ruby too and there are also Ruby-specific patterns.

Anyway, what I meant for real is that Ruby people should also learn and know patterns and don’t assume they are only necessary in Java. People should not think of factories as it’s named but as what it represents, or observers, or strategy, etc. These comes naturally to a code master but writing good software is not that easy to beginners.

Good post, it was interesting reading Nick Kallen’s original post, and the responses that followed.

One thing I’d like to add is that certain design patterns are generally good ideas to keep around and use judiciously, regardless of what names they may carry, and even if they add some boilerplate / chrome. Why? Because structuring your code into certain patterns can make it more legible and easier to understand for someone else coming along. You may be able to write some really neat, terse code through clever use of modules, reflection, symbol logic, lambdas, etc, but if the final result isn’t easily understandable by someone else (or yourself in 10 months), then it isn’t worth much.

In this particular example I tend to side with Nick Kallen. Thinking about certain classes as factories and certain methods as decorators makes it clear what their intended functionality is. If you see a design pattern in code, you immediately know what it’s supposed to be doing. Overloading language features to meet these needs (as you’ve demonstrated by using subclasses as proxies, modules as decorators, and classes as factories) may obscure things. For example, subclasses may be used to enhance existing behavior (as a proxy would), but they can also be used to override existing behavior, or add extra behavior (as a proxy wouldn’t). Using a decorator pattern ought to make it clear that you’re enhancing behavior, using subclasses probably wouldn’t.

@toby so you’d use the code that I converted to Ruby from Java?

> Using a decorator pattern ought to make it clear that you’re enhancing behavior, using subclasses probably wouldn’t

Isn’t that the entire point of subclasses?

Nice writeup Yehuda!

Sandi’s talk on OOP at Gotham Ruby 09 and your writing on how Rubyists sometimes forget about this whole subclassing & modules thing makes me look for those things whenever I’m reviewing code.

Of particular interest to me in this article is this bit:

# super allows us to delegate to the Query this
# module is included into, even inside a block
def select
timeout { super }
end

I wasn’t sure how this was working and had to root around for a reference like this: http://practicalruby.blogspot.com/2007/03/super-accesses-inaccessible.html

For the clarity of other readers, what’s happening here is that when the SubQuery includes the Timeout module, an anonymous, inaccessible ninja class with the module’s constants, class variables, and instance methods is created and is slipped into the SubQuery’s ancestry chain, so this happens:

SubQuery.ancestors.inspect # => “[SubQuery, Timeout, Query, Object, Kernel]”

When a SubQuery instance calls #execute, it can’t find it in SubQuery, so it looks in the anonymous, inaccessible ninja Timeout class. The method is found there, and when it calls `super`, we can see from looking at SubQuery’s ancestors that the superclass of “ninja SubQuery” is Query, so that’s where Ruby starts looking for a method definition for #execute next.

The point of subclasses is to specialize. The point of decoration is to *add* potentiall orthogonal behavior. The new behavior may have been unanticipated by the original class author, and may reflect a different concern (“aspect”) entirely. For instance, wrapping a model object in a HTML Presenter decorator. The presenter knows how to render various attributes of the underlying object in an HTML-friendly way, a behavior which may be specific to certain clients (there could be more than one way to render that object’s attributes as HTML) and which certainly does not belong in the model class itself. You wouldn’t create an HtmlModel subclass to do this, nor (I hope) would you mix an HtmlRenderable module into the original class (what if some other part of the app has a different idea of rendering?). Two different techniques for two different scenarios.

By the way, I agree that traits is a sufficiently novel concept that it deserves to be discussed under it’s own name. I’m less convinced that class-as-factory is worth differentiating, it seems like a trivial variation from the original Factory pattern to me. I would make a new name for “FactoryCallable” (as illustrated in my post) before I’d make one for class-as-factory.

@avdi why wouldn’t you create a UserPresenter subclass and mix the desired behavior in? If the answer is: ActiveRecord doesn’t handle calling #find on a subclass well, I say that’s ActiveRecord failing to manage dependencies correctly.

I gotta give you props for being very diplomatic in this post Yehuda. The original post had a touch of flamebait to it, two ridiculous implications being A) dynamic languages can’t do modularity as well as Java and B) the reason many people dislike Java is because things are designed so amazingly flexibly.

Whereas a fair critique along the same lines might have been to say that the Java ecosystem is more mature and the methods for setting up highly modular systems are more widely employed, so things tend to be more pluggable out of the box.

For anyone who actually knows Ruby–which Nick Kallen ostensibly does–it’s ridiculous to act like Java has some secret sauce that dynamic languages don’t. The reason I don’t like Java is all about how weak it is semantically, which is a completely orthogonal concern to the architectures that are built. You can build exactly the same architecture in Ruby, and usually with considerably *more* flexibility, simply because the Ruby primitives are more powerful (and I’m talking purely about Classes and Modules, not monkey-patching or alias_method_chain). The fact that Rubyists haven’t always written enterprise-level modularity into their code is just a function of the amount of total development done in Ruby to-date. Java certainly didn’t start out the way it is today. And Rails 3 is a brilliant example of how Ruby code can become dramatically more modular without baroque architectures where the need arises.

Java was a response to C++, and it showed the enterprise programming world that a simpler, higher-level, garbage-collected language was viable in the real-world. That is no small feat. However trying to paint a picture of Java as being technically superior to other high-level languages is just grasping at straws.

I am not so sure there is a beneffit in learning Java design patterns. Current design patterns are solutions for problems that don’t exist in Ruby or are better solved using Ruby specific features (as Yehuda demonstrated).

> People should not think of factories as it’s named but as what it represents, or observers, or strategy, etc

Patterns represent solutions, but by definition these solutions assume a set of features in their templates, more especifically, static language features.

Instead of trying to port Java patterns to Ruby (which can lead to “impedance mismatch” problems), I think it is bettter to elaborate the solution in the Ruby universe. The languages are so different that we need almost a complete different set of patterns.

@wycats

In this particular instance, your implementation makes more sense than the “Java” implementation. It depends on context, however. With factories, you could have external configuration determine which class actually gets instantiated, at runtime. Without factories, you’re locked to whatever class you use when you call Class.new. In this example, suppose you want to use the timing out queries by default, but when debugging a problem, you want to turn them off. With configurable factories, you just change the configuration (via file, system property, database, whatever). With classes, you’d have to actually go change the code that instantiates the new classes. Obviously, there are elegant solutions to doing this in Ruby that don’t involve as much factory boilerplate, but the point stands.

>> Using a decorator pattern ought to make it clear that you’re enhancing behavior, using subclasses probably wouldn’t

> Isn’t that the entire point of subclasses?

I probably didn’t sufficiently clarify. With a subclass, you can either add new methods, or change the behavior (but not signature) of existing methods. Changing the behavior can mean you’re either fundamentally altering what the function does (e.g. you *could* change an increment method to decrement instead), or that you’re enhancing the method by adding extra behavior without changing the core functionality. In the query example, the core query behavior remains the same, there’s simply some timeout functionality wrapped around that behavior. You could also wrap some logging or caching functionality in a similar fashion. This differentiation between enhancing and altering behavior is what I’m trying to point out – a proxy or delegate would only enhance behavior, but never alter it.

The decorator pattern generally means that you will still call the underlying method you’re enhancing, you’re just “decorating” that call with some extra functionality. Subclassing alone doesn’t imply such semantics.

(Why do I always end up arguing semantics)

@wycats It has nothing do with AR, it has to do with separating concerns. The more concerns you cram into one object the more potential for developer confusion, namespace clashes (two concerns fighting over the same method/variable name), and other unexpected interactions. And if you’re using UserPresenter.find() (assuming you’ve addressed the AR issues you mentioned; I wouldn’t know, haven’t used AR in a while), that means *every* collaborator of that object gets to interact with the larded-down mashup of an object even if it doesn’t give two shits about HTML, or wants to do its own custom rendering.

Better to separate concerns by wrapping the object with functionality where it is needed and wanted, and leaving the underlying object do one thing well: represent a domain entity.

@avdi all right I can buy that. If you have a single object with potentially several uses, you might want to decorate it differently for those uses. That said, this is just another example of a case where first-class features (like object “views”) would change the ballgame by making first class something that requires a bunch of boilerplate now.

Your point is that the vocabulary of 90s patterns provides a good baseline for us to communicate with each other. My point is that thinking in terms of those patterns can obscure good solutions that make sense in terms of newly discovered patterns. I’m not merely arguing that semantically Ruby makes it easier to implement Nick’s example. I’m arguing that Nick’s implementation is actually *wrong* for Ruby, because there are better patterns available that change our choices.

@hique so you’re saying that none design pattern used in the java world is applicable to ruby’s world? What about observers, strategies, singleton, proxy?

Remember all of these are used in Rails, for exemple. They are not called that way but they are used. So, again, design patterns are not Java specific and they are concepts, not implementation.

Creating a Factory object for creating regular objects doesn’t make sense because Ruby’s classes are factories. But if you have a complex enough business logic that requires you to dynamically build a complex object depending on dynamic data, then you’ll probably need a complex factory object. They’re both factory, and have different implementations.

@wycats Oh, now I agree with you. I’m not defending the old 90s patterns, I’m defending the use of patterns and naming them so that people can learn and communicate better.

@wycats More pointedly, by using what I will here continue to refer to as a mixin mashup object, you assert that if any subcomponent of the application desires a certain extra behavior from User object, every callsite which creates/finds a User object must now be changed to instantiate the new UserWithExtraCheese class instead. Or, some central OmnibusUser class must have a new include added to it. When a single new behavior in one subsystem requires a global change to the program, that’s pretty much the canonical violation of the Single Responsibility Principle.

Using inheritance and classes is a wonderful way to achieve modularity. You can also use proxies and objects with a #new method. What do both of these techniques have in common? They’re Factories and Decorators! That’s why we have the name, because there are several concrete realizations of the same abstract thing.

And you mistakenly trivialize the distinction between composition vs. inheritance. But let me focus on a few things that I find distasteful about your implementation, which to me means that what you’ve done is not the one “ruby” way to do it.

Consider this line: `private :duration`. Woah nelly! You now have defined a formal interface as a private method!

class FastTimingOutQuery < …
def duration
1.second
end
end

class SlowTimingOutQuery < …
def duration
5.seconds
end
end

Chrome? Awkward interface for extension? Check and check.

In the proxy example, the equivalent is `TimingOutQueryFactory.new(qf, 1.second)` … The interface for extension is clearer because it is simply a parameter. (This, I think, also draws out the similarity between currying and factory methods, a subject for another discussion).

One step further. Assume that making new queries is expensive and we want to have only one of each. I claim that using inheritance would be awkward. Here's the elegant way to do it as an explicit memoizing factory:

class MemoizingQueryFactory < …
def initialize(query_factory)
@memo = Hash.new { |h,k| h = query_factory.new(*k) }
end

def call(connection, query, *args)
@memo[connection, query, args]
end
end

But how would you do this with inheritance?

class MemoizedTimingOutQuery
include Timeout
extend Memoize
end

module Memoize
… # I leave the implementation of this as an exercise to the reader because it is filled with delight.
… # (And just try expanding this module to take parameters, like an upper-bound on the size of the hash.)
end

So, where have we arrived with all this? With the indisputable, unassailable, 100% correct, absolutely scientific, four out of five rubyists agree that inheritance and composition are both valid ways of achieving the same thing, namely Decorators and Factories; and that even in Ruby both composition and inheritance are useful and it's not the case that inheritance is universally the way to do it in Ruby; and thus it is not the case that these things just disappear into language features except in simpler examples.

Does it come down to preference? Yes and no. Proxies and explicit Factory objects are probably more straightforward for everyone's taste to do Memoization–mostly objective. But I also feel a little dirty when my parameterization technique is `def timeout; 1.second; end`–mostly subjective. Is one more chrome than the other? If you ignore my (unnecessary in this simple example) abstract proxy (with `#delegate`, etc.) the only difference is that I have Factory objects and you don't. You win a little battle, but given the memoization issue, I think you've lost the war.

But, check this, I'm about to lay down something neat. Proxies are just an object graph. If you expose appropriate methods, you can traverse them. You can pick them apart. You can reorder them. You can re-combine them. Sound like something you'll never want to do? Yes, sounds like — until you actually need to do it. With proxies it's easy! Just do it.

What would you do with inheritance? Start mucking around with the ancestor chain? Good luck bro.

Anyway, delightful article Wycats.

@avdi what?

In Nick’s example, he creates a special factory to return a decorated TimingOutQuery. If he wants to change the TimingOutQuery to a TimingOutQueryWithExtraCheese, he needs to go to the places that used the TimingOutQueryFactory and replace it with a TimingOutQueryWithExtraCheeseFactory. When using decorators, you’re still forced to create a concrete class that has the decorations — whether it’s a subclass or a decorator wrapper doesn’t change that.

Hmmm, you can ignore that last, I see you got the point the first time.

I’m not against new terminology, but I am a little more conservative when it comes to identifying things as new. For instance, it makes sense to me to say to a programmer from a $blub background “in this context the User class itself is acting as a Factory object”. Since it doesn’t really make sense to have separate Factory classes in Ruby, to me that doesn’t say we need a new term; it says that using the class object IS the canonical implementation of Factory in Ruby.

Of course, some concepts, like traits, don’t map as well. Although I think explaining traits in terms of composition-and-delegation is a good way to introduce programmers to them.

@avdi I don’t really have a problem introducing non-Rubyists to Ruby concepts in terms of concepts that are more at home in other languages. However, I do have a problem with encouraging experienced Rubyists to *think* in terms of factories. Making a class its own factory (by making it an object) simplifies the concepts, making it easier to think about the *rest* of the problem (the domain-specific questions of modularity).

When thinking about modularity, I like to be able to devote my full attentions to asking questions like: “what are the dependencies here?” “how should I decouple them?” rather than “how should I implement the factory pattern?”

@wycats, something that’s occurred to me in the process of this discussion is that a pattern remains useful so long as its antipattern is still readily apparent. For instance, I’ve seen a *lot* of tightly class-coupled Ruby code, possibly as a result of the ease of stubbing #new in Ruby mock frameworks. This tells me that it’s still useful to teach Rubyists Dependency Injection as an explicit pattern, because they clearly aren’t being led by the language to just do it anyway.

Likewise, the amount of HTML I’ve seen in Rails models tells me that it’s still useful to teach Presenter as an explicit pattern. And more generally, Decorator for cases of orthogonal concerns.

On the flip side, most Rubyists have grasped #each pretty well, so the explicit concept of Visitor (over external iteration) has less currency.

And I *DO* think that it’s useful to encourage Rubyists to think of Factories as separate entities, because I think the class-as-factory implementation is actually somewhat limiting. When you think of the class as the one and only object which gives birth to new objects of that class, you tend to still bind the code a little closely to the class.

So you’re passing the class object in instead of explicitly referencing the class. Great. But you’re still calling #new on that passed-in class, which says to me that you’re still thinking in terms of classes being the only things which give birth to new objects, via the method “#new”. Whereas if you’re thinking in terms of a Factory, a completely separate object which can give you an object of the type you are looking for, you realize that you don’t even care about getting a new object, or talking to a Class – you just want AN object which satisfies your contract, whose lifecycle is non of your concern. From which point you can then make the jump to passing in an arbitrary callable THING, which will give you back an object which may or may not be new.

I’m sorry, that was a bit rambly. I hope I got my point across, which is that thinking in terms of Factories actually helps you conceptually graduate from the “I need a class to create a new object” model to the “I just need something which will give me an object” model.

As for avoid the X.seconds hard-coding, you can always “inject” (I’m not a fan of the DI term either) the value, instead of hard-coding it by having a mutator on the factory, or whatever the hell you guys agree to eventually call it, of choice.

There. No hard coding.

Hell, if you want to specify units, just inject a hash with :value => X, :units => :seconds. and do “value.__send__(:units, params[:value]).

Great article, Yehuda. Minor nit: “I wondered why Nick hadn’t used Ruby’s equivalent to modules (traits) in his examples” should probably read “Scala’s equivalent …”.

To be fair, Rob’s approach to writing the module was in the context of it being packaged in a gem, which isn’t clear from his post. Rather than placing constraints on how an end-user structured their code he wanted it to just work when the module was included. See his follow up.

Not a bad illustration of the concepts involved! Certainly a worthwhile read.

I find that often situations where a Factory is “needed” – even in the Rubyfied form Yehuda presents – are the result of a more fundamental design failure. Not always, of course, but finding yourself in that spot should force a hard look at your design and the assumptions that lead you there.

A short while ago I found myself working out a mechanism for an object to transform into a more specialised kind (consider a Person that at some later point would “become” a Teacher) and went through the steps of considering explicit transformation, proxy objects, extending Modules and so on. Eventually, though, the nagging feeling won out and re-evaluation turned out that one of my basic decisions just was not right and that the transform was unnecessary.

And finally @Edward, I am not sure if it is really necessary to think about the “hidden ninja class” effect that including/extending a Module creates. I can see the value in approaching it that way, but conceptually the situation is reversed: a Class is a special kind of a Module. Subclassing is inclusion. Conversely, including a Module is another way of defining inheritance…the end result of both is a hierarchical template for the behaviour and data of an Object.

This seems to be a rediscovery (or re-telling) of what Neal Ford has been saying for a few years now:

http://github.com/nealford/presentations/raw/master/Design%20Patterns%20in%20Dynamic%20Languages%20(Neal%20Ford).pdf

Basically, as we go up to higher levels of abstraction/power in our languages, we don’t need some of the patterns of previous levels. Just like we no longer think of subroutines as patterns (as we did in assembler — http://en.wikibooks.org/wiki/Embedded_Control_Systems_Design/Design_Patterns#Subroutines). Or how we don’t need any patterns for dealing with pointers or array bounds checking that are best practices in C.

Great post. super and modules are underused.

@Toby:
>I probably didn’t sufficiently clarify. With a subclass, you can either add new >methods, or change the behavior (but not signature) of existing methods. Changing >the behavior can mean you’re either fundamentally altering what the

I’ve been known to do it, especially with initialize. The language doesn’t stop you, you just cannot use a bare super.

class A
def initialize
puts “Hi mom”
end
end
class B < A
def initialize(name)
puts "#{name} says:"
super()
end
end

Another good presentation on patterns in dynamic languages: http://norvig.com/design-patterns/ppframe.htm

I don’t understand why this needs to be so complicated. Can someone explain why this solution isn’t acceptable?

http://gist.github.com/331204

Great post, thanks! Unless I’m mistaken though, Nick’s solution which uses the decorator pattern allows you to chain several such decorators together. Wrapping the query, for example, both with a timeout and a retry mechanism for example. So you could do something like new RetryQuery(new TimeoutQuery(query, 30)). However, if you tried to include more than one module or concern in your example the last included module would just override all the previous ones. No?

Nope. In Ruby, you can call super to invoke a previously included module, which has the same basic property as the decorator pattern.

I totally agree with @avdi that decoration is about adding new responsibilities. That’s why I definately think mixins overusage in some places (such as 500 methods in one single object!) should be done in some different way.

@wycats invoking super from a module is required and dangerous, showing the coupling issues that it presents. you *need* to know both the semantic meanings of your super and the args that it takes in order to invoke it. so that means the Module knows about its parent classes. it also means the other way around: classes that includes modules are coupled to public (and private!) methods of that module…

That’s why I believe modules are useful, if used wisely.

Leave a Reply

Archives

Categories

Meta