Crazy Command Composition

Ryan Sonnek bio photo By Ryan Sonnek

I’ll send out a bright shiny new nickel to whoever can guess what this spring xml file is actually accomplishing. :)

  <bean id="importDatasetCommand" class="com.codecrate.shard.ui.command.SpecificApplicationEventActionCommandExecutor">
    <constructor-arg><value>com.codecrate.shard.ui.command.ImportDatasetEvent</value></constructor-arg>
    <constructor-arg>
      <bean class="com.codecrate.shard.ui.command.EventDispatcherThreadActionCommandExecutor">
        <constructor-arg>
          <bean class="com.codecrate.shard.ui.command.ApplicationWindowProgressMonitorActionCommandExecutor">
            <constructor-arg>
              <bean class="com.codecrate.shard.ui.command.FoxtrotBackgroundJobActionCommandExecutor">
                <constructor-arg>
                  <bean class="com.codecrate.shard.ui.command.MethodInvokingActionCommandExecutor">
                    <property name="targetObject"><ref bean="importDatasetService"/></property>
                    <property name="targetMethod"><value>importDataset</value></property>
                  </bean>
                </constructor-arg>
              </bean>
            </constructor-arg>
          </bean>
        </constructor-arg>
      </bean>
    </constructor-arg>
  </bean>

I absolutely love the decorator pattern. It promotes encapsulation of specific behavior into seperate classes. The problem is that when trying to compose an object with multiple layers of functionality, it can get out of control (like above). Usually, this is where a “factory” object is created to encapsulate complex object creation, but unfortunately for me, the above example can’t be pushed into a factory helper. Why?

First, the SpecificApplicationEventActionCommandExecutor implements the ApplicationListener interface. Spring inspects the application context for classes that implement this functionality, which means this layer has to be defined in XML.

Next, the ApplicationWindowProgressMonitorActionCommandExecutor implements ApplicationWindowAware interface, which has the same issues as the ApplicationListener interface.

Hopefully I’ll be able to encapsulate this functionality into some form of spring prototype block so that I can just inject my customized behavior into this whole stack of wrappers.