Saturday, May 13, 2006

Ruby Design Pattern: Pollution Control

Avoid method name collisions by mixing in modules to an instance of an inner class.



class Outer
class Inner
end

def initialize(mixin)
@inner = Inner.new()
@inner.extend(mixin)
end
...
end


When extending objects with mixin modules, there is a risk of method name
collisions. Given the example in the Module Injection post, the execute_before and execute_after methods in the Strategy object might collide with method names in a rule module. Suppose the rule module looks like this:

module TransformationRules
def functiondef_before(element)
...
end

def functiondef_after(element)
...
end

def execute_before(element)
...
end

def execute_after(element)
...
end
end


When the dispatch mechanism in the Strategy object finds an execute element, it will dispatch the element to the wrong execute method. It will call the execute_before method defined in Strategy, not the one defined in the TransformationRules module.

Pollution Control reduces the risk of name collisions when extending classes with new functionality by extending an inner class. Thus, functionality is added to a class without affecting the interface of the class.

Related Patterns


Pollution Control is a very close relative of Strategy, Inversion of Control, Dependency Injection and Module Injection.

The thing that makes Pollution Control a pattern in its own right is the purpose: mixing in functionality encapsulated in a module without changing the interface of the client.

No comments: