Archive for The Project

Introducing Hydrocon

Posted in smalltalk with tags , , on April 29, 2009 by moffdub

You may recall me mentioning in passing some attempt at re-implementing The Project in C#. You may also recall me later reflecting on the several false starts I did along the way, which eventually led me to abandoning these attempts.

Lately, though, there has been an urge building in me, kind of like lower bowel movements. I feel like most of my obsessive questioning of how to apply domain-driven design and object-orientation has settled down. Part of the reason why I kept starting and stopping my earlier attempts at re-implementing The Project was because of how little I knew, and that was because of how little experience I had doing it the right way.

I think I’m ready for another try. This attempt at re-implementing The Project shall be code-named “Hydrocon.” Why? I don’t know. Further, this will be written in Smalltalk. There is no reason to learn yet-another-curly-brace language.

Continue reading

Dynamic Enumerations, revisited

Posted in The Project with tags , , , , on January 14, 2009 by moffdub

Announcer: Now, it’s time for the custodian of clean code, the man who codes what he means and means what he codes, El Moffdo!

That’s correct Mr. Announcer, I am your host, designing with a mere pad and pen just to give the bugs a chance. This is the long-awaited sequel to the oft-searched topic of dynamic enumerations. Let’s go.

First, why is this sequel being written? I have learned that the general problem of a variable’s allowed values being restricted to a finite set that can grow or shrink at run-time is not a unique one; it goes by the alias of the Allowed Value Table (AVT). The quest for solutions to this problem is the source of many of the search engine referrals to this blog.

Continue reading

Dynamic State Pattern

Posted in Java with tags , , , on July 30, 2008 by moffdub

Skip the bloggy parts and head to the pattern.

Background

My frequency of posting had decreased slightly since my first two-post night, due mainly to still going through the boot-up sequence at work.

I do a lot of “sitting there seemingly drinking coffee”. In fact, I am typing this post up as I sit here waiting for a co-worker to arrive and give me work.

You may recall me mentioning that I had started re-coding core parts of The Project. My laundry list of complaints against my ignorant self included:

  • anemic domain model
  • TDD not followed
  • testing not isolated
  • one huge controller class for all UI windows AND interaction with domain and infra layers
  • generally, patterns not used where they could’ve been used
  • abuse of getters
  • no clear demarcation, in source files, of layers
  • only half of the Dynamic Enumeration pattern implemented
  • validation and other rules not encapsulated as Rule objects

… and if I went through each source file of The Project, I could easily triple the size of this list.

I put that on hold as work started. But the slow start-up period has not provided a sufficient outlet for my neurosis. This lack of coding/design activity accumulated until I eventually had to cash the check.

As I returned back to my second attempt at The Project, I was kind of disgusted. So disgusted that I scrapped it and started over — again.

I was disgusted mainly because it seemed like my domain model suffered from domain anemia. I had setters for properties, which provided some validation logic. Getters were regulated. But for some objects, that was it. I had started coding first and then tried to get the code to read like English sentences.

This time, before writing a line of code, I tried some organic object-oriented analysis and design. I put on my customer hat and started recording sentences of functionality.

  • “Users describe equipment with a description.”
  • “Users add equipment into one and only one room.”
  • “Users update equipment with modifications to a description.”

and so on.

Then I annotated each sentence with its code equivalent, minding layers, SRP, DDD, and such.

  • “Users describe equipment with a description.”
    User somebody --> equipment.describe(description);
  • “Users put equipment into one and only one room.”
    User somebody --> room.put(equipment);
  • “Users update equipment with modifications to a description.”
    User somebody --> equipment.update(description);

(the “–>” is supposed to mean that the class on the left calls the method on the right)

Note the utter absence of getters (for now) and setters. Where I had used setters, I am now using describe() and update(). Very nice. It even led me to an interesting de-coupling of instance member names from client code.

Motivation

Now, finally the point of the post. Equipment have a lifecycle status: Spare, In use, In repair, In transit, Broken, and Unknown. Originally and in the first remake, this was just another Dynamic Enumeration. But if I had been a good requirements analyst, I would’ve realized that the business never went from state to state willy-nilly.

Equipment would only go from Spare to In use, In repair, or In transit. It would never go to Broken because nobody would keep broken spare equipment. This and other insights all pointed to the State pattern.

Why must there always be a problem? The State pattern is excellent when you know the states and transitions ahead of time. This was not the case for The Project. Administrators had to be able to at least edit and add new lifecycles. Sounds like I need a Dynamic State pattern.

The Pattern

The State pattern involves creating a base state class and subclasses, one for each of your states. The client object that is tracking state passes itself to the constructor of the initial state (subclass).

Transitions are specified in each subclass as a method bearing the name of a valid transition. In these methods, the client object is “called back” to notify it of a state being changed, so it can do whatever it needs to do to handle that event. Then, the client object’s state variable is updated by the subclass to the target of the transition.

For this to be dynamic, the entire state graph will have to be created at run-time. As far as the client object goes, the dynamic nature of the state graph will affect the callback mechanism. I have client objects implement a StateClient interface.

public interface StateClient
{
	public void changeState(State nextState);
	public void callback(String stateVariableName, String transitionName);
}

Implications for implementers of StateClient: a mapping between transition names and a function that handles the transition has to be maintained. Here is where this pattern is a bit weak.

Without much effort, the best you’ll be able to do here is something that does not involve unique logic for one or more states, unless you want to hard-code some of the states ahead of time.

If you add a new state on-the-fly that has unique logic to it, you probably need to invest in more than a mapping between transition and function. I’m thinking you’ll need an interface instead, with a file or table somewhere defining which implementations map to which transition names, and inject it at run-time.

One other alternative to this approach would be to swap out the entire implementation of StateClient whenever there is a change, which may or may not be a viable option.

Instead of specific subclasses, have one State class for which you can specify a name. The same goes for transitions: give each transition a name that maps to a new State object.

public interface State
{
	public void addTransition(String transitionName, State targetState);
	public void invokeTransition(String transitionName, StateClient parent);
}

Implications for implementers of State: a mapping between transition names and target states has to be maintained and done statically at application start-up. This is the reason why the parent has to be injected when a transition is invoked.

Further, behind the scenes, you’ll probably want to keep track of a “state identifier”, i.e. data about the state specific to the implementer; basically, information about the state that is specified at run-time. In my case, this would be an EnumValue, and I provide a method getOrder() to retrieve drop-down menu order.

Example

Never the hand-waver, you can download an example implementation in Java. You should get this output:

YQ1817H981 is now a pending order
YQ1817H981 is now a new order
YQ1817H981 is now a pending order
Illegal transition from Pending to fjeiofje
No transition handler defined for Active Order
YQ1817H981 is now a shipped order
Illegal transition from Shipped to New Order

Some classes of note:

import java.util.*;

public class OrderState implements State
{
	private HashMap transitionMap;
	private String name;
	private String stateVariableName;
	
	public OrderState(String stateName, String stateVariableName)
	{
		this.transitionMap = new HashMap();
		this.name = stateName;
		this.stateVariableName = stateVariableName;
	}
		
	public void addTransition(String transitionName, State nextState)
	{
		this.transitionMap.put(transitionName, nextState);
	}
	public void invokeTransition(String transitionName, StateClient parent)
		throws IllegalTransitionException, NoTransitionFoundException,
		UndefinedStateVariableException
	{		
		if(this.transitionMap.get(transitionName) == null)
			throw new IllegalTransitionException(this.name, transitionName);
		
		parent.callback(this.stateVariableName, transitionName);	
		parent.changeState((State)this.transitionMap.get(transitionName));
	}
}

and the (anemic) domain object Order:

import java.util.*;

public class Order implements StateClient 
{
	private State orderStatus;	
	private String name;
	
	private HashMap orderStatusTransitionHandlerMap;
	private HashMap stateVariableMap;
	
	public Order(String name)
	{
		this.orderStatusTransitionHandlerMap = new HashMap();
		this.stateVariableMap = new HashMap();
		
		this.name = name;
		
		this.orderStatus = Runner.newOrderState;
		
		// this should be filled externally by an IoC container
		this.orderStatusTransitionHandlerMap.put("New Order", new NewOrderAction(this));
		this.orderStatusTransitionHandlerMap.put("Ship Order", new ShippedOrderAction(this));
		this.orderStatusTransitionHandlerMap.put("Pending Order", new PendingOrderAction(this));
		
		// a hashmap of hashmaps
		this.stateVariableMap.put("Order Status", this.orderStatusTransitionHandlerMap);
	}
	
	public void changeOrderStatus(String transitionName)
		throws IllegalTransitionException, NoTransitionFoundException,
			   UndefinedStateVariableException
	{
		this.orderStatus.invokeTransition(transitionName, this);
	}
	
	public void changeState(State nextState)
	{
		this.orderStatus = nextState;
	}
	
	public void callback(String stateVariableName, String transitionName) 
		throws NoTransitionFoundException, UndefinedStateVariableException
	{
		if(this.stateVariableMap.get(stateVariableName) == null)
			throw new UndefinedStateVariableException(stateVariableName);
				
		if(((OrderStateAction)((HashMap)this.stateVariableMap.get(stateVariableName)).get(transitionName)) == null)
			throw new NoTransitionFoundException(transitionName);
		
		((OrderStateAction)((HashMap)this.stateVariableMap.get(stateVariableName)).get(transitionName)).invoke();
	}
	
	public void newOrder()
	{
		System.out.println(this.name + " is now a new order");
	}
	
	public void shipped()
	{
		System.out.println(this.name + " is now a shipped order");
	}
	
	public void pending()
	{
		System.out.println(this.name + " is now a pending order");
	}
}

Finally, I decided to see if anyone else had done something like this before, and wouldn’t you know it, I find this post from a couple years ago. Comparing the two, the implementation I am offering here uses a couple less classes by making transitions Strings and by not wrapping the states in a StateMachine class.

Follow

Get every new post delivered to your Inbox.