The amazing adventures of Doug Hughes

Archive for April, 2007

Put Your Controllers on a Diet, Use a Service Layer

I recently hired my first employee, Jeff. If you’ve been reading my blog you may have noticed a few recent entries by Jeff. The nice thing about an employee is that you can, within the boundaries of the employees willingness to deal with it, give them whatever work you don’t want to do. Or, as in my case, don’t have the time to do.

This has, unfortunately, put Jeff in a tough spot. See, I have him working on a couple projects right now. One of these projects is an “old” Model-Glue application which I myself wrote most of a couple years ago. The application in question is a Model-Glue 1.1 application and also uses Reactor and ColdSpring.

Now, by using Model-Glue, Reactor and ColdSpring you would think that this would be an extremely maintainable application. Well this is true and not true. It’s proven quite easy to maintain the visual side of the application, but it’s turned out to be a pain to update the logical side of the application.

See, when I first started the project I didn’t have the faintest clue what a services layer was. I mean, I had a pretty good idea what a model was and I knew how to write CFCs. I’d written Reactor by then so I wasn’t completely clueless (depending on your personal perspective).

Actually, it’s important to note that I didn’t start out using ColdSpring in the application Jeff is supporting. Instead, I used ChiliBeans, which is a simple component used to configure CFCs with XML. Think of it as a very, very, very light inversion of control (IOC) component.

This was quite useful for configuring CFCs. I wrote all sorts of config components. An EmailConfig would have properties to define who sent an email and who gets BCCed when an email is sent and more. A PaymentProcessorConfig might define all the values needed to process a transaction. I think you get the point. So, yes, ChiliBeans was great for configuring some of these CFCs, but that’s all I used it for.

Somewhere along the lines I started to use ColdSpring because of Autowiring. Autowiring is a process by which, when Model-Glue starts up, it will match beans configured in ColdSpring to setters on your application’s controllers. If matches are found, the beans will automatically be set into your controller for you. This saved me a few lines of code and I quickly adopted ColdSpring.

At first I used ColdSpring as a substitute for ChiliBeans. In fact, a lot of my projects from this time period still have a Beans.xml file which was simply a merging of all my individual bean xml files from ChiliBeans. Sadly, this is what Jeff is still stuck with.

So, if I’m only using ColdSpring for simple configuration, then how do I make use of these configuration settings?

Fat Controllers

I picked up the term Fat Controllers from Jared Rypka-Hauer. A Fat Controller is a controller in an MVC application where there is too much logic (or any, for that matter) in the controller.

Let’s say, for the sake of argument, that you’re sending an email from a Model-Glue application. You’ll probably have a form that submits to an event handler. The event handler would fire a message that’s mapped to an event handler on your controller. Here’s what a hypothetical Fat Contoller method might look like:

<cffunction access="Public" hint="I send an email." name="DoSendEmail" output="false" returntype="void">
    <cfargument name="event" required="true" type="ModelGlue.Core.Event">
	<cfset EmailConfig=getEmailConfig() var/>
	<cfmail from="#EmailConfig.getTo()#" subject="#EmailConfig.getSubject()#" to="#arguments.event.getValue("from")#">
		Dear #arguments.event.getValue("name")#, We thought you might want to buy our penny stocks. Etc. etc. etc. Thanks, Some Company
	</cfmail>
</cffunction>

The getEmailConfig() method above would be set via Autowiring to a CFC configured via ColdSpring. The EmailConfig and additional values from the event are used to send an email via the cfmail tag.

But the thing is, what the heck does this buy us? About the only thing I can think of is separation of configuration from my application. However, I’m still applying procedural techniques within an OO framework. What could be more procedural than getting values and then doing stuff with them in a long line of code?

The example above is fairly simple for the purposes of this article, but from the application that Jeff’s supporting there are controller methods with 50 or more lines of code in them.

So now, a couple years after the fact, Jeff is thrown feet first into this application and asked to make some nontrivial changes. Let’s pretend that he’s working with that email controller above. Perhaps the client has decided that they want to use a Flex or Ajax form to sends the email message without reloading the page the user is on. How do you reuse the code in that controller? Well, long story short, you either put together a hack or you don’t reuse it at all.

The Service Layer

Let’s say that, instead of the controller above, we had CFC that sent an email. For the sake of argument the CFC has a method on it with this signature:

sendEmail(emailAddress, name)

Without getting into the implementation, I think it’d be safe to say that this function performs the service of sending an email message. So let’s say that this is a “Service” CFC.

A Service Layer is made up of a collection of Service CFCs. Each service CFC has a collection methods with simple signatures that do things. They services create a faade for your application’s complex business logic. In many cases each use case in your application is matched by one method in a service.

Let’s say you have a content management system where users can add and edit content, delete content, publish content and view content. You might end up with a ContentService CFC with methods similar to this: saveContent(), deleteContent(), publishContent(), and getContent().

The nice thing about these CFCs is that they’re easily exposed to an HTML-based framework like Model-Glue, to Flex or Flash via remoting or to other languages and platforms via web services.

Getting back to our email use case, our controller could easily look more like this:

<cffunction access="Public" hint="I send an email." name="DoSendEmail" output="false" returntype="void">
    <cfargument name="event" required="true" type="ModelGlue.Core.Event">
	<cfset getEmailService().sendEmail(arguments.event.getValue("from"), arguments.event.getValue("name"))/>
</cffunction>

Let’s ignore the implementation of the sendEmail method. It doesn’t matter. All we need to know is that if we call this method an email will be sent. But, what about all the other data that comes out of the email configuration cfc we were using before? We could easily use ColdSpring to configure the EmailService. Here’s an example configuration:

<bean class="model.email.EmailService" id="EmailService">
    <constructor-arg name="from">
        <value>example@pennystocks.com</value>
    </constructor-arg>
    <constructor-arg name="subject">
        <value>Buy our stocks</value>
    </constructor-arg>
    <constructor-arg name="contentFile">
        <value>buyStocks.txt</value>
    </constructor-arg>
</bean>

Because the service is configured via ColdSpring it can be autowired into your controller. Heck, if you designed an API for your email service that was flexible enough, you could wire it into other controllers that might have a need to send emails from time to time.

This makes it very easier to reuse your application’s logic. It makes it more maintainable. It applies time tested design patterns. It slices, it dices, it even make julian fries.

So, the moral of the story is to put your controllers on a diet, use a Service Layer.

What does Object Oriented Programming do for Me?

In some respects, with the release of ColdFusion MX 6/6.1 and the beginnings of some object oriented (OO) capabilities in ColdFusion, the developer community has been split. On one side, there are those developers who came from Java, SmallTalk, .NET or some other object oriented capable language and were able to pick up the concepts of object oriented application development in ColdFusion fairly easily. On the other side, are the developers who came into ColdFusion new, or at least without any object oriented development experience.

To many of these developers whose tried and true procedural methods have worked just fine so far, object oriented development is completely foreign and un-trusted. I was talking with one such developer the other day, that had been presented with an opportunity that required object oriented development skills. So, what benefits do you give a procedural programmer for shifting to object oriented development when their procedural ways have been serving them just fine for many years?

Real World Modeling

In most applications, we are asked to model some sort of real work scenario. Maybe it is a content management system where users are being asked to publish content and that content goes through a workflow process before being made available. You can fairly easily imagine a newspaper editing room where the writer hands off his article to a publisher who must approve it before going to print. This is a real world model.

Take an e-commerce application as another example. You can picture a customer selecting a product from the shelf, approaching the cashier, providing payment information, and leaving with their purchase. This is a real world model.

Object oriented development is all about real world modeling. With object oriented development, you have a series of independent objects – a customer, a shopping cart, a payment processor, etc. These objects are self contained and know how to perform a limited number of functions. Putting them together into a system though, and all of the sudden you have the building blocks of a full blown e-commerce application. Object oriented development allows you to build an application at the functional level, and not at the implementation level like you do with procedural development.

Code Reuse

In other trades, there are proven solutions that people rely upon every day without re-inventing the wheel. For example, the builder doesn&rsquo;t go out to the forest and start chopping trees for a new house. He uses a common 2&quot;x4&quot; wood to frame the house with a hammer and nails that somebody else already developed. So, why do we as software developers spend so much time re-inventing the wheel with each new application? How many applications have you built that require a user authentication / authorization system? Sure, there may be some added complexities in some cases, but the general principles remain the same.

With object oriented development, you can very easily reuse previously build objects and subsystems in a new application. These objects have been built, tested, and proven in other applications, so you can easily drop them into your application and expect them to work. Through other object oriented development practices, it is easy to extend and enhance the capabilities of an existing object without changing the original code. This improves avoids adding new bugs to the system and speeds your development time.

Reliability

Reliability is a key factor in delivering software applications. After all, what use is an application that keeps crashing or loosing data? As mentioned above, object oriented development is all about small modular components. By developing using these small components, the developer can write and test a small piece of functionality independent of the rest of the application. Then, when working on other aspects of the application, he can assume that that component or object works as advertised. Working in this kind of environment allows you to isolate and test functionality with confidence rather than just using some high level test cases and hoping none of the fringe cases that were missed cause any errors down the road.

Maintenance

Customers and developers can be so focused on the cost and time to develop and application. The customer always wants it done faster and cheaper. However, it has been shown that 60% to 80% of the time and effort spent on an application is done after initial release – in the maintenance phase. Well designed object oriented code is maintainable. If a bug exists, you only need to fix it in one place. With object oriented development, a change to the implementation is invisible to the rest of the application, so no additional fixes or testing is needed and the rest of the application automatically benefits from the change.

Future Expansion

Most of us have never experienced a project whose scope grows or have a customer who comes back wanting new enhancements. But, for those of us who do, object oriented development can assist here as well. Object oriented development has features and principles that allow for easy expansion of applications through things like encapsulation, inheritance, delegation, and design patterns. In addition, pre-existing modules should not have to be retested as objects only relate to each other through their interface without any knowledge of the implementation of the object.

Wrap Up

This was a lot to cover in a &quot;short&quot; article, but hopefully it has piqued some interest in object oriented development. In future articles, I plan to look at some of the common pitfalls that come with object oriented development (it&rsquo;s really not the end all solution to the world&rsquo;s problems) as well as start looking at some of the major principles of object oriented development with relation to ColdFusion.

A few words of introduction …

Well, it looks like I am official now. Doug asked me to put together an introduction as my first contribution to the soon to be Alagad blog. So, what is there to say then ….

My name is Jeff Chastain (if you have not figured that out yet). I am one of “those” developers who grew up taking summer programming classes as early as 3rd grade for fun. I am not old enough to claim having a Commodore 64 or anything glorious like that – my first computer was an IBM PC with those big 5 1/4 floppy disks running Basic.

I have been working with ColdFusion in a variety of capacities from big Fortune 500 companies to little mom and pop type companies for the past seven years. Before that I received a Computer Science degree and did a fair amount of work in C, C++, and C# as well as classic ASP.

I have a fairly extensive background in object oriented development as well as experience using most of the oo frameworks in ColdFusion including Mach-II and Model Glue. I have also been around the block a few times with different versions of FuseBox, ColdSpring, and Reactor. Add to that expertise with database development, user interface development, and a few other buzz words, and hopefully I will be able to come up with something interesting to contribute to this blog.

With that, I will sign off – Doug already has me buried in project work. When did he say he was hiring more help?

Introducing Jeff Chastain

I would like to take a moment to introduce Jeff Chastain, Alagad’s first employee. You may remember that roughly four weeks ago I blogged about an opening with Alagad. After many interviews with many highly talented individuals (which took up way more time than I anticipated) I extended an offer to Jeff, which he accepted.

Jeff distinguished himself in many ways during the application and interview processes. It’s hard to get into all the reasons why I decided to hire Jeff over some others (and I’m not even sure I should). What I will say is that, from the very first email, Jeff was very clear and direct and he illustrated to me that he knew what he was doing. On top of that Jeff struck me as not being too serious, while still being able to get the job done. I feel very confident that Jeff is the right guy for the job. In the words of Joel Spolsky, Jeff is smart and gets things done.

Later today Jeff will be posting his first blog entry here to introduce himself. Now that he’s started with Alagad he will be a regular poster here on DougHughes.net.

One of Jeff’s responsibilities will be to write at least one technical blog entry per week. DougHughes.net has always been an unofficial bullhorn for Alagad. So, for now, we’ll be posting Alagad-sponsored blog entries here. Eventually we will consolidate the two domains into one shiny new Alagad.com website.

So, look to hear a lot more from myself and Jeff over the coming weeks and months as Alagad begins to grow and take a new shape. The future may well be very interesting!

(Oh, and keep your eye out for more job openings!)

Tag Cloud