Friday, May 19, 2006

A Failure I Can Live With

I had some good news a couple of days ago, and I just can't resist toting my own horn a little.

A couple of years ago I was subcontracted to write a web based print formatting system. The system could automatically produce brochures, and used FrameMaker as a formatting engine.

I haven't counted this system as one of the great successes of my career. FrameMaker and Internet Information server did not play well together. (Neither did Apache and FrameMaker.) In the end, I solved the problem by writing a small web server of my own. Though the solution worked, my client was not happy with the design. He insisted he wanted the application to run under IIS, even though it was not technically possible. Fortunately my client's client did accept the solution.

Still, my client wasn't happy, so I wasn't happy. Earlier this week a friend of mine told me what became of my 'failed' system.

The system has worked very well for more than five years now. The customer estimates that it has saved about 97% of the costs that would have been incurred without it.

My friend mentioned an estimated cost of about SKR 50,000,000 if the system had not been in place, which would have made the cost of running the system about SKR 1,500,000, and the savings about SKR 48,500,000. As my friend put it, "talk about Return On Investment".

Suddenly I feel a lot better about the whole thing. That kind of failure I can live with.

Thursday, May 18, 2006

Bug Hunt

A friend and I spent an enjoyable afternoon debugging a Rails application yesterday. "Enjoyable" and "debugging" usually don't go together, but in this case they did.

My friend, who happens to be a much better programmer than I am, was stuck on a bug. His application had a form that worked correctly the first time it was used. The second time around, values filled in the first time reappeared in the form. In the end it turned out that an automatically generated find_xxx_by_id method returned the wrong data the second time it was called. (My friend is filing a bug report.)

Our excursion into bug country was enjoyable because we solved the problem as a team. It made it easier to keep focused. There was communication. We could bounce ideas off each other. I learned a few new things about ActiveRecord. We solved the problem, and the bug report may save other people some trouble in the future.

It was a good half days work.

Slow connection to www.henrikmartensson.org

The connection to www.henrikmartensson.org is incredibly slow at the moment. Don't know why. My site host and I will look into it.

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.

Ruby Design Pattern: Module Injection

Signal that objects of a class is designed to be extended via mixins by passing the mixin module via the constructor.


class ExtensibleClass
def initialize(mixin)
extend(mixin)
end
...
end

Ruby allows objects to be extended with new functionality at runtime. Any object can be extended in this manner by a call to the extend method. Some classes are designed to have their objects extended with new functionality.

Example


Consider a Strategy object that encapsulates a set of transformation rules for XML documents. The document is used by a treewalker. The treewalker walks the node tree representing the XML document. The Strategy class uses Module Injection:

strategy = Strategy.new(io, TransformationRules)
treewalker = TreeWalker.new(strategy)
treewalker.walk(xml_document)

The strategy object contains dispatch code that chooses which transformation rules to call depending on such things as node type (element, processing instruction, text, etc.) and node name.

The Strategy object also needs transformation rules. Keeping the transformation rules in a mixin module makes it possible to reuse the Strategy object with different rule sets.

Because the rules are kept in a module, it is possible to make the module up of several smaller mixins. In this example, TransformationRules can itself mix in several smaller rules modules. This is what the Strategy class might look like:

class Strategy

def initialize(io, rules)
@io = io
extend(rules)
end

def execute_before(node)
# Dispatch code
end

def execute_after(node)
# Dispatch code
end
end

And here is a sample treewalker. This one is for REXML:

module XmlUtil
class TreeWalker

def initialize(strategy)
@strategy = strategy
end

def walk(node)
@strategy.execute_before(node) if @strategy.respond_to? :execute_before
if node.instance_of?(REXML::Document)
walk(node.root)
elsif node.instance_of?(REXML::Element) then
node.children.each { |child|
walk(child)
}
end
@strategy.execute_after(node) if @strategy.respond_to? :execute_after
end
end
end

When to Use Module Injection


Use Module Injection when you want to signal clearly that an object must be extended with a mixin module.

You can also use it when you want to encapsulate a family of algorithms, similar to Strategy, but with the added flexibility of using modules.

Related Patterns


Dependency Injection, Inversion of Control, Strategy, Pollution Control.

Tuesday, May 09, 2006

Rails Author Wanted

My publisher (Apress) is looking for an author interested in writing an advanced book on Rails. They work with new authors all of the time, so prior writing experience isn't necessary. If you're interested send myeditor (Jason Gilmore) and email at jason@apress.com.

Wednesday, May 03, 2006

Integration Driven Development and Anatomies

I attended a talk by Lars Taxén about Integration Driven Development and Anatomies today. IDDA is a development methodology for large projects. "Large" means 1,000+ people.

IDDA was developed at Ericsson for use in telecommunications projects. One of the things I found interesting was that the anatomies part, a method for modelling complex systems, is quite similar to Domain Modelling. That is, both methods aim to create models that mirror real world objects or processes. Anatomies, like Domain Models, make use of bounded contexts to separate different parts of the system.

Some things were very different from what I am used to. For example, IDDA subsystems are implemented in the order they are activated when the system is used. That is very different from the Agile practice of implementing the most valuable functionality first.

For example, consider a document production system consisting of three subsystems: an XML authoring system, a Document Management System (DMS), and a printing system.

With IDDA, the first system to be built would be the authoring system, then the DMS, and finally the printing system. This is the order in which the subsystems are used. First an author writes something, then she stores it in the DMS, then it is printed.

With an Agile methodology, the most likely order is authoring system, printing system, DMS. The authoring system is built first, to enable authors to start using the system as soon as possible. Then the printing system would be built, because that makes it possible to print documents, even though there is no DMS yet. That makes it possible to get value from the system, even though the central piece is missing. The DMS is added last.

The situation may be a bit more complex, of course. For example, once the basic printing engine works, it may be most profitable to implement the basic DMS system, go back and finish the printing engine, and finally put the finishing touches on the DMS.

IDDA focuses on the dependencies between subsystems. For very large and complex systems, this may be a better strategy than focusing directly on business value. (I am not quite convinced, but I am certainly interested in learning more.) Culture and cooperation are other areas that are of particular interest. Ericsson's projects often involve people from all over the world. It is important that they can communicate over the barriers of culture, language, and physical distance.

IDDA hasn't been directly influenced by Agile methodologies, but Systems Thinking has played a part. This may to some extent explain the similarities between Agile methodologies and IDDA, even though they target very different projects.