A Matter of Factory

In my continued exploration of Seaside I revisited an implementation of Factory pattern that is especially easy in Smalltalk and oh so difficult in Java. I enjoyed the rediscovery so much I thought I share it here.

The Problem

I am developing a console for configuring a complex application. A number of Components need to be configured and each component is a subclass of the abstract class ConfigurableComponent. The attributes of each component are sufficiently different that a single composed view is not suitable to act as an editor for all the possible subclasses (although the same editor would work for around half of them). When my user selects a ConfigurableComponent from a list I want seaside to open the correct editor.

Choosing a Solution

There lots of ways to do this, including…

  1. Use a Factory Method e.g. editorView on the subclass of ConfigurableComponent to return its editor view. Easy to implement but I dislike the coupling of the model to it’s view. It also makes it difficult if there are multiple contexts in which the object is editor (e.g. a web based one or a standalone application – the model object would have to know about all the contexts in which it is viewed and return the correct editor for that context)
  2. Use a Simple Factory that holds a dictionary of some kind mapping the class of the Component to its editor. This at least keeps the view and model separate but means there’s another artifact to maintain (i.e. the dictionary) every time you introduce a new subclass of ConfigurableComponent.
  3. Use a bit of Smalltalk reflective magic!

The Magic

You create a DefaultConfigurationEditor (capable of editing a standard ConfigurableComponent) and a number of subclasses which can edit sone (or more) specific ConfigurableComponents. Each editor class then implements the class method isEditorFor: aConfigurableComponent which examines the aConfigurableComponent and returns true if this editor supports its class…

isEditorFor: aConfigurableComponent
^(Array with: ComponentA with: ComponentB) includes: aConfigurableComponent class

You can then implement a class method in DefaultConfigurationEditor like this…

editorFor: aConfigurableComponent
(self allSubclasses detect: [:subclass | subclass isEditorFor:aConfigurableComponent] ifNone: [self yourself]) new.

…now you can add a new subclass of ConfigurableComponent and it will work seamlessly with the DefaultConfigurationEditor. If you need a new Editor for it just create a new subclass of DefaultConfigurationEditor implement isEditorFor: and away you go.

Explore posts in the same categories: Design Patterns, Objects, Seaside, Smalltalk

2 Comments on “A Matter of Factory”

  1. Damien Cassou Says:

    Very good way of doing things 🙂

    What is this “… ifNone: [self yourself]…” ? Why not simply “… ifNone: self…” ?


  2. Damien

    you are quite right the yourself is uneccessary.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: