Archive for October, 2008

Effective Indoctrination

I’ve worked for a few large companies over the years, and as those of you who also have done so know that most offer a “orientation” or “get to know the company” seminars that you get sent to with all the bells and whistles.

They provide adequate food (sometimes) and a posh hotel conference room where they play upbeat music. They try to make you believe that you will have fun, and learn a lot from the experience. You then proceed to drink 18 cups of coffee every hour to fight off the overwhelming desire to sleep, or crawl under your table and pull your hair out one strand at a time.

Corporate indoctrination experiences are often dull, boring, ineffective, a waste of money, and at best do not engage the new employee enough to garner any real interest.

Well, I just got back from a two day affair (called DaVita Academy) that, far and away, was the most effective event I’ve ever been to. Not just for an orientation seminar, but ANY event. DaVita, if you don’t know the name (and you probably don’t) is a dialysis service company. We have over 1400 clinics across the country in which we provide dialysis treatment and support services to people with ESRD (End Stage Renal Disease, or kidney failure).

This company is different – well not different, I dare say it is unique – in how it approaches supporting the people who provide the care to our patients. The support services are myriad, effective, caring, and make a difference in the lives of the patients and the teammates (what we call employees, or staff). I spoke with dozens of people at this event – which was attended by approximately 400 out of our 30,000+ teammates – and from the CEO of the company down to the PTCs (Patient Care Technicians), everyone truly believes our purpose is to provide the best possible care to ESRD patients. It was truly amazing to talk with these people.

As for the seminar, while I found my eyes glazing over several times, I did get an appreciation for the effort that is put forth to make DaVita a fulfilling and fun place to work. The “fun” aspect at Academy was a bit overwhelming. I like to have fun as much as the next person, but it reached a level that was a bit creepy to me. I started looking for the teammates who would be giving us our orange robes and flowers that we should start giving to people at the airport. I like my hair short, but not that short.

However, as with any event like this, as long as you walk in willing to take the experience in the spirit in which it is given, you can leave with some positive ideas. At this company, the people make the difference. The presentations had no impact on what I do, or how I do my job, but meeting the amazing people that work at this company did have an impact.

If anyone has a very positive, or very negative story about corporate indoctrination, I’d love to hear it.

Flex Frameworks: Mate Review

Well I’ve finally reached a point in my latest AIR application where I can write up a useful review of the framework I chose to use: Mate.

In my continuing effort to avoid Cairngorm, I’ve been evaluating other Flex frameworks that are lightweight, rapid and comprehensible. In the application previous to this, I implemented PureMVC, and while I did not get to use all of the features, I did think it was a greater balance of ease and power than is Cairngorm, but was still rigid on implementation.

Less Regulation

For me, the purpose of any design framework is to enforce some standard patterns to create a scalable, flexible application, while allowing the actual implementation up to the developer and architect. Cairngorm does not fit this idea, and PureMVC came close, but still heavily regulated how the application was structured and implemented.

Mate, on the other hand, simply provides the mechanisms for enforcing a design pattern, while allowing more creativity and flexibility on how to implement it. Foremost to this is its use of the native event model in Actionscript for handling the application behavior. The tags provided by Mate simply add a layer of abstraction on top of this system that makes it both more powerful and more flexible (not to mention easier to learn).

Another concept that I found attractive is that you can break up your application into very granular pieces when you are creating a large project, but also have the ability to combine aspects together for a small application with only a handful of views and events.

Want to combine your event handlers and property injectors into the same file? No problem. They even provide different examples on their site that shows different implementation styles.

Tag Based Abstraction

I can’t gush enough about the tags available in Mate. Again, another benchmark for me on a valuable framework is how much menial coding it does for me. Hmm, that sounds familiar to another tag-based technology that I enjoy so much. What was that called again?

How do you get objects returned from a RemoteObject call injected into the view? It can’t be much more simple than this:

<Injectors target="{MyModel}">
   <PropertyInjector source="{MyEmployeeManager}" sourceKey="employees" targetKey="arrEmployees" />
   <PropertyInjector source="{MyProjectManager}" sourceKey="projects" targetKey="arrDivisionProjects" />
   <PropertyInjector source="{MyResourceManager}" sourceKey="resources" targetKey="arrPhysicalResources" />
</Injectors>

How about event handlers? It makes it real easy to find what you’re looking for when you have a tag named EventHandlers with child tags called RemoteObjectInvoker and MethodInvoker.

<EventHandlers type="{EmployeeEvent.GET_ALL}">

   <RemoteObjectInvoker ...>
      <resultHandlers>
         <MethodInvoker generator="{MyEmployeeManager}"
                  method="handleResponse"
                  arguments="{resultObject}"/>
      </resultHandlers>
   </RemoteObjectInvoker>

</EventHandlers>

Less Code!

Ever seen a Hello World example written using Cairngorm? I have and it’s not pretty. I even wrote up a demo on our internal Wiki for a Hello World application using PureMVC. It wasn’t much prettier. It required 12 steps to explain all the mechanisms involved.

In Mate, the required code to get a remote “Hello World!” string and display it in a view in almost laughably simple in comparison. They have a view injection diagram on their site that is a nice representation of how it works in the Mate framework.

Give Mate a try

In case the tone of my opinions in this article wasn’t a giveaway, I am a fan of Mate. It’s definitely something I’m going to keep evaluating for our future applications. I still have one more framework to look at – Swiz – which a colleague of mine has already starting investigating. What he has shown me so far is also impressive.

All in all, I’m glad that there are now frameworks out there that deliver on the promise of power and flexibility instead of just power.

The Value Objects

Otherwise known as a transfer object is simply a design pattern for exchanging data between disparate systems. I’m working on a application with a Flex UI and a ColdFusion backend, and I initially discovered that if I return a query directly to Flex, it is converted into an ArrayCollection populated with simple Objects.

What I wanted was an array of specifically typed objects that I could cast as value objects in Flex. Here’s a very simplistic example of an Employee value object in Flex. It has two properties:

  • Employee ID
  • Employee Name

Flex Employee Value Object

package net.fusioncube.transferObjects
{
   [RemoteClass(alias="net.fusioncube.model.employee.Employee")]
   [Bindable]
   public class Employee
   {
      private var _employeeID:uint;
      private var _employeeName:String;

      /* constructor */
      public function Effort(employee_id:uint = 0,
                  employee_name:String = "")
      {
         this._employeeID= employee_id;
         this._employeeName= employee_name;
      }

        public function get employee_id():uint
        {
        	return _employeeID;
        }

        public function set employee_id(value:uint):void
        {
        	if(value != 0) _employeeID= value;
        }

        public function get employee_name():String
        {
        	return _employeeName;
        }

        public function set employee_name(value:String):void
        {
        	if(value != "") _employeeName= value;
        }
   }
}

You may have noticed the RemoteClass metadata applied to the Actionscript class. What this does is ensure that this Flex class maps directly to a ColdFusion component value object. To make a ColdFusion component value object is simple: you use the <cfproperty> tag for each property and specify each one’s type.

In this example, I’ve also added an init() method, whose use we’ll discover later.

ColdFusion Employee Value Object

<cfcomponent displayname="Employee" output="false">
   <cfproperty name="employee_id" type="numeric" default="" />
   <cfproperty name="employee_name" type="string" default="" />

   <cffunction name="init" access="public" returntype="net.fusioncube.model.employee.Employee" output="false">
      <cfargument name="employee_id" type="numeric" required="false"  />
      <cfargument name="employee_name" type="string" required="false"  /> 

      <cfset this['effort_id']       = arguments.effort_id />
      <cfset this['employee_name']      = arguments.employee_name />

      <cfreturn this />
   </cffunction>

</cfcomponent>

Converting a Query to an Employee Array

Again, as a very simple example, let’s say I have an EmployeeService component in my service layer and have a method listEmployees() that simply queries the employees table and returns all rows.

<cffunction name="listEmployees" access="public" output="false" returntype="query">
   <cfset var effortQuery = "" />

   <cfquery datasource="#variables.config.getSetting("datasource")#" name="employeeQuery">
   select e.* from employees e
   </cfquery>

   <cfreturn effortQuery />
</cffunction>

Since I don’t want to return a query, and I certainly don’t want to have two methods in every single component – one that returns a query and one that returns an array of objects – I use the handy, dandy AOP feature in ColdSpring to apply an advice that does it at runtime.

QueryToVOAdvice Advice

In this advice, I simply loop over the query’s rows and columns to create a simple structure containing the key/value pairs for each row. It then creates a new component for each query row by passing that structure to the init() function – which you saw above – and adds it to an array.

The result is an array of Employee-typed objects.

<cfcomponent displayname="QueryToVOAdvice" extends="coldspring.aop.MethodInterceptor">

   <cffunction name="init" returntype="utility.aop.advice.converters.QueryToVOAdvice" access="public" output="false">
      <cfreturn this />
   </cffunction>

   <cffunction name="invokeMethod" access="public" returntype="any">
      <cfargument name="methodInvocation" type="coldspring.aop.MethodInvocation" required="false" />

      <cfscript>
      var local = structNew();
      local.queryRow = 1;

      // Create an array to hold the value objects
      local.valueObjectArray = ArrayNew(1);

      // Store the resulting query object from the method execution
      local.queryObject = arguments.methodInvocation.proceed();

      // Loop over the query rows
      for(local.queryRow=1; local.queryRow lte local.queryObject.recordCount; local.queryRow = local.queryRow+1)
      {
         local.voStruct = structNew();

         // Loop over the query columns and create a key/value pair for each value
         // in this row of the query
         for(local.columnNum=1; local.columnNum lte listLen(local.queryObject.columnList); local.columnNum = local.columnNum+1)
         {
            local.columnName = listGetAt(local.queryObject.columnList, local.columnNum);
            local.voStruct[local.columnName] = local.queryObject[local.columnName][local.queryRow];
         }

         // Create an instance of the value object (obtained from the getValueObject method)
         // initializing it with the structure we created.  Add the value object to the array.
         arrayAppend(local.valueObjectArray, createObject('component', arguments.methodInvocation.getTarget().getValueObject()).init(argumentCollection=local.voStruct));
      }

      return local.valueObjectArray;
      </cfscript>
   </cffunction>

</cfcomponent>

ValueObject Property

For each of my beans, in this case the Employee bean, I can simply apply an advice in the definition. For this to work, I create a valueObject property in each component.

<component name="Employee">
   <cffunction name="setValueObject" access="public" output="false" returntype="void">
      <cfargument name="valueObject" type="string" required="true" />
      <cfset variables.valueObject = arguments.valueObject />
   </cffunction>

   <cffunction name="getValueObject" access="public" output="false" returntype="string">
      <cfreturn variables.valueObject />
   </cffunction>
</component>

Employee Bean Definition

Now when I define my Employee bean, I specify the type of the value object (the type that gets returned from the init() function), and then apply the advisor (shown below).

<bean id="Employee" class="coldspring.aop.framework.ProxyFactoryBean">
   <property name="target">
      <bean class="net.fusioncube.model.employee.EmployeeService">
         <property name="valueObject">
            <value>net.fusioncube.model.employee.Employee</value>
         </property>
      </bean>
   </property>
   <property name="interceptorNames">
      <list>
         <value>queryToValueObjectAdvisor</value>
      </list>
   </property>
</bean>

QueryToValueObjectAdvisor Definition

<bean id="queryToValueObjectAdvisor" class="coldspring.aop.support.RegexMethodPointcutAdvisor">
   <property name="advice">
      <bean class="utility.aop.advice.converters.QueryToVOAdvice"/>
   </property>
   <property name="pattern">
      <value>^list.*$</value>
   </property>
</bean>

The Flex Array of Typed Objects

Here’s an image of an example array I get back from ColdFusion in one of my current apps. You can see that each object was automatically converted into a Teammate (equivalent of an Employee) rather than a simple Object.

Caveat: If you’re passing back queries with a thousand or more rows, and are running CFMX 7 or older, then this solution may cause serious performance problems as object creation is notoriously “slow” in those versions of ColdFusion.