github
Advanced Search
  • Home
  • Pricing and Signup
  • Explore GitHub
  • Blog
  • Login

ryanwood / shade

  • Admin
  • Watch Unwatch
  • Fork
  • Your Fork
  • Pull Request
  • Download Source
    • 1
    • 0
  • Source
  • Commits
  • Network (0)
  • Issues (0)
  • Downloads (0)
  • Wiki (1)
  • Graphs
  • Branch: master

click here to add a description

click here to add a homepage

  • Branches (1)
    • master ✓
  • Tags (0)
Sending Request…
Enable Donations

Pledgie Donations

Once activated, we'll place the following badge in your repository's detail box:
Pledgie_example
This service is courtesy of Pledgie.

Shade is a state machine (or workflow) engine for ColdFusion business objects. — Read more

  cancel

  cancel
  • Private
  • Read-Only
  • HTTP Read-Only

This URL has Read+Write access

Oops 
ryanwood (author)
Wed Oct 15 12:11:36 -0700 2008
commit  9564d0b27a24c019dddce7c2bc73249ee58f29f8
tree    f22b9e59bb7b2cbfec1251d4aa98f0c61fa912e0
parent  b2457504eeba4e0ece295659fa26bc6ad909fba0
shade /
name age
history
message
file .gitignore Fri Aug 08 12:16:52 -0700 2008 Prevented manually state change. [ryanwood]
file CollectionBase.cfc Fri Jul 18 13:20:38 -0700 2008 Clean up [ryanwood]
file Event.cfc Mon Oct 13 06:52:34 -0700 2008 Added persistence object for saving which creat... [ryanwood]
file LICENSE Fri Jul 18 12:11:38 -0700 2008 Added License. Changed 'entering' callback to '... [ryanwood]
file README Mon Oct 13 07:39:46 -0700 2008 Updated README [ryanwood]
file State.cfc Wed Oct 15 12:11:36 -0700 2008 Oops [ryanwood]
file StateMachine.cfc Mon Oct 13 06:52:34 -0700 2008 Added persistence object for saving which creat... [ryanwood]
file StateTransition.cfc Mon Oct 13 06:52:34 -0700 2008 Added persistence object for saving which creat... [ryanwood]
file StateTransitionCollection.cfc Fri Jul 18 06:55:00 -0700 2008 Updated project name to shade. Added README [ryanwood]
directory test/ Mon Oct 13 06:52:34 -0700 2008 Added persistence object for saving which creat... [ryanwood]
README
=== INFO ===

Shade is a state machine (or workflow) decorator for ColdFusion business objects.

=== OVERVIEW ===

You have a Order business object...

You want to use it as a state machine (workflow), so you create a stateful 
wrapper (call it what you wish) that extends shade.StateMachine. In it you
need to define at least 2 methods: init() and defineStates(). See the example 
below. 

-- Defining States and Events --

You add a state and events in the defineStates() method. You create a state
by calling addState([name of state]). This will register a state for you
object and create two methods available for use in you decorated object.

For instance addState('closed') will create a close() method to fire the close 
event and an isClosed() method to check if the object is in a closed state.

There are 3 events that each state exposes: entering, after, and exit. See
"Adding Event Callbacks" for more.

You also add event here using the addEvent() method. An Event is anything
that will cause you object to transition from one state to another. To make 
an event actually do something, you need to add transitions to that event.
The easiest way is to simply chain the addTransitions() method right to 
addEvent(). A transition is a rule that defines 'from' states and a 'to' 
state. It can also have a guard method that will prevent the transition 
unless it returns true. A guard is called on the original business object 
(not the decorated one).

-- Adding Event Callbacks --

You can also define event callback methods in the decorator. The signature
for those will be: 

  before[state]Action: Fires just before you enter this state
  after[state]Action:  Fires just after the state becomes current
  exit[state]Action:   Fires on the previous state just after the new
                       state becomes current (i.e. when you leave this state)

-- Persistence --

Without specifying a persistence object (service layer), the state property
is updated but not persisted to the database. Obviously, this has a limiting
effect on events. An after event will fire after the state is updated even 
though it will not be changed in the database.

To get the proper use of the event callbacks, you should pass in a persistence
object which will be passed the the business object and is responsible for 
saving it.               

=== EXAMPLE ===

  <cfcomponent displayname="Order" extends="shade.StateMachine" output="false">
    <cffunction name="getState" ...
    <cffunction name="setState" ...
  </cfcomponent>

  <!--- This is optional, but needed for persistence --->
  <cfcomponent displayname="OrderService" extends="shade.StateMachine" output="false">
    <cffunction name="save">
      <cfarguments name="order" ...
       ...perform the save
    </cffunction>
  </cfcomponent>

  <cfcomponent displayname="StatefulOrder" extends="shade.StateMachine" output="false">
    <cfset instance = structNew() />
    
    <cffunction name="init" access="public" returntype="any" output="false">
      <cfargument name="order" required="true" />
      <cfargument name="persistenceObject" required="false" />  
      <!--- 
      Call super passing the original business object and the initial state.
      You can also pass the method to set the state in your business object (without 
      the get/set in front of it). It defaults to 'State' which would them 
      assume that you business object had getState() and setState() methods.
      --->
      <cfset super.init(arguments.order, 'new', 'State', arguments.persistenceObject, 'save') />
      <!---
      or <cfset super.init(arguments.order, 'new') /> if there is no persistence object 
      --->
      <cfreturn this />
    </cffunction>
      
    <cffunction name="configureState" access="private" returntype="void" output="false">
      <cfscript>
        addState('new');  
        addState('open');
        addState('closed');
        addState('returned');
  
        addEvent('process').addTransitions('new', 'open');
        addEvent('close').addTransitions('new,open', 'closed');
        addEvent('return').addTransitions('closed', 'returned', 'canReturn');
      </cfscript>
    </cffunction>
    
    <!--- Observers --->
    
    <cffunction name="beforeClosedAction" access="public" returntype="void" output="false">
      <!--- Perform some action such as sending a notification when an order is closed. --->
      <cfmail ... />
    </cffunction>
  
  </cfcomponent>


=== USAGE ===

<cfscript>
  o = createObject("component", "Order").init();
  order = createObject("component", "OrderState").init(o);
  
  order.process();
  order.isOpen(); <!--- true --->
  order.close();  <!--- notice is sent by mailer --->
  order.return();
</cfscript>
Blog | Support | Training | Contact | API | Status | Twitter | Help | Security
© 2010 GitHub Inc. All rights reserved. | Terms of Service | Privacy Policy
Powered by the Dedicated Servers and
Cloud Computing of Rackspace Hosting®
Dedicated Server