Design Patterns and Cold Fusion
Design Patterns and Cold Fusion
ColdFusion
Sean A Corfield
Consultant
1
Patterns describe problems and
solutions
2
Alexander is not a software architect - he is a building architect!
1. Hierarchy of Open Space - big space in front, small space behind
2. Intimacy Gradient - enter into public areas, navigate into private areas
Who am I?
• Freelance Consultant
• Previously:
• Sr Architect, Macromedia IT
• Architect / Developer:
3
Also manager of Bay Area ColdFusion User Group!
What is this about?
• Common problems
• Common solutions
• Trade offs
4
Show of hands:
1. Who’s using ColdFusion 8? 7? 6.1? 5 or earlier?
2. Who’s using CFCs? Who thinks they’re writing OO code? Patterns?
I want to remove some of the mystery around patterns by showing you how pervasive they are - you're
probably already using some patterns without even realizing it. I hope that you will come out of this
session with a better understanding of what patterns are how they can help you in your day-to-day
programming work - and that you will be inspired to learn more about patterns and extend yourself to
become a better developer.
Our roadmap
• Recommended reading
5
Simple, common pattern
examples
6
A common problem
7
A common solution
8
This is just one possible solution - a simple one.
Trade offs
9
Again, there are other possible solutions, more sophisticated solutions, that have different trade offs.
Including header and footer
<h1>Welcome to my site!</h1>
10
Another solution might be to use content variables and a layout but we’re keeping things simple here.
Patterns provide a common vocabulary
11
If we use different names for the same things, we cannot communicate effectively with each other
Pattern: Composite View
<h1>Welcome to my site!</h1>
12
From Core J2EE Patterns - specifically gives the example of JSP includes.
What is a pattern?
13
It's important to remember that a pattern is all four parts together. A pattern is not just a solution.
Patterns may help us figure out one or more possible solutions to any given problem. The
consequences should allow us to figure out better solutions in specific circumstances.
A common problem
14
A common solution
15
Trade offs
16
We can resolve the negative and avoid having objects refer to application scope by “injecting”
dependencies - passing in the other objects they need - when those objects are created.
APPLICATION scope usage
• In Application.cfc’s onApplicationStart():
application.logger = createObject("component","LoggingService");
• Global access:
application.logger.info("This is a common idiom.");
17
Show of hands: who is using Application.cfc?
Still using Application.cfm? You have to use conditional logic and locking to perform initialization at
application startup.
APPLICATION / onApplicationStart()
is a pattern
• Name - Singleton
18
Subclass - or *any* class that provides the same API!
Java has no global variable scope and no built-in infrastructure for initialization at startup (static
members don’t have quite the same semantics). C++ also has different static member semantics. Both
languages require specific code to provide on-demand initialization and prevent multiple instances.
Java Singleton (one possible solution)
import java.util.HashMap;
public class Singleton {
private static HashMap map = new HashMap();
protected Singleton() {
// Exists only to thwart instantiation
}
public static synchronized Singleton getInstance(String classname) {
Singleton singleton = (Singleton)map.get(classname);
if(singleton != null) {
return singleton;
}
try {
singleton = (Singleton)Class.forName(classname).newInstance();
}
catch(Exception e) {
e.printStackTrace();
}
map.put(classname, singleton);
return singleton;
}
}
19
This is a slightly biased comparison - this Java code is more than just a singleton: it is really a factory
that creates a single instance of any class you need. It uses a cache of objects (“identity map” pattern)
to ensure it only creates one instance of each object. But it does not really solve the problem of unique
instances since you can create, say, a MyClass instance independently of the Singleton. “synchronized”
is required - the equivalent of <cflock> in CF.
A common problem
20
A common solution
21
Trade offs
22
Service objects and APPLICATION
scope
if ( success )
name = application.authService.getUser().getFirstName();
23
That’s another pattern!
• Name - Facade
25
Show of hands: who uses an application framework like Fusebox, Model-Glue or Mach-II? You’ll
recognize this...
A common solution
26
Trade offs
27
As before, we can resolve the negative by applying additional design patterns to help simplify the code
(by refactoring and encapsulating the logic elsewhere - such as a framework).
Flying without a framework
<cfinclude template="login.cfm">
<cfelse>
<cfinclude template="#page#.cfm">
</cfif>
28
login.cfm displays a form where users login (and also contains the processing code for logging in,
setting up the user (object) in session scope etc).
Another pattern (of course)
29
Pretty much all the application frameworks implement this pattern - ColdBox, Fusebox, Mach-II,
Model-Glue.
Patterns and languages
30
Patterns are not code!
31
If you look in the books, magazines and blog articles, you will almost always see explanations of
patterns accompanied by code. A lot of people need to see code to “get it” - show of hands: who feels
they learn best by seeing example code?
Unfortunately, with patterns, this can be misleading at best and sometimes downright dangerous.
Patterns inherently have trade offs and each specific implementation of a pattern has additional trade
offs. The example code for any given pattern may just not be a good solution for you - even if the
pattern itself *is* applicable to your situation!
Patterns and languages
32
Patterns are not code - they’re about design - which means they are broadly applicable but not
universally applicable. Composite View is from the Core J2EE Patterns book but is clearly applicable to
ColdFusion - but certainly not all the patterns in that book are applicable to ColdFusion.
An object-oriented bias?
33
“Although design patterns describe object-oriented designs, they are based on practical solutions that
have been implemented in mainstream object-oriented languages like Smalltalk and C++ rather than
procedural languages ... or more dynamic object-oriented languages.” -- GoF
In other words, many patterns have been identified from common solutions in languages like C++,
Java, C# etc (whether Smalltalk is “mainstream” is a matter of opinion!).
Patterns and ColdFusion
34
The difference between a *design* level pattern and a language-specific pattern is not always obvious,
especially when patterns are illustrated by implementations in a single language (GoF is good for this
since it uses Smalltalk and C++ which are very different languages - Fowler less so since it uses two
similar languages: Java and C#).
Which way to go?
• ColdFusion...
• ...like Java?
35
We’re at a fork in the road. We’ve been “raised” to think of ColdFusion (MX+) as a rapid application
development layer on top of Java. Indeed, we hear “ColdFusion *is* Java”. We’ve been conditioned to
think that what’s good for Java is good for ColdFusion - we think we must write OO code and we must
use design patterns and we must follow Java’s lead.
Well, guess what? Not all Java patterns - and I mean that in the broadest sense - are applicable to
ColdFusion. In my opinion, we should look to dynamic languages like Smalltalk and Ruby for
inspiration...
Ruby / Ruby on Rails patterns
• Famously uses Active Record design pattern for managing
persistence of objects and is core to how Rails works
find_by_colA_and_colB_and_colC(arg1,arg2,arg3)
36
Show of hands: Who has heard of Ruby on Rails? Who has used it?
Active Record is broadly applicable (in other languages) but Rails has made it really popular.
<cffunction name="onMissingMethod">
<cfargument name="missingMethodName">
<cfargument name="missingMethodArguments">
<!---
parse col_and_col_and_col...
SQL query with arguments matched to columns
--->
<cfelse>
<!--- no such method: throw exception --->
</cfif>
</cffunction>
37
The full solution is too complex to show on a slide but this should give you an idea of the structure.
onMissingMethod() is invoked when a call is made to a function that is not explicitly defined in an
object. You can then look at the function name and the arguments and decide what to do. Rails uses
this technique to implement a number of helper methods but the “pattern” doesn’t have a name yet.
Patterns and interfaces
38
If you read about patterns, you’ll see interfaces used extensively. You’ll see Java code examples with
interfaces all over the place. You can be forgiven for thinking that you need interfaces to implement
patterns. The “classic” design patterns book used both C++ *and* Smalltalk to illustrate patterns and
neither language has interfaces (C++ has a construct that is similar to an interface but Smalltalk has
no such construct). Ruby does not have interfaces either.
Patterns and interfaces (continued)
39
<cfinterface> specifies the methods a component provides (API) but not how they behave.
<cfcomponent> *implements* the interface to specify the behavior. An interface can have many
implementations. I was an early - and vocal - advocate of adding interfaces. I submitted the original
ER and rallied the community to vote for it. But duck typing is more powerful and appropriate for
ColdFusion - onMissingMethod() lets you implement any methods dynamically.
Selecting and using
patterns
40
Patterns provide guidance
41
This is all about choosing the “best” solution for your particular situation. Or at least the “better”
solution given a number of possible choices. There are no absolute best solutions - the choice
depends on the forces (problem specifics).
Patterns are not just solutions
42
Pattern catalogs
43
When you first start using design patterns, there is the temptation to treat these books like a grocery
list of ingredients that are necessary for a successful application. Remember that design patterns are
about forces and applicability as much as they are about templates for solutions. They can be
inspiration when you’re stuck on a problem - they can provide guidance when you’re not sure which
way to solve a problem. They are not “building blocks”.
Types of patterns
44
I'm not going to go too deep into classification of patterns but I want to give you a sense for how they
are typically organized within the books (catalogs), partly because each book handles it differently.
Design Patterns (Gang of Four)
• Creational patterns
• Structural patterns
• Behavioral patterns
• Presentation tier
• Business tier
• Integration tier
46
The Core J2EE Patterns book is organized very differently and will look much more familiar to
ColdFusion developers because we (mostly) already think in terms of the tiers mentioned in the book.
However, several of these design patterns have appeared as a response to certain problems which are
Java-specific (in particular addressing the overhead of communications in client-server architectures
based on EJB).
Frameworks and
patterns
47
Frameworks are full of patterns
• ...
48
Since patterns are applicable to common problems and offer templates for solutions to those
problems, it should be no surprise that application frameworks - which all solve similar problems -
are implementing a number of common patterns (often in very different ways).
Some specific patterns in frameworks
• ColdSpring
• Tartan
49
Patterns in Reactor
• Abstract Factory
• Active Record
• Factory Method
• Transfer Object
• ...and others
50
Patterns in Transfer
• Data Mapper
• Decorator
• Factory Method
• Identity Map
• ...and others
51
Recommended reading
52
Design Pattern Books (I)
53
Design Pattern Books (II)
Core J2EE Patterns
“Best Practices and Design Strategies”
Deepak Alur, John Crupi, Dan Malik
54
Design Pattern Books (III)
Refactoring to Patterns
Joshua Kerievsky
55
Thank you!
• Any questions?
• Contact me:
• http://corfield.org/
56