<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8131994348885474777</id><updated>2011-10-11T01:18:26.297-07:00</updated><category term='Google MapReduce'/><category term='object orientation'/><category term='design patterns'/><category term='javascript'/><category term='frameworks'/><category term='coldfusion'/><category term='java'/><category term='mocking'/><category term='Google File System'/><category term='web performance'/><category term='Hadoop'/><category term='chimera'/><category term='cfcommons'/><category term='unit testing'/><category term='software design'/><category term='distributed computing'/><category term='quicksilver'/><category term='class diagrams 101'/><category term='mxunit'/><title type='text'>Micky Dionisio's Software Architecture Blog</title><subtitle type='html'>... thoughts on software design, development and everything in between.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-6528083530117433141</id><published>2011-03-16T08:05:00.000-07:00</published><updated>2011-03-25T08:44:18.011-07:00</updated><title type='text'>Talk Techy to Me - Your favorite tech feeds read to you!</title><content type='html'>Hey my fellow tech geeks. Just like you, I love tech. I live and breathe it. It consumes my 9-5 and 5-9. But if your life and job is as crazy as mine, you know that it's tough finding time to catch up on all your tech feeds. If we fall behind for even a couple of days you start to feel guilty and "disconnected". So I sought out a way to try and change that.&lt;br /&gt;&lt;br /&gt;My commute to the Yahoo! campus in Burbank, CA takes about 45 minutes (that's on a good day!). I often load up on audiobooks but sometimes I have A.D.D. and can't focus on listening to one topic at length. Music and radio, get old pretty quick too. While I do appreciate the way that Ryan Seacrest can talk about nothing and make it sound interesting I can't handle it for more than a 15  minutes.&lt;br /&gt;&lt;br /&gt;One day as I was driving home from work it hit me that my time on the road could be better spent catching up my tech feeds. So in classic programmer spirit, I set out to create a mobile app that would read my favorite tech blogs to me while I'm on the road.&lt;br /&gt;&lt;br /&gt;So came the birth of &lt;a href="http://www.talktechytome.com/"&gt;&lt;b&gt;&lt;u&gt;Talk Techy to Me&lt;/u&gt;&lt;/b&gt;&lt;/a&gt;. This version is free of charge while I work on the paid version that is fully customizable. At the time of this posting it currently supports six popular tech feeds:&lt;br /&gt;&lt;br /&gt;1) TechCrunch&lt;br /&gt;2) Official Google Blog&lt;br /&gt;3) High Scalability (for my programming peeps!)&lt;br /&gt;4) Mashable&lt;br /&gt;5) ReadWriteWeb&lt;br /&gt;6) VentureBeat.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.talktechytome.com/"&gt;&lt;b&gt;&lt;u&gt;Give it a whirl&lt;/u&gt;&lt;/b&gt;&lt;/a&gt;, spread the word, and send me some feedback. Remember it's in beta so when you find bugs please contact me and I'll get it sorted out ASAP. And hey, if you like the app and find it useful, a good review wouldn't hurt ;)&lt;br /&gt;&lt;br /&gt;I guess this constitutes my foray into mobile development...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE - By popular demand, Engadget has been added to the list of free feeds!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;-Mick&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.talktechytome.com/"&gt;&lt;b&gt;&lt;u&gt;Talk Techy to Me&lt;/u&gt;&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="https://market.android.com/details?id=com.audiotize.mobile"&gt;&lt;b&gt;&lt;u&gt;Talk Techy to Me in the Android market&lt;/u&gt;&lt;/b&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-6528083530117433141?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/6528083530117433141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=6528083530117433141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/6528083530117433141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/6528083530117433141'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2011/03/talk-techy-to-me-your-favorite-tech.html' title='Talk Techy to Me - Your favorite tech feeds read to you!'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-2910576587965383182</id><published>2011-01-10T09:43:00.000-08:00</published><updated>2011-01-11T01:54:25.642-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='distributed computing'/><category scheme='http://www.blogger.com/atom/ns#' term='Google File System'/><category scheme='http://www.blogger.com/atom/ns#' term='Google MapReduce'/><category scheme='http://www.blogger.com/atom/ns#' term='Hadoop'/><title type='text'>Distributed Computing, Part 1</title><content type='html'>&lt;div style="background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span id="internal-source-marker_0.7434576987288892" style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Abstract&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; vertical-align: baseline;"&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;You've read or heard about them. Distributed computing frameworks or technologies like Hadoop or Google File System (GFS) and Google MapReduce. This series of posts aims to shed some light on when, why and how you would implement distributed computing techniques.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;If most of the systems you've encountered don't deal with storing and processing large amounts of data (&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;terabytes and up)&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt; on a daily basis, or your company chooses to purchase 3rd party data storage and analysis services, then you may not have realized the critical advances that have been made this past decade in the distributed computing field.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;Since this is part 1 of the series, I'll touch on the three most important problems that distributed systems aim to solve. In subsequent posts I’ll dive deep into what sparked it all - Google File System and Google MapReduce. Then we’ll explore an open source distributed computing platform based off of GFS and MapReduce. This platform called Hadoop, was created by Doug Cutting and spearheaded by Yahoo!. Hadoop is used by many technology giants such as Facebook, Twitter, Amazon and IBM to name a few. We’ll eventually take Hadoop out of the lot for a test drive. &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Let’s get our feet wet.&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Problem 1 - High-end servers are expensive&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;No company likes shelling out thousands of dollars for high end servers. 10 years ago, some could say that servers like these were a necessary evil since data collection is the life blood of any organization and all data &lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;i&gt;must&lt;/i&gt;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; be collected at all costs. Enterprises today continue to intake an enormous amount structured and unstructured data per day and it's growing exponentially.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;How do you begin to store massive amounts of data? If we take a look back to the early 2000’s, companies were spending some serious coin to  either build massive fault tolerant storage systems from scratch or enlisting companies like IBM, HP, SAS etc. to help manage and analyze their data. Either way, you needed high-end servers that come with all the bells and whistles. These servers come with a&amp;nbsp;very high total cost of ownership. It costs a fortune to acquire, a fortune to maintain and like always hardware will fail often and need expensive replacement.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; vertical-align: baseline;"&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; vertical-align: baseline;"&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap;"&gt;On top of that, as data capacity limits red line more hardware needs to be acquired and added to the system. Sure, these systems are built for scalability but it's not easy explaining to your CIO that you need another rack full of expensive blades and switches. This type of horizontal scaling gets expensive very quick. Once you're invested in this type of technology stack you are pretty much locked in for the long haul and it's a vicious cycle. You can bank on your ROI margins dropping over time.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Problem 2 - It's tough to efficiently store massive amounts of data&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;I’m not talking about a few hundred thousand gigs. I'm talking about storing and processing terabytes, petabytes or greater&amp;nbsp;of information on a daily basis. The amount of data that is passed over the internet alone is mind boggling. If you can imagine the birth of the internet as being the Big Bang then we haven’t even entered the cooling phase. That is how explosive and ever expanding the internet and modern systems continue to be. According to&lt;a href="http://www.blogger.com/goog_1491872613"&gt; &lt;/a&gt;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;a href="http://www.pcmag.com/article2/0,2817,2361820,00.asp"&gt;studies performed by to Cisco&lt;/a&gt;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;, as of March 2010 the amount of data that is exchanged across the internet per month is *drumroll*... &lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;21 exabytes&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;. &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Wait, what? 21 exabytes per month?! If you were to &lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;a href="http://www.wisegeek.com/what-are-practical-appliations-for-exabytes.htm"&gt;store all of the words ever spoken by human beings since the dawn of time&lt;/a&gt;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;, it would take only &lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;5 exabytes&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;. Cisco supects that in 2013, that number of data exchanged per month on the internet will grow to &lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;56 exabytes&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;That’s a lot of data.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Problem 3 - It's tough to analyze and process massive amounts of data&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: transparent;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Data comes in many formats such as text, audio, video and images that ranges from structured, semi-unstructured and unstructured. How would you begin perform analysis on this data to find patterns across different formats and types? For instance, how do you determine the patterns of a given user given his purchase history (structured data) and surfing behaviors (semi-structured log files)? It’s pretty tough... and costly... and computation could take a long time if resources aren't allocated in an efficient manner. Regardless, companies know that the answers to these questions provide insight that is paramount to their business. It can discover patterns that can be key to understanding markets, drive new strategies, improve business process, perform scientific calculations to enhance offerings etc. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;That’s why companies that regularly deal with massive amounts of data, like Google, started looking for cheaper, more efficient solutions. Their systems needed to be scalable and elastic as ever.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-weight: bold; white-space: pre-wrap;"&gt;Enter Google File System (GFS)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;In 2003, Google published a paper detailing some of the science and design behind “&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;a href="http://static.googleusercontent.com/external_content/untrusted_dlcp/labs.google.com/en/us/papers/gfs-sosp2003.pdf"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;"&gt;The Google File System&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;”. I’ll dive into the GFS in the next post but at a high level, this file system was developed to provide fault tolerant, reliable data storage using clusters of inexpensive commodity servers. Not the high-end servers that cost thousands of dollars. Just simple, affordable rack mountable Linux servers. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;This design that Google developed directly solved problems #1 and #2.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Then Google MapReduce&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;The very next year after Google released it’s paper on GFS, they released another paper called “&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;a href="http://labs.google.com/papers/mapreduce.html"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;"&gt;MapReduce: Simplified Data Processing on Large Clusters&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;”. The purpose of their now patented MapReduce framework is to be able to process and generate large data sets across a cluster of commodity machines in a distrubuted fashion.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;In essence, it is always better to move computation to data rather than moving data to computation. This exploits the benefits of utilizing data locality in a clustered environment.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;It is modeled after the map/reduce strategies of functional programming wherein there are two phases, map then reduce. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;During the map phase, computation is broken up into smaller chunks and sent &amp;nbsp;to all data nodes in the cluster. Since data is distributed across the cluster, computation will be executed in a parallel fashion since each data node has its own subset of data. When each node is done with its computation, the resulting data set then sent to the master node.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;The master node then starts the reduce phase. All information sent back from the data nodes are combined to get the original “answer” or output. In typical cases, this data is saved for processing by another program.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;Google MapReduce solved problem #3 by providing faster computation and analysis using distributed techniques in tandem with GFS.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-weight: bold; white-space: pre-wrap;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-weight: bold; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;- There are three main reasons why’d you want to look into a distributed computing framework.&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;You need cheap, reliable, fault tolerant data storage that scales horizontally.&lt;/span&gt;&lt;/li&gt;&lt;li style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;The amount of data you collect is growing exponentially. (terabytes, petabytes, exabytes and beyond)&lt;/span&gt;&lt;/li&gt;&lt;li style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; list-style-type: decimal; text-decoration: none; vertical-align: baseline;"&gt;&lt;span style="background-color: transparent; font-family: Arial; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;You need to efficiently process and analyze high volumes of unstructured, semi-structured, and structured data.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;- Although various distributed computing techniques have been around for decades they are often proprietary and expensive.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;- Google'&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;s white papers on GFS and MapReduce sparked an open source distributed computing revolution (like Hadoop).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;In the next posts, we’ll explore GFS and MapReduce then introduce you to Hadoop.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;I hope this helps shed a little light on distributed computing and hope that you'll to read the next articles in the series. Until then, happy coding!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; white-space: pre-wrap;"&gt;Micky&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-2910576587965383182?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/2910576587965383182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=2910576587965383182' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/2910576587965383182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/2910576587965383182'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2011/01/distributed-computing-part-1.html' title='Distributed Computing, Part 1'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-1631305462836037149</id><published>2010-04-23T11:22:00.000-07:00</published><updated>2011-06-15T16:47:12.877-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Finding Intersections Destructively / Nondestructively - Java Collections</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;b&gt;What is an intersection?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Mathematical set theory states an intersection is the common elements between given sets. It's stated as such,&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;A&lt;/i&gt;&amp;nbsp;∩&amp;nbsp;&lt;i&gt;B&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;, where A and B are different sets.&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;Visually it looks like this:&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/intersects.png?attachauth=ANoY7crkpFGq0hFAmeh1HZs7ZtYCR9viv5nyYVgPz7C_c4aOW7dsYOXGkGlPQ6NJI9ZWelZ2ofgt8kFJXHynCsOCgIat0thW2LxS97N-noKqR8WQmrXGE75XbOZre99a8K6ylZ3cYK84T5rW9ESii1WNgIQGeGAdoXdUP-LTaSqrFrwD9oPjN37fHaus1sHOKykaXxwyHFzDdYgTJ8ZBCAT-BP0wkFDA0Q%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/intersects.png?attachauth=ANoY7crkpFGq0hFAmeh1HZs7ZtYCR9viv5nyYVgPz7C_c4aOW7dsYOXGkGlPQ6NJI9ZWelZ2ofgt8kFJXHynCsOCgIat0thW2LxS97N-noKqR8WQmrXGE75XbOZre99a8K6ylZ3cYK84T5rW9ESii1WNgIQGeGAdoXdUP-LTaSqrFrwD9oPjN37fHaus1sHOKykaXxwyHFzDdYgTJ8ZBCAT-BP0wkFDA0Q%3D%3D&amp;amp;attredirects=0" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;b&gt;When would you need to calculate intersects?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;Given &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; line-height: normal;"&gt;n&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt; collections, you need to identify only the elements they have in common and ignore the rest.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Admittedly, I'm a bit spoiled coming from a web technology wherein most cases you can just write up some snazzy SQL to find the commonality and return the record set.&amp;nbsp;In a good sized Java application though you'll often have a good amount of objects and data stored using collections in cache, so SQL is out of the question. You may be tempted to go down the road and create some sort of method that looks like so &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;numberOfOccurrences(Set&lt;t&gt;, String)&lt;/t&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;that returns the number of&amp;nbsp;occurrences&amp;nbsp;and you use that number to determine what to drop and what to keep. This &lt;i&gt;could&lt;/i&gt; work but there is a better, more efficient way to achieve this using a built in Java method - &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Set.html#retainAll(java.util.Collection)"&gt;retainAll()&lt;/a&gt;&amp;nbsp;that resides in the Collections interface. Lets see how:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;The code&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/intersects-code.png?attachauth=ANoY7cogqSCi0dJHAIbNe2PdePEHEMz39dwZl1m1G0mtUX6C6mzpyolj1mng7nzPtiUWsOfR6NH_lkG5l8rvZzow94dx0KRhUuqgtxMOz83FNddrm0OY5t5AB55hD4Ds7sWSEyeiC9BryerArmEGZoqwHh11vzgYo-FlVzRjClqTHQ_GsL-gd6xc2CSLtE-qHNIVa7newWwYQ-HZDjV6x5gf2g51kv1bow%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/intersects-code.png?attachauth=ANoY7cogqSCi0dJHAIbNe2PdePEHEMz39dwZl1m1G0mtUX6C6mzpyolj1mng7nzPtiUWsOfR6NH_lkG5l8rvZzow94dx0KRhUuqgtxMOz83FNddrm0OY5t5AB55hD4Ds7sWSEyeiC9BryerArmEGZoqwHh11vzgYo-FlVzRjClqTHQ_GsL-gd6xc2CSLtE-qHNIVa7newWwYQ-HZDjV6x5gf2g51kv1bow%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;We create two sets each holding fruits. You'll see that Apple and Orange are the common elements between the two sets. Make believe these two sets are your collections sitting in cache.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;We create an HashSet called intersection to hold our common values. Since we are created a holding set, we are finding the intersection&amp;nbsp;&lt;b&gt;&lt;i&gt;nondestructively&lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;,&amp;nbsp;which means without modifying the any of sets being compared. Simply instantiate the intersection set passing in set1 as the initializer.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;To find the intersection, all we do is call retainAll(Collection c) passing in the collection to be compared.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Then we print out the intersection results.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Next I show you how to &lt;/span&gt;&lt;i&gt;destructively&lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; find the intersection by using set2 against set1, again using retainAll() and printing out the both sets. You'll see that set2 has been altered.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;b&gt;You should see the following results...&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/intersects-results.png?attachauth=ANoY7cqPZvPd6kcxXe0OBCN2a-pGyGJDbTTQRspsNms4im7y7L0BzQ2duW8PhoT5dtFLX8JtBp0ihnUNML9EY0YAF48Maq7I-fUkW3RaTo-4uBZk-aFA6qcQm_HkbaYW2eGfGsl6f1VBq8m_2yporb8FXb9A-zC9Ke6__VnE8bKIDCTmxn2jcd9jBwFWhKxnc6KsEF7PNlli60zwkmYJCHIbEEeFHBJWsQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/intersects-results.png?attachauth=ANoY7cqPZvPd6kcxXe0OBCN2a-pGyGJDbTTQRspsNms4im7y7L0BzQ2duW8PhoT5dtFLX8JtBp0ihnUNML9EY0YAF48Maq7I-fUkW3RaTo-4uBZk-aFA6qcQm_HkbaYW2eGfGsl6f1VBq8m_2yporb8FXb9A-zC9Ke6__VnE8bKIDCTmxn2jcd9jBwFWhKxnc6KsEF7PNlli60zwkmYJCHIbEEeFHBJWsQ%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;So, there you have it. Pretty painless right?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-1631305462836037149?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/1631305462836037149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=1631305462836037149' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/1631305462836037149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/1631305462836037149'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/04/finding-intersections-destructively.html' title='Finding Intersections Destructively / Nondestructively - Java Collections'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-8787299915200426170</id><published>2010-04-08T15:17:00.000-07:00</published><updated>2010-04-08T15:34:49.944-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Helpful IntelliJ IDEA Shortcuts</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;IntelliJ IDEA Shortcuts&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;After settling in at the new &lt;a href="http://www.yahoo.com/"&gt;gig&lt;/a&gt;, the IDE of choice for my team is &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt;. I've been using Eclipse for many many years now so there has been growing pains because of the simple fact that I was extremely familiar with all the ins-and-outs of Eclipse and the shortcuts they offered. After a month or so of using IntelliJ, I'm getting more comfortable with it. I found myself writing these notes on a scratch pad and figured I post an entry on it before I spill hot coffee all over my notepad and start crying like a little baby. Without further ado, heres my list:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Various Fixes - alt+enter&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;This tool is equivalent to ctrl+1 in Eclipse and acts as a kind of quick fix tool for you. You'll probably use it the most for the following:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Adding import declarations.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;If code is highlighted yellow, IntelliJ is suggesting that you can possibly write your code in a more efficient manner. Simply double click the piece of code and hit alt+enter. This will give you some refactoring options.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Code Complete - ctrl+shift+enter&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;This nifty shortcut will complete syntactical code for you such as closing braces during a method declaration, or by typing "&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;if&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;" then hitting ctrl+shift+enter will close add the&amp;nbsp;parentheses&amp;nbsp;for evaluation as well as the open and close brackets for the if block. Probably does a lot more but that's what I use this for the most.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Dumb Auto Complete - ctrl+space&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;This "dumb" autocomplete usually appears automatically after you type the "." after an object variable. For instance assume&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;someArrayList&lt;/span&gt;&amp;nbsp;is of type&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ArrayList&lt;string&gt;&lt;/string&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;and when typing&amp;nbsp;"&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;someArrayList.&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;", suggestions are offered based off of that object appear.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Smart Auto Complete - ctrl+shift+space&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;This is really useful one. It acts similar to the dumb complete key but there's is a crucial difference.&amp;nbsp;This shortcut narrows suggested methods down by type.&amp;nbsp;For instance, let's take our "someArrayList." example again. Shortly after the period you will get suggested methods based off of the&amp;nbsp;&lt;b&gt;&lt;i&gt;entire&lt;/i&gt;&lt;/b&gt;&amp;nbsp;ArrayList object. This is the the expected "dumb" auto complete view as I explained in the previous shortcut. However when you instead press ctrl+shift+space, IntelliJ will actually filter those methods based on the type in which the return is being assigned to. So if we were create a integer variable to store the size of &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;someArrayList &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;like so "&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;int size = someArrayList.&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;", smart complete will only expose methods off of the ArrayList object which will only return an&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;int&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;value like &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;size(), hashCode(), lastIndexOf()&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;and &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;indexOf()&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;... &lt;b&gt;&lt;i&gt;Very useful!&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;View Java Docs - highlight method or class+ctrl+q&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Nuff' said.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Highlight instances of a term - highlight item+ctrl+shift+f7&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Nifty shortcut that will search, locate and highlight all the matching terms you've selected within a file.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Refactor a piece of code - shift+f6&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Highlight code and shift+f6 to view suggested refactoring options.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Extract expression to a method - ctrl+alt+m&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;There are times where you find yourself writing inline, procedural code that should be in its own method but you just don't get around to extracting it because you're lazy. This awesome shortcut provides a very simple way to highlight code, turn it into a method update your references to it. Just like Geico says, "so easy a caveman could do it". Do it!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Select word the cursor is currently on - ctrl+w&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;When you really don't feel like using your mouse... geek.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Cycle through open editors - ctrl+left arrow or ctrl+right arrow&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Nuff' said.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Cycle through methods in a file -ctrl+up arrow or ctrl+down arrow&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Nuff' said.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Once debug servers are setup to launch debug shift+f9+enter&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Launches debug server.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Terminate the debug server - ctrl+f2&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Nuff' said.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;And finally, the usual suspects...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Search for a Java Class - ctrl+n&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Search for file in project - ctrl+shift+n&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Search for term within project - ctrl+shift+f&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Comment out code - highlight lines+ctrl+/&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;There you have it. Hopefully this can help guide IntelliJ noobs like myself in the right direction. I'm still feeling my way through this tool so if anyone has any other useful tips for IntelliJ, please post a comment. I'd love to hear them!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;PEACE.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;-Mick&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-8787299915200426170?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/8787299915200426170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=8787299915200426170' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/8787299915200426170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/8787299915200426170'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/04/helpful-intellij-idea-shortcuts.html' title='Helpful IntelliJ IDEA Shortcuts'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-7231390664007853774</id><published>2010-02-25T14:05:00.000-08:00</published><updated>2010-02-25T22:41:55.487-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cfcommons'/><category scheme='http://www.blogger.com/atom/ns#' term='chimera'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><title type='text'>Code coverage &amp; cyclomatic complexity calculations coming to ColdFusion</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;We've heard it over and over again that ColdFusion 9 has made excellent headway in terms of providing engineers with great support to execute proper object orientation without all the bloat. Along with CF9 and awesome unit testing tools like &lt;a href="http://mxunit.org/"&gt;MXUnit&lt;/a&gt;&amp;nbsp;and &lt;a href="http://blog.coldbox.org/post.cfm/introducing-mockbox-the-coldbox-mocking-framework"&gt;Mockbox&lt;/a&gt;, unit testing is really becoming a mainstay for a lot of ColdFusion applications and I hope that it continues to stay that way.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;However one critical and often overlooked aspect of unit testing is &lt;b&gt;code coverage&lt;/b&gt; and &lt;b&gt;cyclomatic complexity&lt;/b&gt; calculation. Often times, developers feel that just because they've got a good amount of tests that its "good enough" without taking a step back and asking themselves questions like:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Are my unit tests covering every line of code?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Am I testing for every distinct path of execution inside a method?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Is my code written efficiently or is there room for improvement?&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Perhaps you've asked yourself these questions but didn't know what the answers to it are. Well the answers lie in code coverage and cyclomatic complexity...&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Code Coverage&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Code coverage metrics show you the percentage of code that is covered and &lt;b&gt;not covered&lt;/b&gt; by your unit tests. This is extremely beneficial to identifying the "holes" in your unit tests. Uncovered lines means no unit tests exist for those lines which is an indirect measurement of code and test quality. If you have not tested it, then it's at risk for error and should be addressed asap before rolling that beaut into production.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Cyclomatic Complexity&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Also known as CCN, it answers the question of "is my code written efficiently?". To boil it down, take a method and imagine all the ways you as the developer can cause simple or complex conditionals. Meaning if's, switches, nested if's, inline method calls to other methods etc...&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;The basic idea is that each of these "conditional" execution paths add to code complexity. In the programming world you always want to keep code complexity to a minimum because the more complex conditional code you have riddled throughout your code base, the less maintainable it is and extensibility becomes almost impossible. Your software becomes &lt;b&gt;&lt;i&gt;risky&lt;/i&gt;&lt;/b&gt; as more complex paths are added resulting in unhappy customers and stressed out engineers - and I think you'd agree with me that stress sucks and in a volatile software, release days are nail biters...&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;So the idea is that you run CCN metrics on your classes and it will spit out a number for you. The standard is that the number should be under 10 and anything over that should be flagged, reviewed and more often that not re-written.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Code Coverage and CCN coming to ColdFusion&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;In languages like Java and C#, there are tools that provide this level of support but not for ColdFusion. That is until now!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Written with Java and ColdFusion, cfcommon's &lt;a href="http://cfcommons.org/"&gt;Chimera&lt;/a&gt;&amp;nbsp;project will provide you with that critical line of defense to help engineers identify parts of their code that need unit tests and/or need to be re-factored because of too much complexity.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Attached is a preliminary screenshot of Chimera playing nicely with MXUnit tests.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;img alt="Chimera ColdFusion Code Coverage Analysis" src="http://cfcommons.org/site/view/images/chimera.png" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Although this image shows ColdFusion code writted in tags, we will also be providing script support as well ;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Please stay tuned as we will be releasing &lt;a href="http://cfcommons.org/index.cfm/module/chimera"&gt;Chimera&lt;/a&gt;&amp;nbsp;BETA very soon and you can check out&amp;nbsp;&lt;a href="http://cfcommons.org/"&gt;cfCommons&lt;/a&gt;&amp;nbsp;in the meantime!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;PEACE.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Mick&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-7231390664007853774?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/7231390664007853774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=7231390664007853774' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/7231390664007853774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/7231390664007853774'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/02/code-coverage-cyclomatic-complexity.html' title='Code coverage &amp; cyclomatic complexity calculations coming to ColdFusion'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-5202899676383281801</id><published>2010-02-23T08:51:00.000-08:00</published><updated>2010-02-23T09:02:29.764-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cfcommons'/><title type='text'>Building a cfcommons application - Battlefield Part I</title><content type='html'>&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif; font-size: x-large;"&gt;Overview&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;a href="http://cfcommons.org/"&gt;cfcommon's &lt;/a&gt;pluggable architecture allows you to harness many of its stable modules and plugins bit by bit, piece by piece without inheriting bloated code and unnecessary overhead. Each module is carefully crafted and engineered to ensure stability and developed with clear and concise features. Gone will be the days of installing multiple frameworks for different feature sets and having to deal with the baggage of worrying about collisions and incompatibility issues that can occur between them.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;To get a full appreciation for what cfcommons is all about, in the next few posts we will create a cfcommons application from the ground up, utilizing each module and plugin "as needed". You will see how &lt;i&gt;&lt;b&gt;incredibly simple&lt;/b&gt;&lt;/i&gt; it is to not only plug and play features, but also how each module plays nicely with each other.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: left;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Without further ado let's create our application using first up cfcommon's&amp;nbsp;&lt;a href="http://cfcommons.org/index.cfm/module/context/neodymium/plugin/"&gt;Neodymium &amp;nbsp;&lt;/a&gt;- an automatic dependency injection plugin.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;dependency injection, what is it?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Also known as "Inversion of Control", is one of the most critical pieces in building clean, enterprise level object oriented software. If you are unclear about dependency injection, I encourage you to first &lt;/span&gt;&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;read&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; about what it's all about.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; &lt;/span&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Many languages have frameworks that enable your software to leverage dependency injection like Java's Spring to .NET's Castle Windsor to ColdFusion's Lightwire. The old way was to "wire" up these dependencies via XML or bean configuration which is extremely wasteful in terms of keystrokes causing you to run into either a gigantic bean config file or a gigantic XML. A good way to induce coder's coma...&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Yea yea, you can break things up into separate XML files or use "shortcut" attributes to help lessen the bloat but still, we're talking about making what will be a thousand line XML template down to hundreds...at least for awhile until it grows even bigger. Thanks, but no thanks..&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;what do you mean by "automatic" dependency injection?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Neodymium allows you &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;to simply annotate your class properties with the right type and it will &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;automatically&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; inject those properties for you during application startup or reload. Once you ask the factory for a bean it will return to you the object with its dependencies properly injected for you.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;so no XML mappings or bean config??!?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;None. Nada. Zilch.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;what if you don't want objects to automatically be injected?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Then use the exclude annotations.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;what if I'm l337 and I want the type to be an interface?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Then use the combination of @type and @implementation, which gives the path to the concrete class. You're so 1337...&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Battlefield Application - Part I&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Let's create a cfcommons app shall we?! I didn't want to use the played out car/student/shapes/{insert boring, mind numbing tutorial topic here}, so I opted to go with a battlefield app which I'm hoping we can turn it into some sort of army game over the next few posts.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;We will start by implementing automatic dependency injection via Neomydium. &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;The battlefield code is also available for you to &lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;a href="http://sites.google.com/site/mickydionisio/fs-1/battlefield-part-1.zip"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;download &lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;and install as you&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;follow along...&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;install cfcommons and create the web directory for this tutorial&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Install the&amp;nbsp;&lt;/span&gt;&lt;a href="http://cfcommons.org/index.cfm/download"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;cfcommons core modules library&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&amp;nbsp;into your web root.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Create a &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;/battlefield/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; directory under your web root. This will be the directory that houses our sample application.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Under create a &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;/model/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; directory. Here is where we will put all our classes and interfaces.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Under the &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;/model/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; directory create an &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;/interfaces/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; directory. Self explanatory...&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;create the context config XML file&lt;/b&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;This file is the central file that you will drop the cfcommon plugins.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;In &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;/battlefield/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;, create a&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; /config/ &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;directory&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Inside the &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;/config/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; directory create an XML file called &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;context-config.xml&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; that looks like so:&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/context.png?attachauth=ANoY7coXcp1XgsD0tFgpbK8GKXJlCYvXLtWO6WuTyIbe9_QSzKieN2KuaDxGoohh05s3X5sLUHrI5dHa3DRpgvXpMLiqD03KDmiKsIsB9tsV5Wann2WL_f2atVbbps-cxMOYQjVvLjRMXNv4xqAe6Ljpim9lbFhu27PAjf7bYLgZxDObno9KF-WR8rCNrArkFMxtsbGR17XOhg7YQKuuK26d-5VBcS3HEg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;img border="0" height="133" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/context.png?attachauth=ANoY7coXcp1XgsD0tFgpbK8GKXJlCYvXLtWO6WuTyIbe9_QSzKieN2KuaDxGoohh05s3X5sLUHrI5dHa3DRpgvXpMLiqD03KDmiKsIsB9tsV5Wann2WL_f2atVbbps-cxMOYQjVvLjRMXNv4xqAe6Ljpim9lbFhu27PAjf7bYLgZxDObno9KF-WR8rCNrArkFMxtsbGR17XOhg7YQKuuK26d-5VBcS3HEg%3D%3D&amp;amp;attredirects=0" width="200" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt; &lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;In this XML you'll see we've declared both a development and production environment &lt;/span&gt;&lt;i&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;and told the Battlefield application that we will use the Neodymium automatic dependency injection plugin via one simple plugin tag.&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Once complete, your directory structure should look like so (minus the .settings, that's eclipse stuff.):&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-dir.png?attachauth=ANoY7crFYF7kyQbrPEMrMZP3Jr1jc4SA60cjA8fVUhQlVF1-03bbwbRZprH2SvS3qvxvlyxR4Vg6bD4ZR4sI_ZLUOVcNd0LoKQEKh0CYI6zMmxP4WHZuYsMFkz-Q6y3MtwsmXQny3s7fV-opAM_BoVqhS51eRTd2SC8eiYNj6LiAniP6qoGPSSe0xwQHlf7Q5H_aYn8KIRzNwMugpXOC1MbiebJVworqFQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-dir.png?attachauth=ANoY7crFYF7kyQbrPEMrMZP3Jr1jc4SA60cjA8fVUhQlVF1-03bbwbRZprH2SvS3qvxvlyxR4Vg6bD4ZR4sI_ZLUOVcNd0LoKQEKh0CYI6zMmxP4WHZuYsMFkz-Q6y3MtwsmXQny3s7fV-opAM_BoVqhS51eRTd2SC8eiYNj6LiAniP6qoGPSSe0xwQHlf7Q5H_aYn8KIRzNwMugpXOC1MbiebJVworqFQ%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;ok the good stuff now. let's take a look at what we are about to build.&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;ol&gt;&lt;/ol&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-class-diagram.png?attachauth=ANoY7cq1RtavViv0P1LA3D5P86ibtDuMKSokzk-gg_Javn2i-fmf1OlSTsMz8mbBr-t1R48jB4EWq6Hta3Z2u6JA5OmA6e0Mz9DU4scCMKrEYk6szLV4bqAEMZrl0sjP7ErpDvAV6HEiGj5Ea9Lz_EDZsbR0QvXWeG5iwqt7odUfachfk0OxcfQY1lEdw66i1z2VwLggvCLI8HljVgzeut7Y-hYGOYHwRw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="187" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-class-diagram.png?attachauth=ANoY7cq1RtavViv0P1LA3D5P86ibtDuMKSokzk-gg_Javn2i-fmf1OlSTsMz8mbBr-t1R48jB4EWq6Hta3Z2u6JA5OmA6e0Mz9DU4scCMKrEYk6szLV4bqAEMZrl0sjP7ErpDvAV6HEiGj5Ea9Lz_EDZsbR0QvXWeG5iwqt7odUfachfk0OxcfQY1lEdw66i1z2VwLggvCLI8HljVgzeut7Y-hYGOYHwRw%3D%3D&amp;amp;attredirects=0" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Simple right? We are going to create a soldier that "has-a" weapon. For all intents and purposes, let's usimagine that by default the Soldier should always be equipped with a knife by default. Meaning every time we need an instance of a Soldier from the bean factory, let's always make sure it has a knife object attached to it.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;where the rubber meets the road...&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-soldier.jpg?attachauth=ANoY7crhy8v5JpQZtNiuFPRGCW6HOKcp7kHpYSDqAezkcBLBkQoXVAt46NVRCvUpuAt7xRk-PMqrn1EaDbqLvNZ73I0sepCfT_i1c7cD9QaSP6C7edAucFpg6UWgN040AUJc-eoFWkNJ0LpTx5IbjRE6jjtrhXyaUAlbhd8vgG9gOv8bKMaBCiUVNx4sqi9LtP249ogJIwlzht-M2krl_vZ2kkE0HMMDbQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;img border="0" height="168" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-soldier.jpg?attachauth=ANoY7crhy8v5JpQZtNiuFPRGCW6HOKcp7kHpYSDqAezkcBLBkQoXVAt46NVRCvUpuAt7xRk-PMqrn1EaDbqLvNZ73I0sepCfT_i1c7cD9QaSP6C7edAucFpg6UWgN040AUJc-eoFWkNJ0LpTx5IbjRE6jjtrhXyaUAlbhd8vgG9gOv8bKMaBCiUVNx4sqi9LtP249ogJIwlzht-M2krl_vZ2kkE0HMMDbQ%3D%3D&amp;amp;attredirects=0" width="320" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Line 3 baby, it's where the magic happens. By simply annotating the property, Neodymium will register Soldier beans with its dependencies properly injected.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;test drive - index.cfm&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-index.png?attachauth=ANoY7cro3jmScaPLZdLV_AxeZ21fmOkO9adq_ns0_P3LqR5YfD1wo7zdaGcKrP6H7ByDt5LQme-nKrTmo6y7lV7fwBnf5CzPfhGemh3aKpb8-ojkUijLMICLS3cS9H2jr-4VOZdccK9fQ_5ZWyGRgxcTDIjX2Hg-Gx8YJ6xN2erRC8y9h6WZjSW3-BllWG9g-rLydZyp5l21nhrswxVBNA-kb9xnveA9jA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-index.png?attachauth=ANoY7cro3jmScaPLZdLV_AxeZ21fmOkO9adq_ns0_P3LqR5YfD1wo7zdaGcKrP6H7ByDt5LQme-nKrTmo6y7lV7fwBnf5CzPfhGemh3aKpb8-ojkUijLMICLS3cS9H2jr-4VOZdccK9fQ_5ZWyGRgxcTDIjX2Hg-Gx8YJ6xN2erRC8y9h6WZjSW3-BllWG9g-rLydZyp5l21nhrswxVBNA-kb9xnveA9jA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;img border="0" height="157" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-index.png?attachauth=ANoY7cro3jmScaPLZdLV_AxeZ21fmOkO9adq_ns0_P3LqR5YfD1wo7zdaGcKrP6H7ByDt5LQme-nKrTmo6y7lV7fwBnf5CzPfhGemh3aKpb8-ojkUijLMICLS3cS9H2jr-4VOZdccK9fQ_5ZWyGRgxcTDIjX2Hg-Gx8YJ6xN2erRC8y9h6WZjSW3-BllWG9g-rLydZyp5l21nhrswxVBNA-kb9xnveA9jA%3D%3D&amp;amp;attredirects=0" width="400" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Here, we are:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Creating an instance of the PluggableContextFactory based off of our context-config.xml we created earlier with the Neodymium plugin installed.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Then we simply ask the context factory for the soldier object.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Then dumping the Soldier and it's weapon.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;index.cfm results&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-res.png?attachauth=ANoY7cpX5SodiWCpf64qfxYNeS8avqDmb0oag6uaelj5qaxPUib4AIuZv9NdtdE5N6j3nic4GPNOYD5Isi3AGSA7RUa10BR-hJLNfWoVIAxqhLYGWTLDY4NU0suE7_6ZK92RWdZ94Mp6h7NmIlKlQ7G1D4nGUsQIwjJ7YVoDwHwZJ8llzs8i3p1q5e8T2qaaanS0e0JcIepIq6w_gM5IF9EftZrSHwMEcQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-res.png?attachauth=ANoY7cpX5SodiWCpf64qfxYNeS8avqDmb0oag6uaelj5qaxPUib4AIuZv9NdtdE5N6j3nic4GPNOYD5Isi3AGSA7RUa10BR-hJLNfWoVIAxqhLYGWTLDY4NU0suE7_6ZK92RWdZ94Mp6h7NmIlKlQ7G1D4nGUsQIwjJ7YVoDwHwZJ8llzs8i3p1q5e8T2qaaanS0e0JcIepIq6w_gM5IF9EftZrSHwMEcQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-res.png?attachauth=ANoY7cpX5SodiWCpf64qfxYNeS8avqDmb0oag6uaelj5qaxPUib4AIuZv9NdtdE5N6j3nic4GPNOYD5Isi3AGSA7RUa10BR-hJLNfWoVIAxqhLYGWTLDY4NU0suE7_6ZK92RWdZ94Mp6h7NmIlKlQ7G1D4nGUsQIwjJ7YVoDwHwZJ8llzs8i3p1q5e8T2qaaanS0e0JcIepIq6w_gM5IF9EftZrSHwMEcQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-res.png?attachauth=ANoY7cpX5SodiWCpf64qfxYNeS8avqDmb0oag6uaelj5qaxPUib4AIuZv9NdtdE5N6j3nic4GPNOYD5Isi3AGSA7RUa10BR-hJLNfWoVIAxqhLYGWTLDY4NU0suE7_6ZK92RWdZ94Mp6h7NmIlKlQ7G1D4nGUsQIwjJ7YVoDwHwZJ8llzs8i3p1q5e8T2qaaanS0e0JcIepIq6w_gM5IF9EftZrSHwMEcQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;img border="0" height="260" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/neo-res.png?attachauth=ANoY7cpX5SodiWCpf64qfxYNeS8avqDmb0oag6uaelj5qaxPUib4AIuZv9NdtdE5N6j3nic4GPNOYD5Isi3AGSA7RUa10BR-hJLNfWoVIAxqhLYGWTLDY4NU0suE7_6ZK92RWdZ94Mp6h7NmIlKlQ7G1D4nGUsQIwjJ7YVoDwHwZJ8llzs8i3p1q5e8T2qaaanS0e0JcIepIq6w_gM5IF9EftZrSHwMEcQ%3D%3D&amp;amp;attredirects=0" width="320" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Viola! Notice that the Soldier object has a Knife object dependency attached to it. Automatic dependency injection baby...&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;download the code&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://sites.google.com/site/mickydionisio/fs-1/battlefield-part-1.zip"&gt;Battlefield Part 1&lt;/a&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="color: black;"&gt;- be sure to also install the latest cfcommons module library&lt;/span&gt; &lt;a href="http://cfcommons.org/index.cfm/download"&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif; font-size: x-large;"&gt;conclusion&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Hopefully you are starting to see the power behind cfcommons. With one simple declaration in the context-config.xml, we've added dependency injection support&lt;/span&gt;&lt;i&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: black;"&gt; in literally a few seconds.&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Neodymium also supports the usual suspects when it comes to dependency injection like singletons, interface based typing and custom annotations. &lt;/span&gt;&lt;a href="http://cfcommons.org/index.cfm/module/context/neodymium/plugin/"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Find out more about it here.&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;In Part II, we will build upon this application and integrate the &lt;/span&gt;&lt;a href="http://cfcommons.org/index.cfm/module/context/mvc/plugin/"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;SimpleMVC&lt;/span&gt;&lt;/a&gt; &lt;span class="Apple-style-span" style="color: black;"&gt;then perhaps &lt;/span&gt;&lt;a href="http://cfcommons.org/index.cfm/module/context/security/plugin/"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;SimpleSecurity&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Visit&amp;nbsp;&lt;a href="http://cfcommons.org/"&gt;http://cfcommons.org/&lt;/a&gt;&amp;nbsp;for more information or to be a contributor.&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Till next time, later peeps!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Mick&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-5202899676383281801?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/5202899676383281801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=5202899676383281801' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/5202899676383281801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/5202899676383281801'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/02/building-cfcommons-application.html' title='Building a cfcommons application - Battlefield Part I'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-2427673377875069425</id><published>2010-02-19T12:50:00.000-08:00</published><updated>2010-02-19T15:58:28.642-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cfcommons'/><title type='text'>cfcommons Reflection API</title><content type='html'>&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif; font-size: x-large;"&gt;what is reflection?&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Reflection is the ability for a program to introspect details about itself (the source code), understand it and even modify it.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;is it possible in ColdFusion?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Yes, don't get it twisted :P&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;really, how?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;In ColdFusion functions like &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;getComponentMetaData()&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;getMetaData()&lt;/span&gt; that will provide you with source level information such as method names, arguments name, type information, annotations, class&amp;nbsp;hierarchy&amp;nbsp; etc. So when you call one of those methods you are essentially using reflection. You are asking the object to reflect upon itself and let you, the developer, know about it.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;ok, but how is this powerful?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Simple - let's take cfcommon's lightweight &lt;b&gt;&lt;i&gt;automatic&lt;/i&gt;&lt;/b&gt; dependency injection plugin called &lt;a href="http://cfcommons.org/index.cfm/module/context/neodymium/plugin/"&gt;Neodymium&lt;/a&gt;. The problem was how do we provide a lightweight &lt;b&gt;&lt;i&gt;automatic&lt;/i&gt;&lt;/b&gt; dependency injection plugin with these goals in mind:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;ul&gt;&lt;li&gt;It must be lighting FAST&lt;/li&gt;&lt;li&gt;Absolutely zero XML&lt;/li&gt;&lt;li&gt;It must be lighting FAST&lt;/li&gt;&lt;li&gt;Absolutely zero bean configuration&lt;/li&gt;&lt;li&gt;It must be lighting FAST&lt;/li&gt;&lt;li&gt;Absolutely no other feature other than dependency injection to bloat the code&lt;/li&gt;&lt;li&gt;It must be lighting FAST&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;By leveraging cfcommon's reflection API, at application start/reload we are able to to reflect upon all classes (cfc's) in a designated directory (package) check to see that if they have a type attribute associated to it then we will &lt;b&gt;&lt;i&gt;automatically &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;inject those dependencies into the object factory. If there was a doNotInject annotation then we simply do nothing.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;b&gt;&lt;i&gt;See how powerful that is? Extremely. Oh and did we mention it's freaking fast?&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;if ColdFusion already gives us the ability, why use cfcommons?&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Although ColdFusion's reflective functions are helpful, there is a lot of uneccessary code you need to write to get at specific information. &lt;/span&gt;cfcommon's Reflection API provides you with object oriented classes that help you get at what you need with one method call&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;. Some examples:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Need to check if a class is annotated? use &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;isAnnotated()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Need to get all annotated methods of a class? use &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;getAnnotatedMethods()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Want to know if a method has an annotation? use &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;hasAnnotation()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Need the superclass?&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; use getSuperClass()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;The list goes on and on. &lt;a href="http://cfcommons.org/site/static/docs/reflection/"&gt;You can check out the API source documentation here.&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;sky's is the limit&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;The goal of the cfcommons project is to push the limits forward for ColdFusion. It's a call to developers to think outside the box and to help provide stable, reusable &amp;nbsp;modules using a powerful platform. Reflection is just one of many modules available to you.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;So give it a try it! Can you think of a problem that you can solve via reflective methods?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;i want more information!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;A &lt;b&gt;must &lt;/b&gt;read about Reflection API &lt;b&gt;WITH&lt;/b&gt; examples -&amp;nbsp;&lt;a href="http://cfcommons.org/index.cfm/module/reflection"&gt;reflection documentation&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Questions?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Brian Carr, &amp;nbsp;the mastermind behind cfcommons, &amp;nbsp;can always be reached via:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;email : brian@cfcommons.org&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;twitter: @cfcommons&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;You can also reach me at micky@cfcommons.org or on twitter (@mickydionisio).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Thanks peeps!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-2427673377875069425?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/2427673377875069425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=2427673377875069425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/2427673377875069425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/2427673377875069425'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/02/cfcommons-reflection-api.html' title='cfcommons Reflection API'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-4973570765950477088</id><published>2010-02-18T13:04:00.000-08:00</published><updated>2010-02-19T15:59:11.225-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cfcommons'/><title type='text'>ColdFusion Commons Project Released</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Over the past few months I've been involved with a new project called the &lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;b&gt;ColdFusion Common Modules Project&lt;/b&gt;&lt;/span&gt;. Inspired by Java's &lt;a href="http://www.springsource.org/"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Spring&lt;/span&gt;&lt;/a&gt; framework, &lt;a href="http://commons.apache.org/"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Apache Commons&lt;/span&gt;&lt;/a&gt;, and ColdFusion's &lt;a href="http://quicksilver.riaforge.org/index.cfm"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Quicksilver&lt;/span&gt;&lt;/a&gt; framework. What exactly is it?&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif; font-size: x-large;"&gt;ColdFusion Common Modules Project&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;The ColdFusion Common Modules project (&lt;b&gt;&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;CFCommons&lt;/span&gt;&lt;/b&gt;) is a collection of initiatives intended on producing &lt;b&gt;reusable&lt;/b&gt;,&lt;b&gt; stable&lt;/b&gt;, &lt;b&gt;object oriented&lt;/b&gt; ColdFusion component libraries.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif; font-size: x-large;"&gt;What's in it for you?&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;i&gt;This project is intended to provide ColdFusion developers with highly scalable, reusable components. Components that are created for &lt;/i&gt;&lt;b&gt;&lt;i&gt;YOU&lt;/i&gt;&lt;/b&gt;&lt;i&gt;, by &lt;/i&gt;&lt;b&gt;&lt;i&gt;YOU&lt;/i&gt;&lt;/b&gt;&lt;i&gt;.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt; &lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: medium;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;You as a CFCommons developer will make an effort to ensure that your components/plugins &amp;nbsp;play nicely with other plugins and that your interfaces are extremely stable and reusable by implementing proper object orientation techniques and interfaces. This ensures that any developer using a CFCommons component can rest easy knowing that installing a new component won't break ten other CFCommon components.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;In its first release, CFCommons offers a handful of features and Context plugins that range from simple MVC to layout management, from&amp;nbsp;automatic dependency injection to ReST web services, from templating to service level transactionality. &amp;nbsp;CFCommon's plug and play architecture allows you to produce decoupled plugins by utilizing the CFCommon Context and Reflection API. The sky is the limit on what you can create.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;Let's take a look at the CFCommons modules...&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;CFCommons Modules&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Context &lt;span class="Apple-style-span" style="font-weight: normal;"&gt;- The CFCommons Context is a reflective, pluggable application platform. This is the heart of CFCommons.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Reflection&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; - The Reflection API is a small set of components that wrap the standard structure output of the native CF reflection methods, getMetaData() and getComponentMetaData() and provide an object-oriented and enhanced view into ColdFusion component (.cfc) meta-data.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;AOP&lt;/b&gt; - The AOP module brings full-featured stand-alone Aspect Oriented Programming    facilities to ColdFusion with an API that is both easy    to understand and implement and that is not dependent upon any other    libraries or frameworks.&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Leverages ColdFusion dynamic language features to provide a programmatic join point model which supports before, after and around join points.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Fast and easy applicaiton of advice to pointcuts.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Advice types are custom function references, or methods that exist on object instances. No need to have advice implement an interface or extend another AOP API specific type.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;Templating&lt;/b&gt; - The cfcommons templating module promotes fixed content reuse by providing a means to inject variable content   at specified locations within given text. Perfect for the implementation of semi-mutable views such as form-letters or   email templates, this module provides an object-oriented set of Components that promote effective templating.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;Faceplait&lt;/b&gt; -&amp;nbsp;Faceplait is a stand-alone, framework agnosting layout manager.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;HTTP&lt;/b&gt;-&amp;nbsp;This module provides library components who's purpose it is to make working with common HTTP tasks, easy.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;Chimera &lt;/b&gt;- A Java/CF based code coverage and cyclomatic complexity tool. (Built to place nicely with MXUnit.) &lt;b&gt;&lt;i&gt;MXUnit peeps, we'll be reaching out soon so stay tuned!&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Here's a quick screen of chimera:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://cfcommons.org/site/view/images/chimera.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://cfcommons.org/site/view/images/chimera.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Want a test drive? Take Weyland out for a spin.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;To get up and running quickly install Weyland along with the CFCommons core. Weyland is a simple HTTP Context with&amp;nbsp;MVC, automatic&amp;nbsp;dependency injection, layout and security support.&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Drop the org directory in cfcommons into your web root.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Drop the weyland directory inside of root as well.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;The directory structure should look like so:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/install.png?attachauth=ANoY7cox58lfw3J6tuRjCOZ7MRjeD0QJwvtUSZh3NWVglRnVzz60iPF_ZxgZ-CP2sjq848lTVf9JcD_pfQ0Q_vxJy7t2a639KtiXErxjyNXzXQiJF-q3wvBEjSrfCdNgFzS-PSUWJs0DG9v4it_azPdem490vFiZF2Vqjd7erH3FOtWqqxJ2MOfJFd3HbAdVzj36vEnEvqDJJ-xRw8SkoFjmjrN7xDSs7w%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/install.png?attachauth=ANoY7cox58lfw3J6tuRjCOZ7MRjeD0QJwvtUSZh3NWVglRnVzz60iPF_ZxgZ-CP2sjq848lTVf9JcD_pfQ0Q_vxJy7t2a639KtiXErxjyNXzXQiJF-q3wvBEjSrfCdNgFzS-PSUWJs0DG9v4it_azPdem490vFiZF2Vqjd7erH3FOtWqqxJ2MOfJFd3HbAdVzj36vEnEvqDJJ-xRw8SkoFjmjrN7xDSs7w%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;And after visiting http://localhost/weyland you shuold see this:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/weyland.png?attachauth=ANoY7coao3of3pLJ1uuMokKD1M2znLCpr8b0Ozte33lLoAMGnYg-3rPiK0jg1fF785nUg2XUHI-lVAcOE5Ae9g7eAre5m6iDJNcP3WC-yBoAvleZJ2Kqqdke-VhC6z92OvLpeBpSlgLZg2wM7m4TTozMiRYAEFyi-Tkeu3kUXkxViDyAHEmogwz9oDCVJFndqTVP07sCnUNS9RFeAEphhiftNampUi0RsQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/weyland.png?attachauth=ANoY7coao3of3pLJ1uuMokKD1M2znLCpr8b0Ozte33lLoAMGnYg-3rPiK0jg1fF785nUg2XUHI-lVAcOE5Ae9g7eAre5m6iDJNcP3WC-yBoAvleZJ2Kqqdke-VhC6z92OvLpeBpSlgLZg2wM7m4TTozMiRYAEFyi-Tkeu3kUXkxViDyAHEmogwz9oDCVJFndqTVP07sCnUNS9RFeAEphhiftNampUi0RsQ%3D%3D&amp;amp;attredirects=0" width="255" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;From that screen you can try out the secure login example and dive right into the code using the documentation. Download them both&amp;nbsp;&lt;a href="http://cfcommons.org/index.cfm/download"&gt;here&lt;/a&gt;!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif; font-size: x-large;"&gt;Interested in learning more or contributing?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Please visit the &lt;a href="http://www.cfcommons.org/"&gt;CFCommons site&lt;/a&gt;, poke around, read some documentation and try it out.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Are you interested in becoming a CFCommons developer? &lt;a href="http://cfcommons.org/index.cfm/contact-us"&gt;Contact us&lt;/a&gt; to submit yourself as a contributor.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Holla.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-4973570765950477088?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/4973570765950477088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=4973570765950477088' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/4973570765950477088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/4973570765950477088'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/02/coldfusion-commons-project-released.html' title='ColdFusion Commons Project Released'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-9174905033029158185</id><published>2010-02-04T16:23:00.000-08:00</published><updated>2010-02-19T15:59:30.645-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web performance'/><title type='text'>Immediate Web Performance Enhancements</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Been doing a lot of research lately on web performance and came across the work of the Exceptional Performance Team from Yahoo!. This team is responsible for putting together best practices to achieve high performing web sites.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;I've hand picked some of their best practices that are, in my opinion, relatively quick to implement. Below I've listed the tips and a quick summation of each. However I encourage you to take a look at the entire list posted by the performance team. There are a total of 34 best practices spanning 7 categories. I've posted the link at the end of this post.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Without further ado, let's jump right in:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Content&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#num_http"&gt;Minimize HTTP Requests&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;Combine script and css files&lt;/b&gt; - &amp;nbsp;During your release process, you can use a number of the tools out there to combine, also known as minifying, your scripts and css files.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;Use css sprites&lt;/b&gt; - combine images into one file and use the css image styling properties to display the correct image. For instance, if you had a set of images that are essentially rollover images, combine them all into on image so that instead of the browser having to load 10 on/off images, it only needs to load it once in one HTTP request.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#cacheajax"&gt;Cache AJAX Request&lt;/a&gt;s&amp;nbsp;- &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Expires &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;or &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Cache-Control &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;headers are your friends. Append a timestamp to your url to ensure so that any subsequent calls to that url will be from the cache. It's important to note that if for some reason the user performs some action that will need to make a request to the url that has already been cached, you need to ensure you update that url's timestamp.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#split"&gt;Split Components Across Domains&lt;/a&gt;&amp;nbsp;- Per the HTTP/1.1 spec, browsers download two components in parallel per hostname at a time. As a rule of thumb, you should separate your static content like images/css/scripts/documents from the servers that server up your dynamic content. This means that if you have three domains, one that serves dynamic and two that serves static, then you allow 6 "parallel downloads" at a time per request.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;CSS&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#css_top"&gt;Put style sheets at the top&lt;/a&gt;&amp;nbsp;- This tip is more of a pseudo performance boost because the idea is all about &lt;i&gt;progressive loading&lt;/i&gt;. &amp;nbsp;It's all about instructing the browser to load items such as images and layouts as soon as possible, once they are available. The HTML page &lt;i&gt;should &lt;/i&gt;be your loading indicator.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#csslink"&gt;Choose link over @import&lt;/a&gt;&amp;nbsp;- In IE, @import behave just like a link at the&amp;nbsp;bottom&amp;nbsp;of the page which impedes&amp;nbsp;&lt;i&gt;progressive loading&lt;/i&gt;. Keep it simple...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Javascript&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#external"&gt;Make Javascript and CSS external&lt;/a&gt; - well it's &lt;i&gt;almost &lt;/i&gt;always a good idea&lt;i&gt;.&lt;/i&gt;&amp;nbsp;The reason I say &lt;i&gt;almost&lt;/i&gt; is that you should be mindful of, as the team puts it, "&lt;i&gt;..the frequency with which external JavaScript and CSS components are cached relative to the number of HTML documents requested.&lt;/i&gt;". If there is a page that uses CSS and/or Javascript but that page is only visited 1-2 times upper limit per user session (like the homepage), then it might not make sense to load external files since&amp;nbsp;quantifying&amp;nbsp;the performance boost would be difficult and probably end up being negligible. Better to put it inline so that CSS can be loaded quickly lessening HTTP requests to external files and maximizing &lt;i&gt;progressive loading&lt;/i&gt;. Of the course on the opposite side of the spectrum if you have CSS/JS that is being used across different pages and those pages are high trafficed, then you should absolutely place those CSS and Javascript files in external files.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#js_dupes"&gt;Remove duplicate scripts&lt;/a&gt;&amp;nbsp;- no brainer here...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#js_bottom"&gt;Put Scripts at the Bottom&lt;/a&gt;&amp;nbsp;- Putting scripts in the head of the HTML file blocks parallel downloads. If you can get away with it, put your scripts right before the end of the body tag.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#minify"&gt;Minify Javascript and CSS&lt;/a&gt;&amp;nbsp;- Basically this means to remove spaces characters and comments from your JS and CSS files. You can take this a step further and even combine your minified files into one. As with anything in programming, use your discretion as the need for combining scripts or css into one file might not make sense in every application.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Server&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#flush"&gt;Flush the buffer early&lt;/a&gt; - If your page is heavy on the back end processing you might consider flushing the buffer. In doing so you will allow you to begin fetching components like images, css, scripts. The ideal place to put this is right after the head tag, before the body.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html#expires"&gt;Add an Expires or a Cache-Control Header&lt;/a&gt; - This is inline with their "Cache AJAX requests" rule. The performance team boils it down to two rules. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;For static components: implement &amp;nbsp;the "Never Expire" policy by setting far future &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Expires&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; headers.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;For dynamic components: use an appropriate &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Cache-Control&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; header to help the browser with conditional requests.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;So there you have it. Some of the few practices from the Yahoo! Performance Team that I believe you could probably do in a reasonable amount of time.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Also if you haven't already take a peek at &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt;&amp;nbsp;that integrates with Firebug for FireFox. Also &lt;a href="http://developer.yahoo.com/yslow/smushit/index.html"&gt;Smush.it&lt;/a&gt;&amp;nbsp;from Yahoo! is a pretty cool tool for optimizing images without losing quality.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Till next time... PEACE.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;-Micky&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://developer.yahoo.com/performance/rules.html"&gt;Best Practices for Speeding Up Your Web Site&lt;/a&gt;&amp;nbsp;- Yahoo! Exceptional Performance Team&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-9174905033029158185?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/9174905033029158185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=9174905033029158185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/9174905033029158185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/9174905033029158185'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/02/immediate-web-performance-enhancements.html' title='Immediate Web Performance Enhancements'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-2922866630150290075</id><published>2010-02-02T14:47:00.000-08:00</published><updated>2010-02-19T15:59:44.343-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Javascript Closures</title><content type='html'>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;What is a closure?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="color: black; font-size: 13px;"&gt;If a function is created in such a way that it will retain it's local variable scope even after the function exits - then its a closure.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="color: black; font-size: 13px;"&gt;&lt;/span&gt;What do I need to understand first about Javascript to understand closures?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Javascript uses&amp;nbsp;&lt;i&gt;lexical scoping.&amp;nbsp;&lt;/i&gt;Huh? Simply put, local function variables are kept alive even&amp;nbsp;&lt;b&gt;&lt;i&gt;&lt;u&gt;after&amp;nbsp;&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;the function exits. You'll hear this explained a few different ways - "variables are kept alive after the stack frame/pops off/deallocated/ends/completed/{insert geeky word to signify stack frames ending}".&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;By default, inner functions have access to variables within their outer functions. It does not matter whether its 1 or 10 levels up.&amp;nbsp;&lt;u&gt;&lt;b&gt;This is absolutely paramount in understanding closures.&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial; font-size: x-large;"&gt;How do you create a closure?&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Any time you create a function within a function &lt;b&gt;and&lt;/b&gt;&amp;nbsp;the inner function refers to an outer function's private variable, you've created a &lt;b&gt;closure&lt;/b&gt;. &lt;i&gt;Simple as that, don't&amp;nbsp;over complicate&amp;nbsp;it.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;A Simple Closure&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/closure1.png?attachauth=ANoY7crbt4SU2UYjiCzfrKR8hXlOWoY4h0dOo6cEJAzim-EI25_RP5s9SFeLIaU0iRsK4mdG8jwUkH4L5AtcKgaZuIfBWl9L_Hwk9j6BjwcqsYSqffykM-XUZ-p7Q5Q_oFprCUchbJtHywv-vFBdNkJWHHX3ozvUFYPvXoUbtCDCyA2l7Kwgh6azyqEjm3Q2tgCr9BLqYo81Q2eHnmWble5evEyc3nETPA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/closure1.png?attachauth=ANoY7crbt4SU2UYjiCzfrKR8hXlOWoY4h0dOo6cEJAzim-EI25_RP5s9SFeLIaU0iRsK4mdG8jwUkH4L5AtcKgaZuIfBWl9L_Hwk9j6BjwcqsYSqffykM-XUZ-p7Q5Q_oFprCUchbJtHywv-vFBdNkJWHHX3ozvUFYPvXoUbtCDCyA2l7Kwgh6azyqEjm3Q2tgCr9BLqYo81Q2eHnmWble5evEyc3nETPA%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;In this example, here is what's going on...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Line 1 - We create a function called &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;multiplyTemplate &lt;/b&gt;&lt;/span&gt;with one argument.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Line 2 - The argument is saved to a private variable called &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;multiplier&lt;/span&gt;&lt;/b&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Line 3 - We declared an inner function. &lt;i&gt;Something should have clicked here.&lt;/i&gt; Remember what I mentioned about inner functions having access to parent function's variables scope. &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&lt;i&gt;&lt;u&gt;multiplyTemplate&amp;nbsp;&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;i&gt;&lt;u&gt;is now a closure&lt;/u&gt;&lt;/i&gt;. Why? Because it is using its PARENT function's private variable&amp;nbsp;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;multiplier&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&amp;nbsp;What's going on here to the end of this inner function on line 5 is absolutely critical to understanding closures.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Line 4 - We return the value of multiplier times y. Multiplier is a private method of the &lt;b&gt;outer&lt;/b&gt; function.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Line 8 - we create a new variable that executes&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;multiplyTemplate(5)&lt;/b&gt;&lt;/span&gt;. Remember the return of &amp;nbsp;is a&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;multiplyTemplate&amp;nbsp;&lt;/b&gt;&lt;/span&gt;function, not a primitive int value. It's on this line where the rubber meets the road. Here is what just happened:&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;multiplyTemplate(5)&lt;/b&gt;&lt;/span&gt;&amp;nbsp;was fired and a new function context was created.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;The argument of 5 was assigned to this function context's private&amp;nbsp;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;multiplier&amp;nbsp;&lt;/span&gt;&lt;/b&gt;field.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;An anonymous function was returned whose value of x is being &lt;b&gt;RETAINED/KEPT ALIVE even though&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"&gt;&lt;b&gt;multiplyTemplate(5)&amp;nbsp;&lt;/b&gt;&lt;/span&gt;has exited.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Line 10 -&amp;nbsp;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;multiplyBy5(10)&lt;/b&gt;&lt;/span&gt;&amp;nbsp;is executed using the&amp;nbsp;function&amp;nbsp;context declared on Line 8. The argument 10 is actually the y argument on line 3 which uses x to multiply to itself. The multiplier x is still 5 &lt;b&gt;through closure&lt;/b&gt; and the value that returns is 50.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Why use a closure?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;I'm sure there are a handful of reasons where you would want to use a closure, however in my experience I've only used them for a couple reasons.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;On main reason is if I need to properly encapsulate data inside an object whether it be transient or a singleton.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;Attaching event handlers to a DOM object via anonymous methods+closure inside of a for loop.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;That's the skinny. There are many many many resources out there that explain closures in less-than-understandable format but hopefully this helps demystify it a bit.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;-Mick&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000; font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-2922866630150290075?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/2922866630150290075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=2922866630150290075' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/2922866630150290075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/2922866630150290075'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/02/javascript-closures.html' title='Javascript Closures'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-618825280562286969</id><published>2010-01-18T13:51:00.000-08:00</published><updated>2010-02-19T16:00:03.511-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><title type='text'>The Unit of Work Design Pattern</title><content type='html'>&lt;span style="color: blue;"&gt;"Everything that we do in this grid or in these fields, or in this group of tabs cannot be saved to the system until the Save button is actually pressed", says the business analysts.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This made Brian Carr and myself sit way back in our chairs and go "Hmmm... How can we solution this problem given our architecture?". The piece of software we're developing is built around SOA - our front end user interface is strictly ExtJS that communicates over ReSTful web services to our platform. Not a lick of CF on the front end. Shortly after those requirement gathering meetings we buckled down to analyze the problem at hand.&lt;br /&gt;&lt;br /&gt;Here were some of our main considerations:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;ExtJS grids come with their own dirty/clean mechanism but that only existed for grids. Our client's requirement existed for any form control, not just grids. That option was out of the picture, especially in a SOA.&lt;/li&gt;&lt;li&gt;Even if that functionality existed for all form controls, how would the platform handle saving these data points simplistically with minimal overhead and a clean API? In a traditional application that doesn't use data mappers or ORM, you'd usually have a post page that inserted/saved everything about that entity - for instance a User. You'd have a web form that when posted, would update all 20 fields even though all you needed to update was one email address. In an enterprise level environment this is a HUGE waste both in sending data over the pipe as well as causing&amp;nbsp;unnecessary&amp;nbsp;database overhead.&lt;/li&gt;&lt;li&gt;We already had our own ActiveRecord implementation in place so handling crud operations from our domain model was extremely simple.&amp;nbsp;&lt;/li&gt;&lt;li&gt;We already implemented the Observer Pattern that I've detail &lt;a href="http://mickydionisio.blogspot.com/2009/12/using-observer-pattern-to-save.html"&gt;here&lt;/a&gt;, to handle saving composites among other things.&lt;/li&gt;&lt;li&gt;At a systems level, we wanted to make small, light and quick web service requests to our platform whenever a form field was updated.&lt;/li&gt;&lt;li&gt;It &lt;b&gt;&lt;i&gt;must&lt;/i&gt;&lt;/b&gt; be transactional.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;We knew that when it came to persisting an object singularly, it was solid. The api was such that these objects could save itself, load itself etc. We also knew that via our Observer Pattern implementation that when an object saved itself and there were any composite relationships attached to that instance, any of those composites would also save itself. So the only two problems where this:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;How do we logically group &lt;b&gt;disparate&lt;/b&gt; objects in memory that are part of a unit of work - like a front end data grid or a group of data separated by tabs - to ensure that the underlying objects that encapsulated these data points can be saved, deleted or rollbacked (removed from memory) when needed. All while using our ActiveRecord and Observer patterns?&amp;nbsp;&lt;/li&gt;&lt;li&gt;ALL of this &lt;b&gt;must&lt;/b&gt; be managed across multiple independent http requests to the platform.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;As usual Brian and I banged our heads against the wall trying to come up with a solid solution. Then it happened... enter the Unit of Work design pattern by &lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="color: blue;"&gt;Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="color: blue;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/UoW.png?attachauth=ANoY7crKVaW26fVDTmHdt3eWrrP60ZrKmbb4OqfnrXqZjL025WWcvLpNddueNqOL4S4chfg1GbYwU1p7Xytc1kNR1OjouRRWBkRXo6ENPnKGrshe_00PD-fcF3WOUn66DLowAlkQFiLO7jPaQAsatbgHWIPWMLRkjL5y0A7OJmYXtD6huEVfpcY86tQWfHff4KbF51qd5vE7&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/UoW.png?attachauth=ANoY7crKVaW26fVDTmHdt3eWrrP60ZrKmbb4OqfnrXqZjL025WWcvLpNddueNqOL4S4chfg1GbYwU1p7Xytc1kNR1OjouRRWBkRXo6ENPnKGrshe_00PD-fcF3WOUn66DLowAlkQFiLO7jPaQAsatbgHWIPWMLRkjL5y0A7OJmYXtD6huEVfpcY86tQWfHff4KbF51qd5vE7&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="color: blue;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Let's jump right in. I won't go over the exact implementation that we used in our software, but I'll provide a quick overview of this design pattern and how you might get started with it.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;As always, here is the class diagram first.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uow_impl.png?attachauth=ANoY7crUfs0YGmkTjJ_z-hpzOg2upf4Y1yMgV7cXSPn9JR9nYG7C8BfWcIzdwjZdaSZcZS0gWaqvxpgftz1I4f-R6LDRVfjq0Pijq3T0jk9D0d9pxXF5gJdDn-gg3ZgHv4c40rTRkjQtwG6009Td5FakSouXHRSHK6bDNyBr-LgUFUdrKHKvEDYnqxEy5k0RDjaHgjbfAHSL8Q6g44Tsuik6ssK3WjScxA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uow_impl.png?attachauth=ANoY7crUfs0YGmkTjJ_z-hpzOg2upf4Y1yMgV7cXSPn9JR9nYG7C8BfWcIzdwjZdaSZcZS0gWaqvxpgftz1I4f-R6LDRVfjq0Pijq3T0jk9D0d9pxXF5gJdDn-gg3ZgHv4c40rTRkjQtwG6009Td5FakSouXHRSHK6bDNyBr-LgUFUdrKHKvEDYnqxEy5k0RDjaHgjbfAHSL8Q6g44Tsuik6ssK3WjScxA%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;So you'll see here that we've got:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;ol&gt;&lt;li&gt;An IPersistent interface that has save and delete that returns a string for example purposes.&lt;/li&gt;&lt;li&gt;A UnitOfWork (UoW) object.&lt;/li&gt;&lt;ol&gt;&lt;li&gt;that has 3 fields to store the new, delete and changed stack. Which all should take an array of objects,&amp;nbsp;preferably&amp;nbsp;strongly typed if your language can support it.&lt;/li&gt;&lt;li&gt;methods for adding to each stack.&lt;/li&gt;&lt;li&gt;a method for committing and deleting the UoW.&lt;/li&gt;&lt;li&gt;a get() method that will pull out an object from the UoW registry.&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;div&gt;&lt;b&gt;The idea is simple really. The UoW acts as a container/wrapper for &lt;/b&gt;&lt;span style="text-decoration: underline;"&gt;&lt;b&gt;disparate&lt;/b&gt;&lt;/span&gt;&lt;b&gt; objects that will need to take part in a single logical transaction.&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is the code for the UnitOfWork object:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uow_index.png?attachauth=ANoY7cqXUffWsk_DuMrExufqGGJRhFZSAXyY5ZhmO_VMzgEmcg6IxM3VOYwPI61KSdBajeFG3vP8dsF6kMHPYxK23tGL76ZJ0iBO7EGeCy9FRic9mqMWb8PjCw8Z7hKplcDInmLE5n-BlKGseWAOtFcjdwU7BM_xPS22yaMWZpWIXKjnJ3EofaIz05HBbR-gMEYEY3Uyxb0f_pm8SrEfED0WLgYfn5FcnQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uow_index.png?attachauth=ANoY7cqXUffWsk_DuMrExufqGGJRhFZSAXyY5ZhmO_VMzgEmcg6IxM3VOYwPI61KSdBajeFG3vP8dsF6kMHPYxK23tGL76ZJ0iBO7EGeCy9FRic9mqMWb8PjCw8Z7hKplcDInmLE5n-BlKGseWAOtFcjdwU7BM_xPS22yaMWZpWIXKjnJ3EofaIz05HBbR-gMEYEY3Uyxb0f_pm8SrEfED0WLgYfn5FcnQ%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Pretty straight forward here. Class members are created to hold objects (stack) and methods are there to throw objects onto a stack. Notice how the entirety of commit() is &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;transactional&lt;/span&gt;&lt;span style="font-weight: normal;"&gt; -&lt;/span&gt;&lt;span style="font-weight: normal;"&gt;&amp;nbsp;it is &lt;i&gt;all or nothing&lt;/i&gt;.&lt;/span&gt;&lt;/b&gt;&amp;nbsp;We iterate over all the stacks and call the appropriate crud method. Also the get() method will pull out the object from the registry based on hashcode. &lt;i&gt;You can do this however based on how you uniquely identify objects in your system.&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Here's the scratch code:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uow_index.png?attachauth=ANoY7crtWjCWBcm-itT2hj9b5FCdc3Vhay_X--6a5838ySrSBFqiPdlD5rlaq4xPsoQvxlt6HeWp7mNROXVJS4B4JT9ap2sbqx-7CO1qaBwxYswBPgnAXv3SiH7J3lkj3XWYqZ2z-b93Y8grwdOIzblfjXLOHrWN1jtSOpJr_70x0di3Nb2Ni1JP3D4YcE4wJUsXVwlsbvdWAlHlh-0rKSZtmbku_qCRYg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uow_index.png?attachauth=ANoY7crtWjCWBcm-itT2hj9b5FCdc3Vhay_X--6a5838ySrSBFqiPdlD5rlaq4xPsoQvxlt6HeWp7mNROXVJS4B4JT9ap2sbqx-7CO1qaBwxYswBPgnAXv3SiH7J3lkj3XWYqZ2z-b93Y8grwdOIzblfjXLOHrWN1jtSOpJr_70x0di3Nb2Ni1JP3D4YcE4wJUsXVwlsbvdWAlHlh-0rKSZtmbku_qCRYg%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Which produces:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/upw_results.png?attachauth=ANoY7cq4fhagw3GBmQvpOWzBJFjgUIK0x24UfSnvzbhi0LrOSgk3VH3mMF73UzebyZDTvLrYtjoG-9AxyE1dOSGZXYN4MVynpoiGbJ-sUEgJ7PIZGvqdGnJfuDXCBpEUGt9pXA61f6sawa509WYgG3WaUcNniBNFaXklkAXqaOitTMWdDhh2uVjsih1JUkzwgDukR9tiRn3xSl6omnu8uiX772Nb_vWHaA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/upw_results.png?attachauth=ANoY7cq4fhagw3GBmQvpOWzBJFjgUIK0x24UfSnvzbhi0LrOSgk3VH3mMF73UzebyZDTvLrYtjoG-9AxyE1dOSGZXYN4MVynpoiGbJ-sUEgJ7PIZGvqdGnJfuDXCBpEUGt9pXA61f6sawa509WYgG3WaUcNniBNFaXklkAXqaOitTMWdDhh2uVjsih1JUkzwgDukR9tiRn3xSl6omnu8uiX772Nb_vWHaA%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this test we:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;created three users&lt;/li&gt;&lt;li&gt;displayed the unique hashcodes for each user&lt;/li&gt;&lt;li&gt;assign user1 and user2 to to the UoW new stack.&lt;/li&gt;&lt;li&gt;assign user3 to the UoW delete stack.&lt;/li&gt;&lt;li&gt;then call commit() on the UoW.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;Cool? On uow.commit() we've executed the appropriate database method to handle persistence and printed the save/delete messages to the screen. Of course in a real implementation this would be whatever persistence mechanism you have in place - DAO, ActiveRecord, data mappers, whatever.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are a couple key things to consider that this post didn't cover:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;You will most likely need a &lt;b&gt;singleton&lt;/b&gt;&amp;nbsp;object, usually called the&amp;nbsp;UnitOfWorkManager,&amp;nbsp;that is responsible for managing your UnitOfWork objects. This plays into the feature of supporting UoW across multiple HTTP requests.&lt;/li&gt;&lt;li&gt;You will need a method on the UoW object that will remove objects from certain stacks altogether. This is for situations that perhaps the user clicks a "new user" object and a new Use robjects get registered. However he/she decides that a new user is no longer needed so they subsequently remove it but there are&amp;nbsp;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;still&lt;/span&gt;&lt;/b&gt;&amp;nbsp;other data changes that need to be persisted for that UoW. Don't get this confused for rollback() or registerDeleted().&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This is one of those design patterns that you can find yourself getting really deep and start customizing like crazy. Be careful for that, make sure to keep it simple...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hopefully you can use this as your jumping off point... Happy UnitOfWorking!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;-Micky&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;References&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://martinfowler.com/eaaCatalog/unitOfWork.html"&gt;Martin Fowler's UnitOfWork&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-618825280562286969?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/618825280562286969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=618825280562286969' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/618825280562286969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/618825280562286969'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/01/unit-of-work-design-pattern.html' title='The Unit of Work Design Pattern'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-6490625549341252447</id><published>2010-01-13T06:56:00.000-08:00</published><updated>2010-02-19T16:05:51.622-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='object orientation'/><title type='text'>My Brother's Term Paper - Strengths and Weaknesses of Object-Oriented and Procedural Programming</title><content type='html'>&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;div&gt;My 17 year old little brother, Gian Dionisio, is currently working on getting into college to pursue a computer science degree and has always expressed a genuine interest in software engineering. I'm on his back 24/7 when it comes to good grades, school etc. so it was a pleasant holiday present when he showed me his senior term paper in which he&amp;nbsp;received&amp;nbsp;a 98 out of 100. Glad he hasn't caught "senioritus" like his older brother did! I'm posting this more for selfish reasons as it's something I'd like to point people to for a totally objective view when it comes to object oriented vs. procedural programming. I've probably given Gian about a 1 minute dump of my own thoughts on the subject but as you'll read, his essay is based entirely on his own research. so here it is, good work Gian, very good work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; white-space: pre;"&gt;&lt;b&gt;Strengths and Weaknesses of Object-Oriented and Procedural Programming by Gian Dionisio&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The process of designing a program is broken down into four steps:&amp;nbsp;analysis, design, implementation, and maintenance. Analysis refers to&amp;nbsp;determining if a problem is solvable, design refers to the process of&amp;nbsp;determining how to solve the problem, implementation is the actual&amp;nbsp;coding of the program, and maintenance refers to the debugging and&amp;nbsp;modification of the program. As the process progresses from one phase&amp;nbsp;to the next, costs rise higher and higher, with maintenance being the&amp;nbsp;most expensive (Lambert). Currently, many programmers use one of two&amp;nbsp;paradigms of programming when designing and implementing a program:&amp;nbsp;procedural and object-oriented. However, many programmers have begun&amp;nbsp;to stray away from procedural programming in favor of object-oriented&lt;/div&gt;&lt;div&gt;because of the way object-oriented programs handle data, which allows&amp;nbsp;for more dynamic and flexible programs. Even though object-oriented&amp;nbsp;programming offers more flexibility than procedural programming,&amp;nbsp;programmers should not perceive procedural programming as obsolete&amp;nbsp;because both paradigms have strengths and weaknesses that do not make&amp;nbsp;one necessarily better than the other.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Procedural programming is best described as a one-way system, using&amp;nbsp;only variables and functions, with no major data grouping, which is&amp;nbsp;the primary strength of object-oriented programming (gabehabe). This&amp;nbsp;paradigm emphasizes on conciseness and reaching the end result as&amp;nbsp;quickly as possible, solving only the problem presented and nothing&amp;nbsp;more, making procedural programs very straightforward (Weisfield).&amp;nbsp;John Barton of IBM notes that generations of programmers have&amp;nbsp;essentially been taught to create a list of instructions for the&lt;/div&gt;&lt;div&gt;machine on how to read data (gather ingredients), how to use equations&amp;nbsp;and functions with subroutines (cook the meal), and how to display the&amp;nbsp;product (a finished meal) (Waldrop).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While the design and implementation of a procedural program may be&amp;nbsp;straightforward, especially in smaller scale projects, as the programs&amp;nbsp;grows larger in scale, both design and implementation become&amp;nbsp;increasingly more difficult as different subroutines are being&amp;nbsp;performed on the same set of data at the same time (Waldrop). When the&amp;nbsp;program is finally functional, modification is made either difficult&amp;nbsp;or impossible because changes in one part of the program may affect&amp;nbsp;the rest of the program as a whole (Archwing). Because procedural&amp;nbsp;programs are not able to be readily modified, maintenance costs become&amp;nbsp;very high. For example, think of a 10-story apartment complex with 10&amp;nbsp;apartments on each floor, and a development lot for 100 houses; the&amp;nbsp;lots of houses may cost more to construct than the apartment complex,&amp;nbsp;but the houses are, for the most part, self-contained with their own&lt;/div&gt;&lt;div&gt;utilities and walls, versus an apartment, which shares utilities and&amp;nbsp;walls, therefore adding another house would be far less expensive than&amp;nbsp;adding another apartment to an apartment complex (Orr). This problem&amp;nbsp;of modification is solved with the principles emphasized in&amp;nbsp;object-oriented programming.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The main strength of object-oriented programming is its ability to&amp;nbsp;handle data by taking advantage of the way we perceive of environment&amp;nbsp;with the use of objects (Parr). Objects can be seen as separate&amp;nbsp;entities, each with their own characteristics. These entities all&amp;nbsp;share two characteristics: states and behaviors (Sun). For example, a&lt;/div&gt;&lt;div&gt;dog has 'states' (name, color, breed) and 'behaviors' (barking,&amp;nbsp;fetching) (Sun). Objects "encapsulate" these qualities, meaning that&amp;nbsp;they contain data, otherwise known as states, and methods, otherwise&amp;nbsp;known as behaviors (Orr). These objects inherit these qualities from&amp;nbsp;blocks of code known as "classes"; a class can be seen as a blueprint&amp;nbsp;or template of an object, much like how biologists group organisms&amp;nbsp;into classes such as "bird" or ”mammal” (Waldrop). This use of objects&amp;nbsp;gives a solution of designing large scale programs by writing&amp;nbsp;small-scale software units that communicate with each other, rather&amp;nbsp;than a huge system (Parr). This tactic of "divide and conquer” is&amp;nbsp;employed in both procedural, with the use of subroutines, and&amp;nbsp;object-oriented programs, with the use of objects (Nemirovsky).&amp;nbsp;However, in a procedural program, the programmer must tell the&amp;nbsp;computer how to perform an action and when to execute it, in contrast&amp;nbsp;to an object-oriented program, where the programmer only tells the&amp;nbsp;object what to do, and then the object performs it (Sherer). This&amp;nbsp;means that a programmer doesn't need to know how or why an object&amp;nbsp;works, but merely what it does; demonstrating the principle of&amp;nbsp;information hiding, a method of encapsulation in which only certain&amp;nbsp;details are able to be seen (Orr). Information hiding allows for large&amp;nbsp;scale projects to run much more smoothly because programmers don’t&amp;nbsp;need to know the implementation of a class to use it, and allows&amp;nbsp;changes to be made without drastically affecting the entire program,&amp;nbsp;as well as a certain degree of consistency within the application, as&amp;nbsp;programmers working on the project are using the same base classes&lt;/div&gt;&lt;div&gt;(Lindsay).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When code is segmented into smaller sections, each with their own&amp;nbsp;separate individual functions, programs become easier to work with.&amp;nbsp;For example, in an object-oriented program, if a program needs to know&amp;nbsp;the month in a two-digit format, it sends a message to a Date object&amp;nbsp;with the message asking for the date in that format, rather than&amp;nbsp;accessing the date from a variable floating somewhere within the&amp;nbsp;program (Waldrop). Within that same program, another object can ask&amp;nbsp;for the date in a three-letter format by sending a message that&amp;nbsp;corresponds to that demand to the same Date object, and the Date&amp;nbsp;object would return that date. Object-orientation also allows the&amp;nbsp;developer to assemble his or her code in the same manner that he or&amp;nbsp;she thinks about the problem (Waldrop). The developer can create an&amp;nbsp;object named &amp;nbsp;”Airfoil” and define a function that instructs the&amp;nbsp;object how to handle data, and then the developer can send a message&amp;nbsp;to the Airfoil object to calculate something, such as wind resistance&amp;nbsp;(Chastain). By developing and debugging small components independent&amp;nbsp;from the program, developers are able to isolate and test code more&amp;nbsp;efficiently, and can assume that the program works as advertised,&amp;nbsp;rather than guess where problem may lie (as with the case of a&amp;nbsp;procedural program) (Chastain). By breaking up code into smaller&amp;nbsp;pieces, object-oriented programs become easier to modify, and because&amp;nbsp;of this many companies are interested in reaping the benefits of the&amp;nbsp;object-oriented approach, that is, reusable and easily modifiable&amp;nbsp;programs (Patrizio). Object-oriented programming can be considered&amp;nbsp;better at representing the real world than procedural programming&amp;nbsp;because object-orientation allows for more intricate and dynamic&amp;nbsp;interactions as well as allowing non-technical workers to better&amp;nbsp;understand and participate in the maintenance of a program because&amp;nbsp;objects better appeal to the natural human cognition patterns&amp;nbsp;(Archwing). An example of an object-oriented program’s ability to be&amp;nbsp;modified can be demonstrated in a payroll program; if the program was&amp;nbsp;written procedurally, the area that assesses the employee's paycheck&amp;nbsp;would be in an "if-then" form, versus an object-oriented program,&amp;nbsp;which would send messages to all the employee objects, which would&amp;nbsp;then calculate all the paychecks (Sherer). Any modifications done to&amp;nbsp;the procedural program might cause a chain effect in the program,&amp;nbsp;making unintentional changes. Object-oriented programs also become&amp;nbsp;easy to build upon in case the scope of the project grows larger&lt;/div&gt;&lt;div&gt;because of the principles stressed in object-oriented programming,&amp;nbsp;such as encapsulation and inheritance, allow the application to expand&amp;nbsp;quickly, and pre-existing classes do not have to be modified in any&amp;nbsp;way because objects interact with each other through their methods and&amp;nbsp;messages (Chastain).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Object-orientation offers many tools and principles that allow&amp;nbsp;programmers to create dynamic programs; however, learning to use these&amp;nbsp;tools can prove difficult. An entire way of thinking was built off of&amp;nbsp;the procedural method, and “reprogramming” the programmers may take a&amp;nbsp;lot of effort on the developer’s part before they can fully reap the&lt;/div&gt;&lt;div&gt;benefits of clarity and reusability (Waldrop). Procedural programming&amp;nbsp;is action-oriented and solves problems through a series of logical&amp;nbsp;steps, versus object-oriented programming, which looks at the entire&amp;nbsp;problem as a whole and then derives a solution with the use of a&amp;nbsp;series of reusable classes (Patrizio). The object-oriented approach&amp;nbsp;presents a radically different method of method approaching software:&amp;nbsp;code and data become merged into one single, cohesive unit— the&amp;nbsp;object, and is an abstraction of a set of real-world things, such as&amp;nbsp;"date" or "employee" (Archwing). Systems are made up of multiple&amp;nbsp;objects, such as date, or processing, and make requests with messages&amp;nbsp;which ask for specific pieces of information (Archwing). This&amp;nbsp;different way of thinking can be met with resistance by some, as in&amp;nbsp;the case or Chevron’s programming staff, who have difficulty grasping&amp;nbsp;the concepts (Moser).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A method for tackling the problem of learning how to use&amp;nbsp;object-oriented programming and concepts is through the use of&amp;nbsp;graphical user interfaces (Moser). Graphical user environments have&amp;nbsp;been in use by high school computer classes in hopes to intrigue&amp;nbsp;students to Iearn object-oriented programming by showing the fun,&amp;nbsp;enjoyable side of programming without having to touch the dense&amp;nbsp;terminology of the industry (Demski). For example, many high schools&amp;nbsp;have begun to use the BlueJ graphical user interface, which displays&amp;nbsp;coded boxes and arrows that allows students to watch the concepts in&amp;nbsp;action, and allows them to get a clear understanding of the concept&amp;nbsp;(Dernski).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, learning how to use object-oriented programming is not the&amp;nbsp;only problem, but when to use it. Object-oriented programming, while&amp;nbsp;very good at managing data complexity, is difficult to apply, which&amp;nbsp;may be a major reason for programmers not to adopt object-oriented&amp;nbsp;programming. Marc Funaro, a computer programmer, made a blog post&amp;nbsp;detailing his experience in trying to incorporate object-oriented&amp;nbsp;programming principles into his own programs, and stated that by doing&amp;nbsp;so, had almost ruined his business (Funaro). Marc was under the&amp;nbsp;impression that by incorporating aspects of object-oriented&amp;nbsp;programming, his programs would become much more efficient and&amp;nbsp;reusable (Funaro). However, this is only partly true, because in order&amp;nbsp;to fully take advantage of object-orientation, one needs to learn how&amp;nbsp;use object-oriented analysis and design; using an object-oriented&amp;nbsp;language will not yield the promised benefits unless one learns to&amp;nbsp;think in the appropriate manner (Buckier). Brian Carr, a seasoned&amp;nbsp;software architect, stated that programmers who use an&amp;nbsp;object-oriented language but are not thinking in an object-oriented&amp;nbsp;way are essentially procedural programmers; additionally, learning how&amp;nbsp;to use object-oriented programming does not make one a better&amp;nbsp;programmer, but rather, adds another tool to the programmer's disposal&lt;/div&gt;&lt;div&gt;(CF OOP Debate). Carr also notes that object-oriented programming is&amp;nbsp;better than procedural in one aspect: managing complexity. Funaro&amp;nbsp;also complained about design and implementation time when using&amp;nbsp;object-oriented programming, and that a project done procedurally&amp;nbsp;would be completed much more quickly (Funaro). Mike Chandler, another&amp;nbsp;object-oriented programmer, commented on this, saying, “There are some&amp;nbsp;projects that procedural programming would be better suited than OOP,&amp;nbsp;especially those that are smaller scale. When you’re designing a&amp;nbsp;program, you really need to think about the customer’s needs. Will he&amp;nbsp;wants to modify or extend the program? That’s when you need OOP” (CFOOP Debate).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this age of technology, advancements are being made very quickly,&amp;nbsp;however just because progress is being made, doesn’t mean we should&amp;nbsp;abandon older methods. Object-oriented programming, though powerful&amp;nbsp;and very flexible, is not without its drawbacks, suffering from longer&amp;nbsp;design and implementation times. Procedural programs, though&amp;nbsp;inflexible, are quick to design and implement, and may even prove&amp;nbsp;superior to object-oriented programming is smaller scale projects if fast delivery is key. However for the mid to enterprise level software systems, the object oriented approach does cost a little bit more up front but extraordinary gains are realized during the maintenance and enhancement phase, which is where most cost is incurred.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-6490625549341252447?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/6490625549341252447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=6490625549341252447' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/6490625549341252447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/6490625549341252447'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/01/my-brothers-term-paper-strengths-and.html' title='My Brother&apos;s Term Paper - Strengths and Weaknesses of Object-Oriented and Procedural Programming'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-5783060505005807785</id><published>2010-01-08T10:48:00.000-08:00</published><updated>2010-02-19T16:00:34.700-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><title type='text'>Fundamental Lightwire Bug?</title><content type='html'>&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;**UPDATE&amp;nbsp;01/09/10** &lt;span style="font-weight: normal;"&gt;Peter Bell, the creator of Lightwire, has addressed this issue. You can find his blog post about it &lt;a href="http://appgen.pbell.com/2010/01/09/critical-lightwire-error-in-setter-injection-for-transients/"&gt;here&lt;/a&gt;. I've also update this post as well.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;This bug seems extremely fundamental to be a real bug so my initial thoughts are that&lt;b&gt; I'm doing something completely wrong&lt;/b&gt;. An issue like this would have been discovered by now.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Brian Carr and I were working on some front end development for our project that leverages Quicksilver and Lightwire when we came across an bug in the UI. Whenever a form was submitted that contained form validation errors, it appeared to be returning correctly the first time. However if you were to submit the same form again, we noticed the error messages would continue to duplicate and stack. Initially we thought there was an issue with Quicksilver not configuring the beans correctly or perhaps we tagged our Errors object with a singleton annotation. After some digging into our bean configuration annotations, everything was annotated correctly.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;So next step was to switch our dependency injection provider to ColdSpring, which Quicksilver allows you to do with one line. What happened to our surprise? It worked! The errors were displaying correctly. Ok, so now we know that the issue is Lightwire specific but didn't know whether it was a Quicksilver or Lightwire problem so&amp;nbsp;we dug into Quicksilver's injection provider service for Lightwire. Perhaps we're wiring something incorrectly. After a good amount of investigation we verified Quicksilver was setting configuring beans correctly for Lightwire consumption.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Our next step was to completely bypass Quicksilver altogether. If we can configure these beans using just Lightwire and a scratch pad and still seeing this error then we can safely deduce that it was a problem in Lightwire. So here is what we found...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;First, here is the jist of the classes involved. Both are &lt;b&gt;TRANSIENT&lt;/b&gt; objects.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/errorsclassdiagram.png?attachauth=ANoY7cpDBahogq4ZTPqwBUY5eKueSWD1eMNYf_9W6l2YEI0s-QLCFn5Bt-TwBt53QMbr3qVAxMlCSLCqEhiMkhZxZdgWn64navOolBj8JpIl_bt1sr16rcipJqJ93OfzGWB6NalVTAqRUT_XCyYbcOF7tfkL-J0ia1kJ_WMwkNPQiIStNDyZAdxONO1adDsj5zM88LixC03crFfF0WnuYqtaUh41Nkxpdw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/errorsclassdiagram.png?attachauth=ANoY7cpDBahogq4ZTPqwBUY5eKueSWD1eMNYf_9W6l2YEI0s-QLCFn5Bt-TwBt53QMbr3qVAxMlCSLCqEhiMkhZxZdgWn64navOolBj8JpIl_bt1sr16rcipJqJ93OfzGWB6NalVTAqRUT_XCyYbcOF7tfkL-J0ia1kJ_WMwkNPQiIStNDyZAdxONO1adDsj5zM88LixC03crFfF0WnuYqtaUh41Nkxpdw%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Simply, a BusinessServiceResponse has an Error object. For this example, the hashcode member is a unique hash that is attached to each unique instance.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Here is the code that we are using to test:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/errorcode.png?attachauth=ANoY7cp754Nql_Z6KkLGRlIomIzZsbanhxuFobtCBqjW2O5otQltWvBNxoEGhTd6zfqHgfcCcAcVi0KpBnQs76eVuE5cCWKui5K_CHVcgX4WbivnhVkMMgwn4tN0x2hcvA8br7DXJBVb_4umoMFdRsprZT3T2n1-zgVQD2cedIGYhatdyDtkqgRBkKLcF12NG016OfGMZGTPZYMHzYCWzuj7QZ1s6RguNQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/errorcode.png?attachauth=ANoY7cp754Nql_Z6KkLGRlIomIzZsbanhxuFobtCBqjW2O5otQltWvBNxoEGhTd6zfqHgfcCcAcVi0KpBnQs76eVuE5cCWKui5K_CHVcgX4WbivnhVkMMgwn4tN0x2hcvA8br7DXJBVb_4umoMFdRsprZT3T2n1-zgVQD2cedIGYhatdyDtkqgRBkKLcF12NG016OfGMZGTPZYMHzYCWzuj7QZ1s6RguNQ%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Line 4 - 14 Configure the two transients - Errors and BusinessServiceResponse&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Line 16-20 Configure setter dependency.&amp;nbsp;BusinessServiceResponse has an Errors property to be injected with the Errors transient object.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Line 24-38 On the first iteration we are getting the bean for the first time then displaying the hashcode on the BusinessServiceResponse and the Errors. It's important to note that Errors hashcode is accessed through the BusinessServiceResponse on line 37.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Here are the results:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/lw_bug_result.png?attachauth=ANoY7cof6jouZqQ2oYu5m3CJtjDo3G31WQ0IrZbsqQnRgIJKqctOGkwLepfP0PdMBwJMeAmMI5D0dg8xgJYTBT7r90US4Z0cwCiVZfw-aItn9qzE2E54-jD2vIAthecNMSQT9pdugpUrAgNK1l0pZ3vm3LfEYlBK3FghP1mQTDfI5REWe6v4yVOYIcW0Uah0glayHb_QjZ7vHAkb7cuDSLppFI8oJ-I9uw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/lw_bug_result.png?attachauth=ANoY7cof6jouZqQ2oYu5m3CJtjDo3G31WQ0IrZbsqQnRgIJKqctOGkwLepfP0PdMBwJMeAmMI5D0dg8xgJYTBT7r90US4Z0cwCiVZfw-aItn9qzE2E54-jD2vIAthecNMSQT9pdugpUrAgNK1l0pZ3vm3LfEYlBK3FghP1mQTDfI5REWe6v4yVOYIcW0Uah0glayHb_QjZ7vHAkb7cuDSLppFI8oJ-I9uw%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;It appears that errors is being handled as a transient as the hashcode are identical across all three BusinessServiceResponse creations. Now that we know what the problem was, we dug into the Lightwire code. We found the issue in Lightwire.cfc. It loads setter dependencies as singletons by default??? Nooo, can't be.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/lwcode.png?attachauth=ANoY7crIqQUoPRjkJA0tHYXJzzJr6WIqQx65JV3uV86TCbjgE-BIZqnEQyX_k9zMnIrFc0Pim3oUaLZ8Uk2gyaazJR-ltXSwSfRfaPOEq2i9KRanCw40EBFGz7bDb0G-BlK8AMnyGGCKOatfErOYRpnd7EpN4ks6FND5AH8o94xLjVynB0T4P1h4Bi8pzvSWN8TjXsiERYgfnwUqWqmzNMD2zB0ZjQvgeg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/lwcode.png?attachauth=ANoY7crIqQUoPRjkJA0tHYXJzzJr6WIqQx65JV3uV86TCbjgE-BIZqnEQyX_k9zMnIrFc0Pim3oUaLZ8Uk2gyaazJR-ltXSwSfRfaPOEq2i9KRanCw40EBFGz7bDb0G-BlK8AMnyGGCKOatfErOYRpnd7EpN4ks6FND5AH8o94xLjVynB0T4P1h4Bi8pzvSWN8TjXsiERYgfnwUqWqmzNMD2zB0ZjQvgeg%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;On line 273, its creating each bean as a singleton. After replacing line 273 with an singleton/transient check like so:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/lwcodefix.png?attachauth=ANoY7cr5ykKiG5PQnkZqOJJDv8ddNr3-ZXkIIIy-69DAdFKOXsmUjLzsDEh9CBzGUAXuZ6ruf3RY64TvKelNgCbn2KspuAFdPg2w-pnCP8SAVsU2mv_xmIy8qrQtkARhJ-O3lRd5tr8sIbTXhTy_MBfoISQQis0y1lKVWCG-cPLVjmMeea6-ofehMxn7gwWpn0Fiofx9C65fJ13wjNHpUc6izO_uMhTdCA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/lwcodefix.png?attachauth=ANoY7cr5ykKiG5PQnkZqOJJDv8ddNr3-ZXkIIIy-69DAdFKOXsmUjLzsDEh9CBzGUAXuZ6ruf3RY64TvKelNgCbn2KspuAFdPg2w-pnCP8SAVsU2mv_xmIy8qrQtkARhJ-O3lRd5tr8sIbTXhTy_MBfoISQQis0y1lKVWCG-cPLVjmMeea6-ofehMxn7gwWpn0Fiofx9C65fJ13wjNHpUc6izO_uMhTdCA%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;It worked.&amp;nbsp;Let's rerun our tests.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/lw_bug_result_good.png?attachauth=ANoY7crnCmE_kyC4BPbCxLKJJHrPeoS8YMSVv7PPkmvh1U9yGaQhWchgDBXl5araDb7XWOcyOH6hu8VMfeKWCzxFwGwVVb1h8-ZmSP3cX0Bl5x78uNL2enW416gOJUOGeaAye0iMo8MRMlCl52K8xik7xOXeIWbc2rrMY85l90KifK3we1iCss19yCc5iT_acdCWEHZSf_Ac01aJ1sBItx7tuie-ykhx8A%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/lw_bug_result_good.png?attachauth=ANoY7crnCmE_kyC4BPbCxLKJJHrPeoS8YMSVv7PPkmvh1U9yGaQhWchgDBXl5araDb7XWOcyOH6hu8VMfeKWCzxFwGwVVb1h8-ZmSP3cX0Bl5x78uNL2enW416gOJUOGeaAye0iMo8MRMlCl52K8xik7xOXeIWbc2rrMY85l90KifK3we1iCss19yCc5iT_acdCWEHZSf_Ac01aJ1sBItx7tuie-ykhx8A%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;Hashcodes are different meaning now they are transients as well.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;b&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: blue;"&gt;*** UPDATE 01/09/10 *** Do &lt;span style="text-decoration: underline;"&gt;NOT&lt;/span&gt; use the code I posted as a fix as there has since been an official&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.pbell.com/images/lightwire.cfc.zip"&gt;&lt;span style="color: blue;"&gt;patch&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;to fix this issue. Grab it from&amp;nbsp;&lt;a href="http://www.pbell.com/images/lightwire.cfc.zip"&gt;here&lt;/a&gt;. Many thanks to&amp;nbsp;&lt;a href="http://appgen.pbell.com/"&gt;Peter Bell&lt;/a&gt;&amp;nbsp;and &lt;a href="http://www.remotesynthesis.com/"&gt;Brian Rinaldi&lt;/a&gt; for their help and quick response on this!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: blue; font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: 13px;"&gt;Please guys, help me see the light...&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-5783060505005807785?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/5783060505005807785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=5783060505005807785' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/5783060505005807785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/5783060505005807785'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2010/01/fundamental-lightwire-bug.html' title='Fundamental Lightwire Bug?'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-8879646973678562719</id><published>2009-12-17T12:07:00.000-08:00</published><updated>2010-02-19T16:00:50.750-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='quicksilver'/><title type='text'>Quicksilver - REST, MVC, AOP in 26 lines of code, 6 annotations and 0 xml.</title><content type='html'>&lt;span style="font-family: Arial; font-size: 13px;"&gt;You read it right. Let's jump right into how the&amp;nbsp;&lt;a href="http://quicksilver.riaforge.org/index.cfm"&gt;Quicksilver&lt;/a&gt;&amp;nbsp;Framework accomplishes this.&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/25linesproof.png?attachauth=ANoY7cpZyCKSDemleWIBUZkx7YBbQDyoprijWxpDrw2wUYWGYbO4T8_glk9f9fGwrz1VRz2tvYbn4K2_KyVkac8w19DM358px7LOxY75OWESWz1io28tVU-TpqIlrMc2JOReubhR4xUmddLozhhgJZE5M1D-pgk8Cf2rvMAnBRIlPKHJviKuOwp5ykb_VEwCD40yFoWfQNrwyEecZmNSutAut7-Sl4nYug%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/25linesproof.png?attachauth=ANoY7cpZyCKSDemleWIBUZkx7YBbQDyoprijWxpDrw2wUYWGYbO4T8_glk9f9fGwrz1VRz2tvYbn4K2_KyVkac8w19DM358px7LOxY75OWESWz1io28tVU-TpqIlrMc2JOReubhR4xUmddLozhhgJZE5M1D-pgk8Cf2rvMAnBRIlPKHJviKuOwp5ykb_VEwCD40yFoWfQNrwyEecZmNSutAut7-Sl4nYug%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span style="font-family: Arial; font-size: x-large; font-weight: bold;"&gt;Here is the view - getStuff.cfm&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/getStuff.png?attachauth=ANoY7cqgEubjw8en6_8rwyFqrCQr8W1ETpkF6bEvMtStDCEBzQPFCzKqLnRvczGFieatGkfn8tDBdLd5lW3zThSZBrX1auMaGhzhU76GBTidtzeQ2ppFzVWyTm0v8TWuKinTPuva2xk_pHFylP4t1zzHplXkXMNpM8ToeLValAdh6fjxWaUybKui8SQ49MMFlpVbGF7sqe4HEG0wVklBU2BMPPuv_-cGHg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/getStuff.png?attachauth=ANoY7cqgEubjw8en6_8rwyFqrCQr8W1ETpkF6bEvMtStDCEBzQPFCzKqLnRvczGFieatGkfn8tDBdLd5lW3zThSZBrX1auMaGhzhU76GBTidtzeQ2ppFzVWyTm0v8TWuKinTPuva2xk_pHFylP4t1zzHplXkXMNpM8ToeLValAdh6fjxWaUybKui8SQ49MMFlpVbGF7sqe4HEG0wVklBU2BMPPuv_-cGHg%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;And finally, the results when run:&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/mvcdump.png?attachauth=ANoY7cpJ80x6gie4xP6uEw4OZ_X2Bmh3VEBsJ_joKWSpixT5NSrhRUOnubr7pGt_E62h65KQjIrIYmJ4hHOYOtHZczxPwPo4css-KQ5U8Uisf-h6i5W-pNK_HAD8sYRCzIpMSs6JfKwtP6pz1CnE9U_AmBhZiFReEcV9ttjA0tS7hReaI59J6Y8P_mT_dJ__IlCoS58C-OJQmCEVpopqk0AacB5qOzDB1w%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/mvcdump.png?attachauth=ANoY7cpJ80x6gie4xP6uEw4OZ_X2Bmh3VEBsJ_joKWSpixT5NSrhRUOnubr7pGt_E62h65KQjIrIYmJ4hHOYOtHZczxPwPo4css-KQ5U8Uisf-h6i5W-pNK_HAD8sYRCzIpMSs6JfKwtP6pz1CnE9U_AmBhZiFReEcV9ttjA0tS7hReaI59J6Y8P_mT_dJ__IlCoS58C-OJQmCEVpopqk0AacB5qOzDB1w%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: x-large; font-weight: bold;"&gt;So, how did we just implement MVC?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/mvc_walkthrough.png?attachauth=ANoY7coxQC-TBHnZ6Qb4o3VWaThgt13se-rAivokB5yc6qev-jQsxWiAIHRza4b0D3hjFN7O4Ug7LA8wjy7Fa-BSaBLrQnzyzHwzPmloZqll7guPyTCecNpFb5HNW7hpbua5dXELJJ-PIgyR0o-rI-zseJHSbFkNaPG34vL9dN4gObWFssCusJnBn9O4S4wsTNccSo2U8AVfyCDkwZzHpten8bTpvb_CSw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/mvc_walkthrough.png?attachauth=ANoY7coxQC-TBHnZ6Qb4o3VWaThgt13se-rAivokB5yc6qev-jQsxWiAIHRza4b0D3hjFN7O4Ug7LA8wjy7Fa-BSaBLrQnzyzHwzPmloZqll7guPyTCecNpFb5HNW7hpbua5dXELJJ-PIgyR0o-rI-zseJHSbFkNaPG34vL9dN4gObWFssCusJnBn9O4S4wsTNccSo2U8AVfyCDkwZzHpten8bTpvb_CSw%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;STEP 1 -&amp;nbsp;&lt;/b&gt;Annotate your component with @viewRoot.&amp;nbsp;This is where all your views are stored.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;STEP 2 -&amp;nbsp;&amp;nbsp;&lt;/b&gt;Map the uri and http method to your url. You can optionally use the @returnTypeName annotation so when defined, it's value is mapped to the methods return and will be available&amp;nbsp;in the request scope of your view Look at the getStuff.cfm screen cap above..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;STEP 3, non-step -&amp;nbsp;&lt;/b&gt;Sit back and relax. Watch the goodness&amp;nbsp;of convention over configuration. QS will look&amp;nbsp;in your @viewRoot for a directory named after&amp;nbsp;the controller, in this case SampleService.&amp;nbsp;Then within that directory look for a file&amp;nbsp;whose name matches the method being&amp;nbsp;mapped.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;span style="font-size: x-large; font-weight: bold;"&gt;How did we implement AOP?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/aopwalkthrough.png?attachauth=ANoY7co7zFRjw8taK91BKBNwwWu9aI6uA8Pd-uvBROBSS7VC3TeU7j6X9QnHKNUToayA8HHocOW3DaHh3cvyf7y0I_8eg_N8-Lp40TPp4NdkZyFN1B9MYZjBEMIGRQnY2jhA0ohqhu2dawh1DlNsXeeNdN26bDz1CHcdFppZwYiIh-08qpWlwhQT6YYn9KkW0WFoWtP5T26gJXnE_WmkgQdSpVdPNzoE-g%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/aopwalkthrough.png?attachauth=ANoY7co7zFRjw8taK91BKBNwwWu9aI6uA8Pd-uvBROBSS7VC3TeU7j6X9QnHKNUToayA8HHocOW3DaHh3cvyf7y0I_8eg_N8-Lp40TPp4NdkZyFN1B9MYZjBEMIGRQnY2jhA0ohqhu2dawh1DlNsXeeNdN26bDz1CHcdFppZwYiIh-08qpWlwhQT6YYn9KkW0WFoWtP5T26gJXnE_WmkgQdSpVdPNzoE-g%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 13px;"&gt;&lt;b&gt;STEP 1&lt;/b&gt; -&amp;nbsp;Annotate your cross cutting method&amp;nbsp;with @aspect and give it a name.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;&lt;span style="font-size: 13px; font-weight: normal;"&gt;&lt;b&gt;STEP 2 -&amp;nbsp;&lt;span style="font-weight: normal;"&gt;Decorate the target method with&amp;nbsp;@preAspects and/or @postAspects&amp;nbsp;annotations. A comma separated list of the aspect&amp;nbsp;names.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;So when getStuff() was run, Quicksilver &lt;b&gt;first &lt;/b&gt;ran the aspect addRandomStuff(). All in 2, dos, ni steps. Cool eh?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;span style="font-size: x-large; font-weight: bold;"&gt;How did we implement REST?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/restwt.png?attachauth=ANoY7cpM_wrAxfF3c8VQfEYVALwi_5_ziR3Jcgkpws-VkyAxz5gisPQX4BZ5A3kgzrDCs62H0PSQORim2xDWCtaVqHpUaT2kLMNk9r73CcgejKNv5GH3qUm4bPcKQvLCogGKN3pKnil4x1JG_XrTc_IB1AjoS4bo46H27SbRg6jtnF0Z0V0BhiK_gtBv6hOnRZdRo-pXPEUWD6oaLnMan6QwVDs6xxa2rQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/restwt.png?attachauth=ANoY7cpM_wrAxfF3c8VQfEYVALwi_5_ziR3Jcgkpws-VkyAxz5gisPQX4BZ5A3kgzrDCs62H0PSQORim2xDWCtaVqHpUaT2kLMNk9r73CcgejKNv5GH3qUm4bPcKQvLCogGKN3pKnil4x1JG_XrTc_IB1AjoS4bo46H27SbRg6jtnF0Z0V0BhiK_gtBv6hOnRZdRo-pXPEUWD6oaLnMan6QwVDs6xxa2rQ%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;b&gt;&lt;span style="font-size: 13px; font-weight: normal;"&gt;&lt;b&gt;NO STEPS!&lt;/b&gt;&amp;nbsp;- You &lt;/span&gt;&lt;span style="font-size: 13px;"&gt;&lt;i&gt;already &lt;/i&gt;&lt;/span&gt;&lt;span style="font-size: 13px; font-weight: normal;"&gt;did when you annotated for MVC.Proof? Lets hit that URL again but leverage Quicksilver's automatic response serialization (of array, structs, queries) &amp;nbsp;and get back a JSON representation of "stuff" instead of going through MVC. &lt;/span&gt;&lt;span style="font-size: 13px; font-weight: normal;"&gt;Simply append ".json" to the end of the url, &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;n&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: x-large; font-weight: bold;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;span style="text-decoration: underline;"&gt;othing else needs to change&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 13px; font-weight: normal;"&gt;. Hit the url with .json and you'll see this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/restjson.png?attachauth=ANoY7crse0mAKARLQuineoxRCD7fB19yfH1XrmlmqfGYpwEgljhErLMx4sMQH3QsaWkkqkV_frvFXk77g_kw3Xm06e_bnlfvjVMJLw6mvkNqvzRmxcuUcXJLlZWQAUVm-Fscq9bdTKzjRAipqFAyWHw8qKVkOxjEiDLtrWf3s-KHMI98uvQaAx5jgaG4aMt-_IhAahQA0t7bkpqtDPgxuV0RmSEnTFGFmA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/restjson.png?attachauth=ANoY7crse0mAKARLQuineoxRCD7fB19yfH1XrmlmqfGYpwEgljhErLMx4sMQH3QsaWkkqkV_frvFXk77g_kw3Xm06e_bnlfvjVMJLw6mvkNqvzRmxcuUcXJLlZWQAUVm-Fscq9bdTKzjRAipqFAyWHw8qKVkOxjEiDLtrWf3s-KHMI98uvQaAx5jgaG4aMt-_IhAahQA0t7bkpqtDPgxuV0RmSEnTFGFmA%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-family: Arial; font-size: 13px; white-space: pre;"&gt;That's all folks. All of this in  26 lines of code using 6 annotations and 0 xml.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 13px; white-space: pre;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 13px; white-space: pre;"&gt;Hope this helped and please hit us up with any questions.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 13px; white-space: pre;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-family: Arial; font-size: 13px; white-space: pre;"&gt;-Micky&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-8879646973678562719?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/8879646973678562719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=8879646973678562719' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/8879646973678562719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/8879646973678562719'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/quicksilver-rest-mvc-aop-in-26-lines-of.html' title='Quicksilver - REST, MVC, AOP in 26 lines of code, 6 annotations and 0 xml.'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-4578566604904294287</id><published>2009-12-15T09:10:00.000-08:00</published><updated>2010-02-19T16:12:42.574-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='class diagrams 101'/><category scheme='http://www.blogger.com/atom/ns#' term='software design'/><category scheme='http://www.blogger.com/atom/ns#' term='object orientation'/><title type='text'>Design Before You Develop - Intro to Class Diagrams with Quick Reference</title><content type='html'>If you already are a design-before-you-develop junkie like I am, &lt;a href="http://www.urbandictionary.com/define.php?term=daps"&gt;daps&lt;/a&gt; to you. You can probably stop reading here and move onto the next blog in your queue. For the rest that are curious about it but don't know where to start, read on. &amp;nbsp;It's my opinion that you should get into the good habit of designing before you develop. Even if the design takes you 10 minutes on a scratch pad, a quick design session on a whiteboard or&amp;nbsp;several&amp;nbsp;days in a full blown modeling tool, you should do it.&lt;br /&gt;&lt;br /&gt;Why? Because it's during those sessions that you and your team can express the intended inner workings of your software modules, poke holes in it, rinse then repeat as needed. You can focus on a list business of requirements, design the class diagrams and literally step through the requirements allowing you to articulate the path of execution that'll take place to fulfill each requirement. All of this is done without a lick of code. You discover design flaws early on, &lt;span style="text-decoration: underline;"&gt;not during development&lt;/span&gt;. That's risky. You can even take it a step further and generate &lt;b&gt;&lt;a href="http://sequence%20diagrams/"&gt;sequence diagrams&lt;/a&gt;&amp;nbsp;&lt;/b&gt;against your UML model and requirements, they are invaluable! But sequence diagrams are outside the scope of this article, we'll get to it some other time.&lt;br /&gt;&lt;br /&gt;I'll say it again and again that during the design process you need to forget the code. Coding should be the easy part. It's the &lt;i&gt;design &lt;/i&gt;that lends your software scalability and flexibility. Without a proper design, you run the risk of causing not only future headaches for yourself and your team but more importantly, the business. Yea yea, without the design phase it's so much faster to release a product. Sure, you can tell your boss/client what you're doing is rapid development. Sure, your bosses will be happy for the time being cause you got it out so quick. You're the hero. You're the man. But who cares if you are spending the next year after your go live fixing code, trying to re-design after the fact and burning through company cash hand over fist. Or worse, bandaiding already production level code with&amp;nbsp;cut rate&amp;nbsp;code because everything is an "emergency" and you don't have the luxury of thinking things through anymore. All the while the boss that was singing your praises is no longer impressed that you put out a piece of software that constantly breaks. It's a vicious cycle and could've been avoided by dedicating a little more time to designing up front. Use the above as a case to your boss when you need a little more leeway to get some design cycles in in the beginning.&amp;nbsp;Just like Ben Franklin put it:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: blue;"&gt;An ounce of prevention is worth a pound of cure.&lt;/span&gt;&lt;/blockquote&gt;He was a pretty smart dude, and his quote certainly applies to software engineering. Let's put in that ounce of prevention by designing first eh?&lt;br /&gt;&lt;br /&gt;UML to the beginner can seem pretty damn intimidating. In my comp sci class I remember cracking open the UML section and my eyes glazed over at all the fricking symbols. I thought to myself, how in the hell am I going to memorize all this? After I got some real world experience, &lt;i&gt;it's really not that bad&lt;/i&gt;. Given, you can get pretty deep into it I find that I'm able to express a software model with only a few symbols. I thought I'd share with you some of the ones that I use all the time with Microsoft Visio however the symbols below are not application specific, they are universal symbols.&amp;nbsp;Here's the quick reference:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uml_legend.png?attachauth=ANoY7cr7pZ7ZM3IAXsyUcAG0rPZL5COv0Sy9FHB9vDp3T2gnC_GZXzKanVpL0Q6RZ-HDI1aHwNypTjqbAff0Tt_IRJdbe4QSfMG8y1-4aOeR4PUtQeL3j0Jdag1DmxWaVpdpLi_NfR-34_HmI70UgtC13MkgcdKMMLi9YHf0YgzvGdVUXLqYPNkkf-HflDbmgSh23xnkLmeXVSedlkQ36U61fCpygbytpw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uml_legend.png?attachauth=ANoY7cr7pZ7ZM3IAXsyUcAG0rPZL5COv0Sy9FHB9vDp3T2gnC_GZXzKanVpL0Q6RZ-HDI1aHwNypTjqbAff0Tt_IRJdbe4QSfMG8y1-4aOeR4PUtQeL3j0Jdag1DmxWaVpdpLi_NfR-34_HmI70UgtC13MkgcdKMMLi9YHf0YgzvGdVUXLqYPNkkf-HflDbmgSh23xnkLmeXVSedlkQ36U61fCpygbytpw%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;These symbols should be more than enough to get you going. Below is a what a real class diagram might look like using all above symbols:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uml101.png?attachauth=ANoY7crSw1zHNECHg6eL71IzkeLC4lBXBn7vTUzX0Ok0PNWCeFPXxM_ggsyGhoqjs2Gg_keGobPaepfK3u-rVuQr8WBpfqGDvEujrv3yiTMFfxAf0FqFkDHLaQVi_lM15UFvAfqI9g9HOADXYtpl_qcLUG4EQKhKa6Tre-_3yD7c7dnrr4WmDEcGxBIbr6l1RSUWjUzc1jjMzdZUC1awopi9sBTLohBiZg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uml101.png?attachauth=ANoY7crSw1zHNECHg6eL71IzkeLC4lBXBn7vTUzX0Ok0PNWCeFPXxM_ggsyGhoqjs2Gg_keGobPaepfK3u-rVuQr8WBpfqGDvEujrv3yiTMFfxAf0FqFkDHLaQVi_lM15UFvAfqI9g9HOADXYtpl_qcLUG4EQKhKa6Tre-_3yD7c7dnrr4WmDEcGxBIbr6l1RSUWjUzc1jjMzdZUC1awopi9sBTLohBiZg%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;In the above class diagram, there are two applications being modeled at the same time that use shared components. A school app and a war game app. I've put together some questions I'd ask myself while making some observations of this class diagram:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Person is being extended by Student and Soldier.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Soldier is in the common package. "Is this correct? Shouldn't it be in the wargame package? What happens if its not?"&amp;nbsp;&lt;/li&gt;&lt;li&gt;Soldier can have many pistols. "But is that true? Should it be a one to one? Should there be a collection manager of sorts to keep the api simple? Better ask the business."&lt;/li&gt;&lt;li&gt;Student can have many books via its multiplicity.&amp;nbsp;"Same multiplicity questions apply here?"&lt;/li&gt;&lt;li&gt;Student is teachable, since it implements ITeachable. "Are the methods defined here really granular? Do they really belong in this interface? Is there anything else I can add to this interface?"&lt;/li&gt;&lt;li&gt;A pistol implements IWeapon so it must fire.&lt;/li&gt;&lt;li&gt;fire() on the IWeapon interface returns numeric. "Is this the proper return type?", "Should it be another return type?", "Are we going to calculate fire() based on the numeric damage its dealt?, &amp;nbsp;If so keep it. If not, let's redesign".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Soldier doesn't have an interface. "Does Soldier need an interface?", "Is there something that all soldiers must be able to do? Let me dig into the requirements and do some textual analysis."&lt;/li&gt;&lt;li&gt;Person has a firstName, lastName and age member. "Are these shared across all Person objects?". "Do they need to be specific to a subclass?"&lt;/li&gt;&lt;li&gt;All classes are have their packages before the name so it's clear where each class should exist.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This list could go on and on!&lt;br /&gt;&lt;br /&gt;All of these questions should be addressed during design to ensure you and your team have a clear path of development. There are a bunch of open source tools out there especially in C# built into Visual Studio (and I'm sure Java has theirs too) that will parse through class files to generate UML diagrams ad hoc.&amp;nbsp;For ColdFusion developers, at the time of this entry,&amp;nbsp;&lt;a href="http://www.compoundtheory.com/"&gt;Mark Mandel&lt;/a&gt;&amp;nbsp;has been recently tweeting about a prototype he's working on&amp;nbsp;that will generate UML using&amp;nbsp;&lt;a href="http://colddoc.riaforge.org/"&gt;ColdDoc&lt;/a&gt;&amp;nbsp;and UML2 tools.&amp;nbsp;Initial&amp;nbsp;&lt;a href="http://www.yfrog.com/froggy.php?username=Neurotic"&gt;screen caps&lt;/a&gt;&amp;nbsp;looks promising,&amp;nbsp;so it's definitely something look out for. For more info check out Mark's&amp;nbsp;&lt;a href="http://twitter.com/Neurotic"&gt;twitter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'll also add that it's important to note that these tools should&amp;nbsp;&lt;b&gt;not &lt;/b&gt;be misused. Meaning you shouldn't develop first just to produce a class diagram against off-the-cuff code. These tools should be used when&amp;nbsp;you need a way to dynamically create accurate class diagrams from current code&lt;b&gt;&amp;nbsp;&lt;/b&gt;for a number of reasons:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You may be working within an enterprise level organization where there are multiple teams with their own special access to certain aspects of the code. Developers often need to know how to leverage an API in which they have no access to the source. In my experience that's where these automated UML tools come in handy. You can print it out and ship it off to whatever team needs it. From the UML, they can discern the contracts in which they need to develop against.&lt;/li&gt;&lt;li&gt;You don't have to deal with the headache of documentation maintenance.&lt;/li&gt;&lt;li&gt;You need to reverse engineer and&amp;nbsp;analyze&amp;nbsp;design at a high level, especially if the code base is pretty huge and there's a lot going on.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So that's class diagrams in a nutshell and hopefully you'll give the design before you develop approach a try if you haven't already. It may seem like a long and drawn out process at first but believe me practice makes perfect. Take it little by little. Maybe try it with that new module that needs developing or that module that is in need of some major refactoring that you've been putting off for months. After awhile, you'll be zipping through design sessions quickly because you've trained yourself to identify patterns and problems during that analysis phase. It'll eventually become second nature and you'll soon feel dirty &lt;i&gt;not &lt;/i&gt;doing some form of design up front.&lt;br /&gt;&lt;br /&gt;Hope this helps.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;-Micky&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Resources&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Beginning-C-Objects-Concepts-Code/dp/159059360X"&gt;Beginning C# Objects: From Concepts to Code&lt;/a&gt; -&amp;nbsp;&lt;b&gt;HIGHLY &lt;/b&gt;recommend this book for the beginner UML/OO developer. C# is in the title but the content applies to all languages.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-4578566604904294287?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/4578566604904294287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=4578566604904294287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/4578566604904294287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/4578566604904294287'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/design-before-you-develop-intro-to.html' title='Design Before You Develop - Intro to Class Diagrams with Quick Reference'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-6572579178581175614</id><published>2009-12-13T12:30:00.000-08:00</published><updated>2010-02-19T16:01:23.967-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='quicksilver'/><title type='text'>Quicksilver and REST</title><content type='html'>Let's talk about some REST a la Quicksilver shall we? In my &lt;a href="http://mickydionisio.blogspot.com/2009/12/quicksilver-framework-primer.html"&gt;Quicksilver primer&lt;/a&gt;&amp;nbsp;post I touched on what it's all about and its automatic dependency injection capabilities. Today we touch on another one of its core features - &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt;. If you are not familiar with the concept I encourage you to look into first before reading this post.&lt;br /&gt;&lt;br /&gt;Let's set&amp;nbsp;the stage. Imagine you built a simple informational design patterns site that explains design patterns. It's been in production for awhile now using OO best practices like service objects to be the intermediary between internal api calls and the data layer. This site has been using Quicksilver because they wanted a powerful flexible framework to one day use AOP and REST in addition to Automatic Dependency Injection just in case they needed to open up their API to other programs. Fast forward to now, they've been getting requests to open up their API via web services. They can use Quicksilver's REST support to do this &lt;i&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;easily&lt;/span&gt;&lt;/b&gt;.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;To understand how QS provides a simple solution to this, let's explore a possible alternative. They could develop soap based web services that consumes their service layer. Not a bad approach, but possibly time consuming and if done incorrectly can also lead to duplicate code since the methods will need to understand how to return json, xml, or a custom format. Also each web service endpoint would be exposed through a cfc - /path/to/webservice/&lt;b&gt;DesignPatterns.cfc?wsdl &lt;/b&gt;and call methods off that. &amp;nbsp;Ugly ugly ugly. Doing it this way is unorganized and resources are all over the place with crud-type methods names - saveThis(), updateThat(), getThis() etc. Get my drift? How does Quicksilver solve this?&lt;br /&gt;&lt;br /&gt;Let's dig into the code that we are about to REST'ify.&lt;br /&gt;&lt;br /&gt;We've got a design pattern service with one method &lt;b&gt;getCreationalPatterns()&lt;/b&gt;, it simply returns an array of strings whose values are pattern names. Here's the code:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/reg_service.png?attachauth=ANoY7cqBYb2CAZMG8G6seVeCP31Gq3ky1l3a56tJKialLblRfCT32ao-4L63FdLS7V2QX8giLWr_7cqIhJiqUw1N6m0A1sOJOHIbi7FHT-LG4wGd1MmRGAgXoRl5pS0gP9Rb_vWiNq5Ole1PIvHHpYo5fVSgU6PUP_T618JaO0ZVg5eLDqmfosw08wLVKTdFOXehE4MH5Ozwu7ETakz4nEKustdaVkeOMQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/reg_service.png?attachauth=ANoY7cqBYb2CAZMG8G6seVeCP31Gq3ky1l3a56tJKialLblRfCT32ao-4L63FdLS7V2QX8giLWr_7cqIhJiqUw1N6m0A1sOJOHIbi7FHT-LG4wGd1MmRGAgXoRl5pS0gP9Rb_vWiNq5Ole1PIvHHpYo5fVSgU6PUP_T618JaO0ZVg5eLDqmfosw08wLVKTdFOXehE4MH5Ozwu7ETakz4nEKustdaVkeOMQ%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Simple enough right?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We've got a singleton annotation at the top that tells Quicksilver that this should be handled as a singleton. This is part of automatic dependency injection baby.&lt;/li&gt;&lt;li&gt;getCreationalPatterns() simply returns an array. &lt;i&gt;In the real world this &lt;/i&gt;&lt;b&gt;&lt;i&gt;could (and should)&lt;/i&gt;&lt;/b&gt;&lt;i&gt; get as complex as you wanted to, perhaps delegating to a DAO or gateway or even another service but for this example let's &lt;b&gt;KISS&lt;/b&gt;.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Good, now take a look at the unit test written for this. Again keeping it simple, let's assert that we are getting five elements back. Using&amp;nbsp;&lt;a href="http://www.mxunit.org/"&gt;MXUnit&lt;/a&gt;, let's write it:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/test_design_patterns.png?attachauth=ANoY7crL668_lhQqCFkvxZxcrNIdTIK4ycVFiH_PDh8jU2V2PdVBqhIjz2kV3G3UKCCSPClfDH_8coaaa9LsVBi5ege6xTZRFl0KxFvC45Rwois4djFmJYzOvllYQ4J6-I3ZUrXQvUH_K4rXbwMA43cEYGLUWjOCRSQGWuDRDWT3VgesQCaIOyhMJiRgmJOtbzoSMWDA99hsT5_Ercecnzen5X8ELEmzeIklPZH9U9KWJo3uybzkssM%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/test_design_patterns.png?attachauth=ANoY7crL668_lhQqCFkvxZxcrNIdTIK4ycVFiH_PDh8jU2V2PdVBqhIjz2kV3G3UKCCSPClfDH_8coaaa9LsVBi5ege6xTZRFl0KxFvC45Rwois4djFmJYzOvllYQ4J6-I3ZUrXQvUH_K4rXbwMA43cEYGLUWjOCRSQGWuDRDWT3VgesQCaIOyhMJiRgmJOtbzoSMWDA99hsT5_Ercecnzen5X8ELEmzeIklPZH9U9KWJo3uybzkssM%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Test passed. Sweet.&lt;br /&gt;&lt;br /&gt;Ok so let's now expose this method as a RESTful endpoint that returns a json representation of creational patterns shall we? Let's &lt;b&gt;not &lt;/b&gt;create a new component and go through soap based web services, it too much work :) Let's use Quicksilver. How? Use &lt;b&gt;two&lt;/b&gt;, &lt;b&gt;&lt;i&gt;count em, two&lt;/i&gt;&lt;/b&gt; simple annotations in your service object.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;@url - this annotation is used to specify your url pattern.&amp;nbsp;&lt;/li&gt;&lt;li&gt;@httpMethod - possible values are GET, POST, DELETE, PUT. You can use multiple methods separated by commas.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;So here's the updated code:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/rest_service_restd.png?attachauth=ANoY7crb0C_IryymAvc1ewjGhIIR4ZmUz68nLuluJGUoFHuyQvXVsnCXC-Dm-0Owdwx-PrZVphwwY7uxEl0kvEd9x2K6k06rmkCAmGtUxjE8GpwFNh6DmZMocsJKq9Rq5qh3CQo-XvJZYVUyAhc-HrXhX3RqmKbZK8zTC1lxznKaanTkPw7NLRQGk1Oh5QL9Z26l9JsD_hCmHc8fNbAYgJVyttCt8bS9fA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/rest_service_restd.png?attachauth=ANoY7crb0C_IryymAvc1ewjGhIIR4ZmUz68nLuluJGUoFHuyQvXVsnCXC-Dm-0Owdwx-PrZVphwwY7uxEl0kvEd9x2K6k06rmkCAmGtUxjE8GpwFNh6DmZMocsJKq9Rq5qh3CQo-XvJZYVUyAhc-HrXhX3RqmKbZK8zTC1lxznKaanTkPw7NLRQGk1Oh5QL9Z26l9JsD_hCmHc8fNbAYgJVyttCt8bS9fA%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Lines 8-11 baby, that's all you need. Now when I crack open my browser and hit:&lt;br /&gt;&lt;blockquote&gt;http://localhost:8500/learnqs/howtorest/api.cfm/design/patterns/creational.json&lt;/blockquote&gt;We get a json representation like so:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/creationalpatternrep.png?attachauth=ANoY7cpDbPfUz2KKlDj4YdbapwmepSA1MUKbqAtATtK7zIgSmnmLTHb8714JsAX6_jWSxt16AMujrq6PaljyQMiCzMbh32uJZOe2Hc5_0mY3MarJuODRDcXArxOB1adN25Ghmibk27yKJJQO34k4P_WtiBYrH_Ks321XzY49q7MmBsB1VS0I1DT0lj2RGdj_SAPZEI0Y9riZJLwvM8KBGFbxHvFzGmSl3LMgZli9iGEch0TEPqesENo%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/creationalpatternrep.png?attachauth=ANoY7cpDbPfUz2KKlDj4YdbapwmepSA1MUKbqAtATtK7zIgSmnmLTHb8714JsAX6_jWSxt16AMujrq6PaljyQMiCzMbh32uJZOe2Hc5_0mY3MarJuODRDcXArxOB1adN25Ghmibk27yKJJQO34k4P_WtiBYrH_Ks321XzY49q7MmBsB1VS0I1DT0lj2RGdj_SAPZEI0Y9riZJLwvM8KBGFbxHvFzGmSl3LMgZli9iGEch0TEPqesENo%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;When opened looks like:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/creationalpatternrep_opened.png?attachauth=ANoY7coK3J-oGhGk9uHjoeMsQY9nEUF13AIVBvGhGF9if6ldpwAMA8CfXDQKYEABgRFvCqGyDXzRO5QeBW3ky7N555Wq9IX4aQJe6bRfv4dumO-59V3yaovzKFkj5zeniA_8wpiCluOcCP4l2HjvMqUUub9Iga3ePtw5Bqxh1COCgSToN_NUcTTePKhjZAOAT4UvMwmFvXYDOwtlA59ruDf-JX3n1uMrNVApoTrNLoidQcEAecrn3rM%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/creationalpatternrep_opened.png?attachauth=ANoY7coK3J-oGhGk9uHjoeMsQY9nEUF13AIVBvGhGF9if6ldpwAMA8CfXDQKYEABgRFvCqGyDXzRO5QeBW3ky7N555Wq9IX4aQJe6bRfv4dumO-59V3yaovzKFkj5zeniA_8wpiCluOcCP4l2HjvMqUUub9Iga3ePtw5Bqxh1COCgSToN_NUcTTePKhjZAOAT4UvMwmFvXYDOwtlA59ruDf-JX3n1uMrNVApoTrNLoidQcEAecrn3rM%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;See how easy that was? We've just opened up our API via restful web services to our consumers quickly and easily.When this URI is called from an ajax request, consumers are free to use the json representation of the creational patterns however they wish.&lt;br /&gt;&lt;br /&gt;Lets take a closer look at that URI:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uri.png?attachauth=ANoY7cq5EmfRTcRO53b4TRqYwzxo9otPYC1oXLE_eWPvv9HGo3PUzEsBaoXjL-Lp49rbprCLEcadaOejsK0uaEzIV5gDxGGFF0yDZvgKODKTXAknJdeyJ_2vqRNrBlcE6a-K2GSSIBNJqn2GRzJmf7LxsrFeILRRXPygUZ4HdF-pkAneXm3W_0_T-7KeS56CjqqLTaHaApiQ&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/uri.png?attachauth=ANoY7cq5EmfRTcRO53b4TRqYwzxo9otPYC1oXLE_eWPvv9HGo3PUzEsBaoXjL-Lp49rbprCLEcadaOejsK0uaEzIV5gDxGGFF0yDZvgKODKTXAknJdeyJ_2vqRNrBlcE6a-K2GSSIBNJqn2GRzJmf7LxsrFeILRRXPygUZ4HdF-pkAneXm3W_0_T-7KeS56CjqqLTaHaApiQ&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We've mapped an HTTP GET call to the url "/design/patterns/creational". Talk this out. Map a HTTP GET to the /design/patterns/creational resource and give it to me in json.&lt;/li&gt;&lt;li&gt;@httpMethod GET is the annotation to map an http method a function&lt;/li&gt;&lt;li&gt;api.cfm is the required cfm template that must exist for CF to parse the uri. This can be named whatever you want. index.cfm, rest.cfm, I just arbitrarily named it api.cfm.&amp;nbsp;&lt;span style="font-style: italic;"&gt;Again, as with any request that must go ColdFusion, you must go through a cfm page. In Quicksilver, however, that cfm page does&amp;nbsp;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;not&lt;/span&gt;&lt;/b&gt;&amp;nbsp;need to exist. Just the fact that its in the URL is enough, we'll take care of the rest. In our example, api.cfm is not a real file.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;After api.cfm comes the path we set in our @url annotation.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Automatic Serialization&lt;/b&gt; -&amp;nbsp;Quicksilver will automatically serialize arrays, structs and queries to json for you and since our return type is an array, automatic serialization is kicks in.&lt;/li&gt;&lt;li&gt;&lt;b&gt;By default the return of this call also returns an HTTP status code of 200. &lt;/b&gt;&lt;i&gt;&lt;b&gt;You have full control over the status codes as well.&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Easy right? Imagine this uri being called via ajax call from jQuery, ExtJS or whatever ajax feature you use. You'll get a json representation back.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lastly, you've heard use say again and again that the Quicksilver framework &lt;b&gt;does not get in your way&lt;/b&gt; and&lt;b&gt;&amp;nbsp;keeps your codebase HIGHLY testable&lt;/b&gt;. We're not just saying this to sound cool, we'll prove it. Lets re-run our unit test even after we &amp;nbsp;activated REST.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/test_after_rest.png?attachauth=ANoY7crD6-5WBBQd_jzxz0HKnGzebzajDPZ2ITCMj22tcP8NdOT6Yh42uSPEPMtKYS2YSqiFYcLqwdAFP3AAo8GVbxEn9dFie393gi7bh17ohsWM1TvE6cTZgOEr_huVzHr97cMqZrbxXqu5WfGh6a_q7Klxtx2Ae9uy0GLKoMsfFaEBNwx2EEsCstNtG1_sweGu4uK5QhRaJY5Q8DfVf53svoWuLa0sMg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/test_after_rest.png?attachauth=ANoY7crD6-5WBBQd_jzxz0HKnGzebzajDPZ2ITCMj22tcP8NdOT6Yh42uSPEPMtKYS2YSqiFYcLqwdAFP3AAo8GVbxEn9dFie393gi7bh17ohsWM1TvE6cTZgOEr_huVzHr97cMqZrbxXqu5WfGh6a_q7Klxtx2Ae9uy0GLKoMsfFaEBNwx2EEsCstNtG1_sweGu4uK5QhRaJY5Q8DfVf53svoWuLa0sMg%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Look at that :) Test still passed. There's your proof. Quicksilver doesn't inject itself into your code rather it hangs out outside of it. It allows you to implement code and test without the framework in your way and we mean it. How? Via annotations baby! Read more about in the&amp;nbsp;&lt;a href="http://mickydionisio.blogspot.com/2009/12/quicksilver-framework-primer.html"&gt;Quicksilver&lt;/a&gt;&amp;nbsp;primer post if your confused.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;i&gt;side note: Just FYI - Quicksilver also supports &lt;b&gt;custom representations&amp;nbsp;&lt;span style="font-weight: normal;"&gt;prepended with whatever extension you want - .extjs? .pdf? .myCoolExtension?.&lt;b&gt;&amp;nbsp;Also allows you to have FULL control on HTTP&amp;nbsp;&lt;/b&gt;&lt;b&gt;status codes that are returned as well as the ability to send variables via the URL, http raw post, form post etc.&lt;/b&gt;&amp;nbsp;&amp;nbsp;No problem. We'll get to that in future blog posts, promise. Or check out Brian's Quicksilver blog. Link at the end of the article.&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So to wrap up, I hope you now see how Quicksilver is as unobtrusive as possible. We REST'd our application with no added components, no messy soap web services, no duplicate code all while remaining organized and &amp;nbsp;highly testable.&amp;nbsp;No framework artifacts riddling your awesome code. How about that? A framework that actually cares about risk management.&lt;br /&gt;&lt;br /&gt;-Micky&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Resources&lt;/b&gt;&lt;br /&gt;&lt;a href="http://quicksilver.riaforge.org/blog/"&gt;Quicksilver Blog&lt;/a&gt; - entries by the one and only Brian Carr. Check it out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-6572579178581175614?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/6572579178581175614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=6572579178581175614' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/6572579178581175614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/6572579178581175614'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/quicksilver-and-rest.html' title='Quicksilver and REST'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-1620751347406750490</id><published>2009-12-11T14:22:00.000-08:00</published><updated>2010-02-19T16:05:37.984-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='object orientation'/><title type='text'>Quick Tip - See nested conditionals? Consider Guard Clauses</title><content type='html'>&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Just a quick tip when you are refactoring code with crazy nested if/else logic. As a rule of thumb if you see a method that has conditional statements check to see if these exists:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Is there a private variable, let's call it &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; that is private to the function that is being set within each (or at least a majority) of the if/case legs whose value is a method call?&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Is&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;x &lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;is being returned at the end of the method?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;You got nested conditionals?&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Here is what it would would like:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/nogaurds.png?attachauth=ANoY7cp-lZ7cSwZJsDNYeLNZmrTrOLteYaYDBYKgwDPd1XobIV0s3ERZdZSQPomkzosVlgLJBbdAnzzRgVGSRBLTQh5vNrfotS2QcGZe-T7de9zbgIIjxbgPfUtgE1f_asbu_XtPMf4vEZO77XPkBwmaMox_dndXtAs2jUqeu4qQmYQXL52J5xtvyjc6DbbkcsGD7bpqCihQmKIIJGvjPBVTUOfjf4yCVg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/nogaurds.png?attachauth=ANoY7cp-lZ7cSwZJsDNYeLNZmrTrOLteYaYDBYKgwDPd1XobIV0s3ERZdZSQPomkzosVlgLJBbdAnzzRgVGSRBLTQh5vNrfotS2QcGZe-T7de9zbgIIjxbgPfUtgE1f_asbu_XtPMf4vEZO77XPkBwmaMox_dndXtAs2jUqeu4qQmYQXL52J5xtvyjc6DbbkcsGD7bpqCihQmKIIJGvjPBVTUOfjf4yCVg%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Notice the:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; &amp;nbsp;private variable at the beginning of the function&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; is being returned at the end of the function&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Nasty nasty nasty nested conditional that sets &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;result to the value of a method&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;If the above is true or the code you are refactoring looks similar to this, you might want to look into using guard clauses. Sounds more complicated than it really is. Basically see if you can refactor it like so:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Remove the private variable thats being set during each if/else leg.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Return the method or the condition that is setting it.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Simple as that. Here is the code above refactored:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/withguards.png?attachauth=ANoY7cr9iGe_lPu8zczOWHFKCP0VZcg0fmQtZOjqoDYsNEjNJidCIqXYS9MlJOvgLxE9gJZiNhgNU0EakM5xpPWVensu5YTOWBXkkKrPPxdTrcOCzwhkx1mOiepwo6paBGnA-_4qTbij4rCn4HNeHLbvGLnrfqV_jA4sQei7LpeHsgqWtvwNmiH2l8R13De-zEGXsomrze0-AEWoQGAtXJhwWuMV68f6IA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/withguards.png?attachauth=ANoY7cr9iGe_lPu8zczOWHFKCP0VZcg0fmQtZOjqoDYsNEjNJidCIqXYS9MlJOvgLxE9gJZiNhgNU0EakM5xpPWVensu5YTOWBXkkKrPPxdTrcOCzwhkx1mOiepwo6paBGnA-_4qTbij4rCn4HNeHLbvGLnrfqV_jA4sQei7LpeHsgqWtvwNmiH2l8R13De-zEGXsomrze0-AEWoQGAtXJhwWuMV68f6IA%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Notice now:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;No more nested if's&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;After each if/else leg, we are returning the method.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Given that some legacy methods you are trying to refactor are not as trivial as this and each have their own unique level of suck - this is always a good start. This keeps your method simple, less complex and highly testable because each execution path is linear. Guard clauses baby, a good alternative to the &lt;a href="http://mickydionisio.blogspot.com/2009/12/understanding-strategy-pattern-and.html"&gt;strategy pattern&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;HTH&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;-Mick&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-1620751347406750490?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/1620751347406750490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=1620751347406750490' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/1620751347406750490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/1620751347406750490'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/quick-tip-see-nested-conditionals.html' title='Quick Tip - See nested conditionals? Consider Guard Clauses'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-7794691655595773748</id><published>2009-12-10T08:48:00.000-08:00</published><updated>2010-02-19T16:05:25.766-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software design'/><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='object orientation'/><title type='text'>Understanding Strategy Pattern and Polymorphism - Two Birds With One Stone</title><content type='html'>&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;First off, many thanks to the people that messaged me saying they enjoyed the&amp;nbsp;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;a href="http://mickydionisio.blogspot.com/2009/12/using-observer-pattern-to-save.html"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Observer Pattern&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&amp;nbsp;tutorial for saving composites. I'm really glad it helped&amp;nbsp;demystify&amp;nbsp;patterns and OO for you! &lt;i&gt;And can I add it was pretty cool that these people were a mix from both CF and C# camps :)&lt;/i&gt;&amp;nbsp;I am a big advocate of design patterns so I will not be shutting up about them anytime soon, sorry!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Today I wanted to touch on my favorite &lt;a href="http://en.wikipedia.org/wiki/Behavioral_pattern"&gt;behavioral&lt;/a&gt;&amp;nbsp;pattern - the &lt;b&gt;Strategy Pattern&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;What does this pattern solve? If you have an object that:&lt;/span&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Is constantly being subclassed just to override specific implementations (methods).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Has a &lt;a href="http://www.urbandictionary.com/define.php?term=fugly"&gt;fugly&lt;/a&gt;&amp;nbsp;method(s) that has to run through a mine field of if/case statements just to execute.&lt;/span&gt;&lt;/li&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;                  &lt;/div&gt;&lt;/ol&gt;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Let me start of by first saying when you use this pattern you can truly see&amp;nbsp;&lt;i&gt;polymorphism at its finest&lt;/i&gt;. And yes, polymorphism is achievable through ColdFusion. If someone tells you different, they are smoking crack. Say no to drugs.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;I won't bore you with the computer science explanation of polymorphism so here's my simple, to-the-point summation. If objects are of different types &lt;b&gt;but&lt;/b&gt;&amp;nbsp;share &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;a common&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: arial, sans-serif;"&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;derivative(s)&lt;/span&gt;&lt;span style="font-weight: normal;"&gt;, they should&lt;/span&gt;&lt;/b&gt;&amp;nbsp;&lt;/span&gt;be interchangable. This should help, lets keep it simple:&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;If A = B and A = C then B = C.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;In the example above, B and C can behave polymorphically because they both share a commonality - they both are a&amp;nbsp;&lt;span style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; border-collapse: collapse; font-family: arial, sans-serif; font-size: 17px; white-space: pre;"&gt;derivation&lt;/span&gt;/implementation of A. &lt;b&gt;Understand this critical principle&lt;/b&gt; of OO and you are well on your way to your OO awakening.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Moving on. Here's the official definition of the Strategy Pattern:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="line-height: 21px;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Define a family of &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;algorithms&lt;/span&gt;&lt;/b&gt;, &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;encapsulate&lt;/span&gt;&lt;/b&gt; each one, and make them &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;interchangeable&lt;/span&gt;&lt;/b&gt;. Strategy lets the algorithm vary independently from clients that use it.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;What's this mean? I've underlined the key words in this definition. When you hear&amp;nbsp;&lt;span style="color: blue; font-weight: bold; line-height: 21px;"&gt;&lt;span style="text-decoration: underline;"&gt;algorithms&lt;/span&gt;&lt;/span&gt;, think &lt;b&gt;verbs &lt;/b&gt;which mean &lt;b&gt;methods&lt;/b&gt;. When you hear&amp;nbsp;&lt;span style="color: blue; line-height: 21px;"&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;encapsulate&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;, think about &lt;b&gt;delegating&lt;/b&gt; responsibilities to new objects whose &lt;b&gt;sole&lt;/b&gt; purpose is&amp;nbsp;to protect "&lt;i&gt;something&lt;/i&gt;" and ensure that these objects are doing &lt;b&gt;only&lt;/b&gt; &amp;nbsp;"&lt;i&gt;something&lt;/i&gt;" and doing it well (&lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;SRP principle&lt;/a&gt;). And lastly, when you hear&amp;nbsp;&lt;span style="color: blue; font-weight: bold; line-height: 21px;"&gt;&lt;span style="text-decoration: underline;"&gt;interchangeable&amp;nbsp;&lt;/span&gt;&lt;/span&gt;think &lt;b&gt;polymorphism&lt;/b&gt;. I'll reword that definition a bit to be in line with what I just described.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: blue;"&gt;Define a family of &lt;b&gt;methods &lt;/b&gt;and&amp;nbsp;make sure you've encapsulated each distinct&amp;nbsp;method implementation (algorithm)&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;away&lt;/b&gt;&amp;nbsp;into new objects so these objects may be &lt;b&gt;switched out polymorphically at run time&lt;/b&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;First, here's an abstract class diagram I put together:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/StrategyHighLevel2.png?attachauth=ANoY7cpCkfWzP569nbL29YIj6z37Wm0D24OLG8UT8wG1D47ULk0isc7zzHtGDRW39Va5Tcw2l_YD2w8061ENnG4tZfvdATrhzvvJlK8szp6J0abWQ2MlO1NgYHjH_ACr5RN1CyzSvZdNXNXAqPHfyh83GMl2kdwRLKLGpRL8JpxIgilYykmZFjWkUaGoh9siS1FJ_IcVMYaKTxWrBFh1KBkF384Rf2My5g%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/StrategyHighLevel2.png?attachauth=ANoY7cpCkfWzP569nbL29YIj6z37Wm0D24OLG8UT8wG1D47ULk0isc7zzHtGDRW39Va5Tcw2l_YD2w8061ENnG4tZfvdATrhzvvJlK8szp6J0abWQ2MlO1NgYHjH_ACr5RN1CyzSvZdNXNXAqPHfyh83GMl2kdwRLKLGpRL8JpxIgilYykmZFjWkUaGoh9siS1FJ_IcVMYaKTxWrBFh1KBkF384Rf2My5g%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;For the purposes of this tuorial just imagine that the inside of the &lt;b&gt;legacy&lt;/b&gt;&amp;nbsp;code for subject.doStrategy() you've got the if/case problem going on. It's riddled with them.&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;i&gt;e.g. -if something, set this then return this way, if something else set that and return that way&lt;/i&gt;.&amp;nbsp;You get the idea.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;In the class diagram above notice:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;We have a Subject, think of this as concrete class that has a composite relationship to an implementation of IStrategyBehavior which subject.doStrategy() delegates to.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;The idea is that subject.doStrategy() should&amp;nbsp;&lt;b&gt;NOT&lt;/b&gt; have any switches or ifs or&amp;nbsp;overridden&amp;nbsp;via subclassing just to provide concrete implementation.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Also notice the UML note. We delegate to another object that implements IStrategyBehavior through composition (Subject is composed of IStrategyBehavior), this is where that whole "&lt;span style="color: blue; line-height: 21px;"&gt;encapsulate&amp;nbsp;each one, and make them&amp;nbsp;&lt;b&gt;&lt;span style="font-weight: normal;"&gt;interchangeable&lt;/span&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="color: black;"&gt;" is happening. We're saying listen, Subject, yes you will doStrategy() however you are delegating to a "strategy" property and ask it to call its own doStrategy(). This means at runtime you, Subject, don't care about &lt;i&gt;how&lt;/i&gt; your are doStrategy()'ing, you're handing it of to your polymorphic property "strategy" and calling doStrategy() on that.&amp;nbsp;We've just encapsulated that behavior &lt;b&gt;away &lt;/b&gt;from Subject into its own set of classes or&amp;nbsp;&lt;i&gt;family of algorithms&lt;/i&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small; line-height: 21px;"&gt;OK now we can move on to concrete designing but first lets understand our requirements We're going to use the standard gaming example well because COD:Modern Warfare 2 just came out and it's glorious. &lt;/span&gt;&lt;span style="line-height: 21px;"&gt;&lt;span style="font-size: x-small;"&gt;(xbox live : Error401, add me)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small; line-height: 21px;"&gt;Build a Soldier that can fight()&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small; line-height: 21px;"&gt;fight() cannot have any if's/switches inside of it&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small; line-height: 21px;"&gt;fight() will execute differently based off what weapon Soldier is holding - Pistol, Rocket Launcher and Machine Gun&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Here is the concrete design:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/strategy_concrete.png?attachauth=ANoY7coJAB8I7DGIhG4kDAJGYlcYudP5q2NaFQ-zHO89Qi5O4W2I_n1xj2VLG7ScPFJoxZKdvCxcOy-DKz-2gqFupOf-Ejz8R_Es3n8oQqrZgbwrCSm66_CymBY5C3oWssZUFhSmKBsLaLC98Q0KuWLxX1X5vztwi1gd6xP0P5oImDaQC3w1SKqA4MrCq0nt1ow_ttz7_bsCJ2_eQX6B-rlVkQuRSiBuMw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/strategy_concrete.png?attachauth=ANoY7coJAB8I7DGIhG4kDAJGYlcYudP5q2NaFQ-zHO89Qi5O4W2I_n1xj2VLG7ScPFJoxZKdvCxcOy-DKz-2gqFupOf-Ejz8R_Es3n8oQqrZgbwrCSm66_CymBY5C3oWssZUFhSmKBsLaLC98Q0KuWLxX1X5vztwi1gd6xP0P5oImDaQC3w1SKqA4MrCq0nt1ow_ttz7_bsCJ2_eQX6B-rlVkQuRSiBuMw%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Here notice the following:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;We've modeled a Soldier &lt;span style="color: blue;"&gt;(Subject)&lt;/span&gt; and are creating a strategy pattern for subject.fight().&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Interface ISolder has a fight() method with the &lt;b&gt;same&lt;/b&gt; contract for for fight() in IFightBehavior.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;We've created three concrete implementations &lt;span style="color: blue;"&gt;(concrete strategies)&lt;/span&gt; of IFightBehavior - PistolBehavior, MachinegunBehavior and RocketLauncherBehavior.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: red;"&gt;Side note :&lt;/span&gt; This pattern can also be achieved through an abstract class and subclassing but try to stay away from inheritance as much as you can. Favor composition and interface based programming. You have more flexibility that way.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Code time - Soldier.cfc (I've omitted showing the interfaces. It should be straight forward how to create them from the class diagram above):&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/soldier.png?attachauth=ANoY7cqRQjiP09WhW-uedI0gnT8D1hahZlsmL6oLSqjRFqCFm-li_Wi8bBfe88JBE2wfdG68itg6neSaYvuwT55S5orIV8ad6vea9g3IR2aH0mJb0tsP1a7bsf1aKDR-VMmOodySePX3eNsGM0ezwOkbiQ6eu-JDYdVqKaEbQeRCuRFpgcL6ut8dOM8Y8Hy7pECUWaxLdnJCenhtyb8GVV7qf7imZGjKgA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/soldier.png?attachauth=ANoY7cqRQjiP09WhW-uedI0gnT8D1hahZlsmL6oLSqjRFqCFm-li_Wi8bBfe88JBE2wfdG68itg6neSaYvuwT55S5orIV8ad6vea9g3IR2aH0mJb0tsP1a7bsf1aKDR-VMmOodySePX3eNsGM0ezwOkbiQ6eu-JDYdVqKaEbQeRCuRFpgcL6ut8dOM8Y8Hy7pECUWaxLdnJCenhtyb8GVV7qf7imZGjKgA%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: red;"&gt;Critical &lt;/span&gt;piece of code on line 2 - &lt;b&gt;fightBehavior is polymorphic&lt;/b&gt;. Interface based programming baby. In most of my examples I will program to an interface, not an implementation (concrete type). At run time this property can be switched out by&amp;nbsp;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;b&gt;any&lt;/b&gt; object that implements IFightBehavior. That's polymorphism peeps. Simple as that. Don't&amp;nbsp;over complicate&amp;nbsp;it.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;fight() delegates to the fightBehavior property. In the abstract portion of this entry, when I said that a Subject, in this case Soldier, doesn't care &lt;i&gt;how&lt;/i&gt;&amp;nbsp;it does doStrategy(), in this case fight() - this is exactly what I mean. You're simply calling getFightBehavior().fight(). Soldier doesn't care &lt;i&gt;how&lt;/i&gt;&amp;nbsp;its actually doing it because it could be doing it &lt;i&gt;n &lt;/i&gt;number of ways through polymorphism&lt;i&gt;. &lt;/i&gt;All Soldier cares about is that fight() returns a string. And we the developer have ensured that it will since fightBehavior implements the IFightBehavior interface which also has a matching fight() method that expects a return of string.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Here is what your concrete behaviors might look like. I've consolidated it into one image in order - PistolBehavior (goes Bang!), MachineGunBehavior(lots of bangs!) and RocketLauncherBehavior(goes Boom!):&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/strategy_concrete_behaviors.png?attachauth=ANoY7cp_S5zbyfOZztgxVWUnCQtP8u1Unv_t2Fr3wO0kFMiS4sMyKHUnzJKh14GSnk2sGB1KoozoXbNnbbFb05Ba6vZ6S6ZK1UU1TR41076oumVBA7ylQKt06hPfdhBr1Rb6DhLQEUSIHEyF0JWJ2cV8jN0gBoTS24GBP-0skY_C-v-UQRZTaIq0dmM2NdlMBPCK2e2oCktJH3tBSE1ZckQsPzR8TKYrBomPTlE3lB87PeLJ_An34Tg%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/strategy_concrete_behaviors.png?attachauth=ANoY7cp_S5zbyfOZztgxVWUnCQtP8u1Unv_t2Fr3wO0kFMiS4sMyKHUnzJKh14GSnk2sGB1KoozoXbNnbbFb05Ba6vZ6S6ZK1UU1TR41076oumVBA7ylQKt06hPfdhBr1Rb6DhLQEUSIHEyF0JWJ2cV8jN0gBoTS24GBP-0skY_C-v-UQRZTaIq0dmM2NdlMBPCK2e2oCktJH3tBSE1ZckQsPzR8TKYrBomPTlE3lB87PeLJ_An34Tg%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;The classes simply implement IFightBehavior and provide a concrete implementation for fight() in their own unique way. This is&amp;nbsp;their&amp;nbsp;&lt;b&gt;only&lt;/b&gt; responsibility.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;These three classes are now interchangeable with any return type, property or method argument with the type of IFightBehavior. Like where? Like in Soldier's fightBehavior property!&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;And finally the implementation and the results when run:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/strategy_results.png?attachauth=ANoY7coTle-Pzv0USAv0YUVYsJfV_65Uxxj8vzSIf_m_Gstg7m5xxIFfDNGk8vadXRXUDpyRSwOwcsOraYJwoD-YUkLTWDM2mcteyVAFEwIvW8GxRU2nzfnEd_j_VNJpCXZjcVy101IZkvGSCi8WaoGTyTIubOm7Ktnp8xlxkZxKKH9tBfjUEXm48q5rcfgmEfkVj3ncUmiNCyyp9nXLRhI3Wg5CoNEAvQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/strategy_results.png?attachauth=ANoY7coTle-Pzv0USAv0YUVYsJfV_65Uxxj8vzSIf_m_Gstg7m5xxIFfDNGk8vadXRXUDpyRSwOwcsOraYJwoD-YUkLTWDM2mcteyVAFEwIvW8GxRU2nzfnEd_j_VNJpCXZjcVy101IZkvGSCi8WaoGTyTIubOm7Ktnp8xlxkZxKKH9tBfjUEXm48q5rcfgmEfkVj3ncUmiNCyyp9nXLRhI3Wg5CoNEAvQ%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/strategy_results.png?attachauth=ANoY7coTle-Pzv0USAv0YUVYsJfV_65Uxxj8vzSIf_m_Gstg7m5xxIFfDNGk8vadXRXUDpyRSwOwcsOraYJwoD-YUkLTWDM2mcteyVAFEwIvW8GxRU2nzfnEd_j_VNJpCXZjcVy101IZkvGSCi8WaoGTyTIubOm7Ktnp8xlxkZxKKH9tBfjUEXm48q5rcfgmEfkVj3ncUmiNCyyp9nXLRhI3Wg5CoNEAvQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;While I'm hard coding the actual setFightBehavior() above, let's imagine that the setting of the weapon came from a weapon select box from a form. When the form is posted you process the selections and dynamically set the behavior and subsequently call &lt;i&gt;soldier.fight()&lt;/i&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;If you added 50 more weapons to the select box as long as there were 50 more behavioral classes that implemented IFightBehavior, your consuming code DOES NOT CHANGE and you don't have to needlessly subclass and override methods anymore. That's the beauty and power of this pattern - polymorphism at runtime which keeps your API clean. In our example above, calls to &lt;i&gt;solder.fight()&lt;/i&gt; need not change.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;i&gt;&lt;span style="font-style: normal;"&gt;To drive it home for the last time. A solution without this pattern would most likely force you to add additional subclasses or add if/case's in solder.fight() that checks for weapon a soldier is holding, do some process logic then execute fight() in a specific fashion. Unnecessary complexity.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;So there you have it - the strategy pattern in a nutshell. I've managed to work out some pretty slick solutions with this pattern in CF and C# from organizing complex search algorithms to encapsulating gnarly business logic and I'm sure you could find umpteen more uses for it. This pattern keeps complexity low, forces objects to be highly focused with singular responsibility all while being easily scalable and&amp;nbsp;maintainable.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Hopefully I helped you get another step closer to object oriented design pattern nirvana. And remember, as&amp;nbsp;&lt;a href="http://www.aliaspooryorik.com/blog/"&gt;John Whish&lt;/a&gt; said to me and I couldn't agree more, &lt;i&gt;"&lt;/i&gt;&lt;span style="color: #333333; font-family: 'Lucida Grande', sans-serif; font-size: 14px; line-height: 16px;"&gt;&lt;i&gt;Death to inheritance - long live the strategy pattern!"&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;-Mick&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;p.s. - which pattern is next?&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-7794691655595773748?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/7794691655595773748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=7794691655595773748' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/7794691655595773748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/7794691655595773748'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/understanding-strategy-pattern-and.html' title='Understanding Strategy Pattern and Polymorphism - Two Birds With One Stone'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-3444894897186030621</id><published>2009-12-09T02:05:00.000-08:00</published><updated>2010-02-19T16:02:14.730-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coldfusion'/><title type='text'>ColdFusion Comes of Age - Community to Follow?</title><content type='html'>&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;About a month ago my fellow CF'er&amp;nbsp;&lt;a href="http://www.mikechandler.com/"&gt;Mike Chandler&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; showed me this&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;a href="http://www.techcrunch.com/2009/11/02/mfg-com-takes-off-the-cuffs-with-manufacturing-marketplace-redesign/"&gt;article&lt;/a&gt;. The initial once over was quick with only a handful of comments that made me chuckle then I moved on. As I was sifting through old email I found the link and decided to see where the conversation went, if anywhere. That, my friends, is what&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;inspired this blog post.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Basically a CEO announced a launch of their new site which was rebuilt in Java and somewhere in the post called ColdFusion outmoded. I’m writing this entry not because I’m miffed that he called ColdFusion outmoded, I’m writing this because of some, not all, of the responses that ensued. People are entitled to their opinion both the CEO of MFG and the responders alike but I really couldn’t believe the level of back and forth going on between commenters. Some responses reminded me of elementary school where kids are cracking “your momma” jokes back and forth, getting heated over well, nothing. Sarcastic banter and throwing out stats is &lt;b&gt;not &lt;/b&gt;going to make your point, &lt;/span&gt;&lt;i&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;especially&lt;/span&gt;&lt;/i&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; in a forum. And seriously, all the CEO said was that it was "outmoded". Give me a break, that is &lt;b&gt;n&lt;/b&gt;&lt;b&gt;ot &lt;/b&gt;a big deal people.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;So this got me thinking, “What do we as a community need to do to be taken seriously?”. Here's my $.02.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;First, let’s &lt;/span&gt;&lt;b&gt;&lt;u style="text-decoration: none;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="text-decoration: underline;"&gt;stop&lt;/span&gt;&lt;span style="font-weight: normal;"&gt; bashing other languages. There's something to learn in every language regardless of what side of the fence you are on and whether you care to admit it or not, its true. There is always something to learn. &lt;i&gt;Always&lt;/i&gt;.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Secondly, let's &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;stop&lt;/span&gt;&lt;/b&gt; responding immaturely when someone says “ColdFusion &lt;/span&gt;&lt;i&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;{insert derogatory verb here}&lt;/span&gt;&lt;/i&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;”.&amp;nbsp;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Let it go. Breathe. Do a 10 count. I get it, we are all passionate about ColdFusion. &lt;b&gt;But &lt;/b&gt;we should be even &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;more&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; passionate about what ColdFusion is used for -&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;software engineering&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;. More passionate about &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;solving complex problems&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; that completely kick our ass. The kind of problems that you find yourself solving when you're dozing in and out of consciousness in the middle of the night cause you can't sleep, just to wake up still trying to solve it and can't get that computer on fast enough. And hey, in my experience ColdFusion allows you to solution&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;those types of problems and solution them pretty damn well - thats why I love it just as do you.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Adobe and the ColdFusion team hit the nail on the head with CF9. They’ve armed us with the capabilities to enter the arena and stand and bang like the big boys. It gives us the ability to execute the core tenets of object oriented programming - encapsulation, inheritance and polymorphism.&amp;nbsp;It makes OO feel natural just like C++, Java and C# with its new and improved script syntax and quick object creation.&amp;nbsp;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;It feels &lt;b&gt;grown up&lt;/b&gt;. It feels like it has&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;come of age&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;. It demands to be taken seriously. &lt;b&gt;But&lt;/b&gt; there’s one &lt;span style="color: red;"&gt;&lt;b&gt;critical&lt;/b&gt;&lt;/span&gt; piece missing. We as a development community need to &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;come of age&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; with it. We need to mature. We need to start designing before we write code. We need to really understand &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;object orientation&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; and &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;design patterns. &lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Strive to be&lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; software engineers&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;, not just &lt;b&gt;complacent&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;code monkeys&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;. We need to advocate designing before we develop because identifying problems with our architecture while it’s in design is much better than discovering them hundreds of hours into development and hundreds of $'s in the hole. We need to&amp;nbsp;design, poke holes, re-design, poke more holes,&amp;nbsp;&lt;i&gt;then &lt;/i&gt;&lt;i&gt;lastly&lt;/i&gt; start&lt;i&gt;&amp;nbsp;&lt;/i&gt;coding (this should be the easy part). But hey even if you need to rework design during development, your design should be such that its easy to&amp;nbsp;&lt;b&gt;maintain and modify&lt;/b&gt;.&amp;nbsp;We need to architect applications that scale. That are flexible.&amp;nbsp;We need to understand &lt;b&gt;&lt;i&gt;why&lt;/i&gt;&lt;/b&gt; to use Framework A, B, and C and more importantly &lt;b&gt;&lt;i&gt;how&lt;/i&gt;&lt;/b&gt; they work under the hood. We need to fully &lt;b&gt;understand the problems&lt;/b&gt;&amp;nbsp;these frameworks were created to solve.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Lastly and &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;most important&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;, we need to &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;solve problems&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; just like the big boys and be sure to &lt;b&gt;share &lt;/b&gt;the solutions amongst each other. Problems whose solutions &lt;/span&gt;&lt;b&gt;&lt;u&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;cannot&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;be summed up with “&lt;i&gt;check out how I used this really cool CF feature to create a pdf or make an ajax request&lt;/i&gt;”. Other languages and developers don’t care about that. They’ve got their own cool features that they'll argue it puts yours to shame and vice versa. &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;We need to solve problems that transcend languages&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;. Problems that only&lt;b&gt;&amp;nbsp;sound&lt;/b&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;design,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;architecture, design patterns and well written, efficient algorithms&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;can solve. Once you solved it, share your solution. Get involved. Publish it. It’s only then that we can be taken more seriously. It's only then we can &lt;b&gt;&lt;i&gt;share&lt;/i&gt;&lt;/b&gt; complex solutions that programmers from other languages&lt;i&gt;&amp;nbsp;&lt;/i&gt;can stumble upon and implement. Solutions that came from the mind of a &lt;b&gt;ColdFusion software engineer&lt;/b&gt;. A solution that programmers from another language can &lt;b&gt;respect&lt;/b&gt; and apply with their language of choice.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;CF9&lt;b&gt; &lt;i&gt;has&lt;/i&gt;&lt;/b&gt;&lt;i&gt; &lt;/i&gt;&lt;b&gt;come of age&lt;/b&gt; and has equipped us to do all of the above. It’s been our responsibility as a community to &lt;b&gt;come of age&lt;/b&gt; with it. Next time that startup comes knocking, do it right from the beginning. The next time that corporate piece of software needs a new module, do it right from the beginning. Do it object oriented. Use frameworks for the right reasons. Even dive into design patterns. There is a reason for object orientation and blackboxing, that's why its taught in computer science. Don't fight it and know that advice and direction is only a tweet or email away - our community is great about that. Apply those concepts and over time that piece of software you wrote will grow and scale easily and it's then that your piece of software will be a testament to ColdFusion and its capabilities. It's then we'll no longer have to squabble over statistics because we've got proof of high profile adoption.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;We're on the path to get there. We have a fricking ton of brilliant minds in this community doing some very cool things every single day, &lt;i&gt;you&lt;/i&gt; included.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;So let's walk the walk and &lt;b&gt;stop &lt;/b&gt;talking the talk. Let's build better software as a community. It'll end up speaking for itself.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;-Micky&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-3444894897186030621?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/3444894897186030621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=3444894897186030621' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/3444894897186030621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/3444894897186030621'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/coldfusion-comes-of-age-community-to.html' title='ColdFusion Comes of Age - Community to Follow?'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-2140443410412700604</id><published>2009-12-08T11:38:00.000-08:00</published><updated>2010-02-19T16:02:23.218-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mxunit'/><title type='text'>MXUnit - DataProvider Goodness</title><content type='html'>&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Just when I thought my unit tests were pretty dang light its become even lighter after I came across &lt;/span&gt;&lt;/span&gt;&lt;a href="http://blog.mxunit.org/2009/11/data-driven-testing-with-mxunit.html"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Marc Esher's blog post&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt; about DataProviders that shipped with the new &lt;a href="http://blog.mxunit.org/2009/11/mxunit-108-released.html"&gt;MXUnit 1.0.8 release&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;In my unit tests, especially tests that are very data driven like DAO's and validators I found myself doing this alot:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/dp_annoying.png?attachauth=ANoY7cptTlxS9smyLSqJxkx38lSHE6E3ItKTdjG2nD6P91GsB70B4UU6lsFAqHbTlqC0oAmts_Heg7weUp06EtS-JdoVz8cwBZdRXUv27NMHyqsfD1omZuxoVzpgvnuLrDi5ZaGSIlyDoN-qPgLFm0Xqs9BkrnHgnFSs4-qAU7NA23FiL1nY_l7WgtIr7xvUnvlhcT1CivRH-y-NBJqKsRliRpkwGjQJvQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/dp_annoying.png?attachauth=ANoY7cptTlxS9smyLSqJxkx38lSHE6E3ItKTdjG2nD6P91GsB70B4UU6lsFAqHbTlqC0oAmts_Heg7weUp06EtS-JdoVz8cwBZdRXUv27NMHyqsfD1omZuxoVzpgvnuLrDi5ZaGSIlyDoN-qPgLFm0Xqs9BkrnHgnFSs4-qAU7NA23FiL1nY_l7WgtIr7xvUnvlhcT1CivRH-y-NBJqKsRliRpkwGjQJvQ%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;As the screencap shows, there are many time where you need to setup data sets that will be used during assertions or mocks and usually start out inline. You'll find yourself &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;duplicating tests&lt;/span&gt;&lt;/b&gt; that really assert the same thing just with a &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;different data set&lt;/span&gt;&lt;/b&gt;. I admit that in unit tests I've become lazy and often times do not even create a private method that returns a pseudo dataset for reuse, yea yea I'm sorry. I just duplicate this code above in each method that needs it because it feels innocuous in a test, I mean after all its simply a query with one record for goodness sake. Well with the new MXUnit data providers its time for me to stop whining because they've made it extremely easy to declare a dataset (DataProvider) and have it injected into the test by doing just three things so:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Create your dataprovider in the setup() as a class level member (variables scope)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Annotating your function using the&amp;nbsp;@mxunit:dataprovider annotation with the value being the dataprovider you want to inject.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Referencing that dataset as an argument in your test method&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Here's how it looks like now (with the provider flow):&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/dataprovider_better.png?attachauth=ANoY7cqMRJoi88Wj1GaI98RuQU8Hr-AbfT2UUERCAdIPkT19XuBux-kjyYWZRQ39iVrVA_2dj7hxXTRCIRks5ysb5-sUtT9HkqxlruqFj-0YOlhMpKJ1EKIjINFev1FEA0ONIIc-7Yro-DrmJG8VLAeq684i7WhsKLnpyp1Id4SR66h8xhYTgjGHcKsKAvpUL8iN3AvY1HPB3VV74jCncEmiOdEzz0v8Lw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/dataprovider_better.png?attachauth=ANoY7cqMRJoi88Wj1GaI98RuQU8Hr-AbfT2UUERCAdIPkT19XuBux-kjyYWZRQ39iVrVA_2dj7hxXTRCIRks5ysb5-sUtT9HkqxlruqFj-0YOlhMpKJ1EKIjINFev1FEA0ONIIc-7Yro-DrmJG8VLAeq684i7WhsKLnpyp1Id4SR66h8xhYTgjGHcKsKAvpUL8iN3AvY1HPB3VV74jCncEmiOdEzz0v8Lw%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Booya - that DataProvider is now available to any test method in that TestCase. No need to write duplicate code or private methods. MXUnit simply passes it off politely to your test method. &lt;b&gt;If you have multiple rows in the query it iterates each and fires your unit test, no more separate tests essentially doing the same thing.&amp;nbsp;&lt;/b&gt;Damn you MXUnit for making me write better, more efficient code.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;MXUnit all the way.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;-Mick&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Resources&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;a href="http://blog.mxunit.org/2009/11/data-driven-testing-with-mxunit.html"&gt;http://blog.mxunit.org/2009/11/data-driven-testing-with-mxunit.html&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;a href="http://blog.mxunit.org/2009/11/mxunit-108-released.html"&gt;http://blog.mxunit.org/2009/11/mxunit-108-released.html&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-2140443410412700604?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/2140443410412700604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=2140443410412700604' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/2140443410412700604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/2140443410412700604'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/mxunit-dataproviders-goodness.html' title='MXUnit - DataProvider Goodness'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-776780600531456417</id><published>2009-12-08T09:13:00.000-08:00</published><updated>2010-02-19T16:02:33.942-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='quicksilver'/><title type='text'>Quicksilver Framework - A Primer</title><content type='html'>&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Let's chat about some &lt;a href="http://quicksilver.riaforge.com/"&gt;Quicksilver&lt;/a&gt;! Quicksilver was created by a good friend of mine, Brian Carr, who has brought&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;us the first RESTful framework for CF called&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://powernap.riaforge.org/"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Powernap&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;. For reasons unknown to me he has given me the honor of working side by side with him on &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://quicksilver.riaforge.org/"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Quicksilver&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;- a framework that &amp;nbsp;allows programmers to quickly create&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;MVC applications with some &lt;b&gt;powerful and flexible features&lt;/b&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;When we say powerful features, we mean it. We all know that &amp;nbsp;MVC is powerful and flexible because its given.... No need to stress that. The fact that "MVC" is in the Quicksilver USP is enough. When we use the words &lt;b&gt;powerful and flexible&lt;/b&gt;&amp;nbsp;we are truly talking about the &lt;b&gt;features&lt;/b&gt; as well. QS offers so much more than just MVC. &lt;i&gt;So... much... &lt;b&gt;more&lt;/b&gt;.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;At a high level, here are the 4(+1) core&amp;nbsp;tenets&amp;nbsp;that we stuck to when developing QS:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: blue;"&gt;Provide MVC&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: blue;"&gt;Native Aspect Oriented Programming(AOP) capabilities&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: blue;"&gt;Provide Automatic Dependency Injection&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: blue;"&gt;Provide fully functioning REST support&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: blue;"&gt;Provide 1-4 easily and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;transparently&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;as possible meaning there should be no framework artifacts in your actual implementation code getting in your way resulting in an app that becomes extremely dependent on its framework. If we&amp;nbsp;achieved&amp;nbsp;this we can guarantee that your application remains HIGHLY testable which means better and more focused tests, which leads to non-fragile software, which leads to happy customers and ultimately you not having to be a nervous wreck every time a code migration is ordered.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;So how did we achieve this? &lt;span style="font-weight: normal;"&gt;By using&lt;/span&gt; Annotations.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;We took a page from Java/C++ and refer to them as annotations but other popular programming languages have the same feature but named differently e.g. C# calls them Attributes. Although there are many different flavors of annotations from language to language, at the end of the day annotations will provide metadata for your class files, its members and source code. With the release of CF9, you can append this metadata by way of using the cf comments with two asterisks like so:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/annotation.png?attachauth=ANoY7cryWDtKRvq9Y0U5_c0BzviFicwIrWKOmIIELxd4pAJEMkOp7oj8TSKPNnSwbf-r4veG9vp2HSnEsncVN-fT6qUKYpUCeitO_uUgsFtArOtFRItYQCaY_y7zMf_Vr5rFEcTy-NJnuBzrfTvUqT0PbhicacjPZwb1HQxR7m0QuQixJNDZgh82wmKTMlB0ldAEJwJmb8PeHwrk_t-aMgZJ5X3X-0oRug%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/annotation.png?attachauth=ANoY7cryWDtKRvq9Y0U5_c0BzviFicwIrWKOmIIELxd4pAJEMkOp7oj8TSKPNnSwbf-r4veG9vp2HSnEsncVN-fT6qUKYpUCeitO_uUgsFtArOtFRItYQCaY_y7zMf_Vr5rFEcTy-NJnuBzrfTvUqT0PbhicacjPZwb1HQxR7m0QuQixJNDZgh82wmKTMlB0ldAEJwJmb8PeHwrk_t-aMgZJ5X3X-0oRug%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Notice how the property is annotated via a code comment that this factory property should have a type of "path.to.some.factory". What's so cool about this? It's because an annotation is not part of implementation code - code that goes inside an actual method to be run or as a class member. Anything inside this annotation is available to the developer to introspect at runtime but actual implementation code knows nothing about it. This gives developers the ability at "compile" time to introspect source and perhaps churn out automated documentation, run debug level tests when "compilation" is running in debug mode, or in our case build a framework that gives you some really powerful features like the ones I explained above.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;My intent on this entry was not to touch on every single one of those points but lets start with one - &lt;b&gt;Automatic Dependency Injection&lt;/b&gt;. If you look at the example above we are simply telling the object that it should have a property called "factory" that has a type of "some.path.to.factory". No dependency injection going on here son, zero. That is unless you've installed Quicksilver and have either &lt;/span&gt;&lt;/span&gt;&lt;a href="http://lightwire.riaforge.org/"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Lightwire&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;or &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.coldspringframework.org/"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Coldspring&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;installed in root. QS will by default look to see if you have Lightwire installed if not it looks for Coldspring. We decided to go with Lightwire first since it manages transient objects better than Coldspring. Ok back to the code - you've installed QS and Lightwire and now when you create your object, QS will&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;automatically inject&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&amp;nbsp;those dependencies for you. &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;No XML, no bean configuration, nothing.&lt;/span&gt;&lt;/b&gt; Just the simple fact that you've annotated your property with the type is enough, QS takes care of the rest. So when you ask for an object that has property annotations attached with either the @type annotation or even inline property declaration like - &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;property name="factory" type="some.type"&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;, you will have a proper object and its correct dependencies.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;But what about for our interface based programmers that love properties that are of an interface type? Properties that doesn't have an actual concrete implementation defined as a type? Good fricking question! Here's how QS supports that with an addition annotation.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/implementation.png?attachauth=ANoY7cpsN8ElIn3RiOjmjbat3BNHYgqpC89F9hOCDx21pZ_6DKf4p4SG7gqjTvZjv3kgmqYnBZxRNyEGhbXbxRat3Hn-WcCAHswGKKX20MvpJhPcEe2mVR7mrKKqSBEkg8y_xJHbhnqyaJo7KDfFdGkUVFwSdSvNz6kJ6_SQs4PaQ-vgZTxfB9_pZlwgLYE2p5wXe-1zOcetWnV2a4nlNOZBPwskoIbLXw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/implementation.png?attachauth=ANoY7cpsN8ElIn3RiOjmjbat3BNHYgqpC89F9hOCDx21pZ_6DKf4p4SG7gqjTvZjv3kgmqYnBZxRNyEGhbXbxRat3Hn-WcCAHswGKKX20MvpJhPcEe2mVR7mrKKqSBEkg8y_xJHbhnqyaJo7KDfFdGkUVFwSdSvNz6kJ6_SQs4PaQ-vgZTxfB9_pZlwgLYE2p5wXe-1zOcetWnV2a4nlNOZBPwskoIbLXw%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;Simple type your property to the interface then use the @implementation annotation to give the actual concrete type. Your property still stays polymorphic and the world is good to you again.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;So now you see the power of QS by way of annotations. QS exposes &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;all&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; of its features through annotations. We grew tired of having framework artifacts littered throughout code. Controllers that needed to instantiate &lt;i&gt;this&lt;/i&gt; and extend &lt;i&gt;that&lt;/i&gt;. XML configs spanning hundreds and hundreds of lines. With QS you get&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="border-collapse: collapse;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;MVC without that nonsense and so much more on top of that.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;And we've tried our best to make sure that the "so much more" is NOT a pain for you to implement when time comes to use them like AOP or REST.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="border-collapse: collapse; font-size: small;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="border-collapse: collapse; font-size: small;"&gt;Brian and I are putting QS to the test. You've heard me talk about the new platform that we're writing from scratch. This project uses Quicksilver so know that its being actively developed. I spoke with Brian and we've got an updated QS release coming up soon so please friends do check it out, find some bugs and put it through the ringer. Brian and I are always open to questions and feedback so definitely reach out.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="border-collapse: collapse; font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="border-collapse: collapse; font-size: small;"&gt;&lt;span style="border-collapse: separate;"&gt;With that primer out of the way, we'll dive head first into the AOP or REST capabilities of Quicksilver. What you think?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="border-collapse: collapse; font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="border-collapse: collapse; font-size: small;"&gt;Later friends.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="border-collapse: collapse; font-size: small;"&gt;-Mick&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-776780600531456417?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/776780600531456417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=776780600531456417' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/776780600531456417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/776780600531456417'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/quicksilver-framework-primer.html' title='Quicksilver Framework - A Primer'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-4877772641425650037</id><published>2009-12-07T08:30:00.000-08:00</published><updated>2010-02-19T16:06:01.158-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='object orientation'/><title type='text'>Using Observer Pattern to Save Composite Objects</title><content type='html'>&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;I've recently been asked by a few people how I &amp;nbsp;go about saving composite objects so I figured it may be worth a blog entry. &amp;nbsp;I have a handful of applications I work on, both in CF and .NET, that share similar patterns for solving the problem of saving an object and its composites transactionally &lt;b&gt;&lt;span style="text-decoration: underline;"&gt;and&lt;/span&gt;&lt;/b&gt; in order. For example, if Object A has an Object B through composition and B cannot save until A is finished saving itself. &lt;b&gt;&lt;i&gt;Additionally if B has a problem saving itself, A should rollback as well&lt;/i&gt;&lt;/b&gt;. So how the frick does that all work?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;As with really anything in programming it can be done a million ways. Some ways are better than others but there is no golden ticket. In my experience, an acceptable solution could be by way of a service object, business object, DAO, ORM (no brainer here) or a combination of all of the above depending on how abstract you want to get. In this example I'll walk you through how I solved this problem using the tried and true Observer Design Pattern.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;The Observer Pattern was created by the Gang of Four (GoF) - Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Long story short back in 95' these very smart guys identified 23 recurring software problems, designed solutions for each called a "&lt;a href="http://en.wikipedia.org/wiki/Christopher_Alexander"&gt;design pattern&lt;/a&gt;" (which borrowed from proper architect Chris Alexander) and released a book to school us on it. If you don't own this book you definitely should, shame on you. Familiarize yourself with the problems and patterns the GoF describe and lock it away in your brain cache. When time comes, you'll be well equipped to tackle some tough design problem thrown at you. Cool? Good. Here is the definition of the observer pattern:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="font-size: small;"&gt;Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;So given the composite save problem at hand, I looked to design patterns to see if I could use one as a viable solution. I think I was on a long flight to Boston so I spent the entire flight sifting through design patterns and with the help of the book and a beer or two, I was pretty sure the observer pattern would be a good match. Thinking of the problem at a high level we have a possible one-to-many relationship between an object and its composites that needed behavior between the two such that when an object is saved, it needs to notify the composite objects who are waiting intently to save themselves but cannot before that initial object is saved successfully. For the purposes on this blog entry I've created a couple class diagrams that explain the design, then we'll jump into some code. Here's the high level/abstract:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/Observer.png?attachauth=ANoY7co1S2U9rYrmwukZNEJrioOZ2qnXRAeigsEU0qW5IxEDctdAOx2Zkyc6k6cvJmmWKEB9ZcShAWj7-mUNoyLyteGf2zjL-ABflcsCMZmSA_N2HOi2gnYICzBwVXDdaGSOUESZr46qDgW90rQzypWUrvdAZo1C0nI9S1mU3rLGlb2MPEtBepcys8PrDVxuZj-TiGElktBJLbzGrpyMLqlOSEjjnm-y-A%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/Observer.png?attachauth=ANoY7co1S2U9rYrmwukZNEJrioOZ2qnXRAeigsEU0qW5IxEDctdAOx2Zkyc6k6cvJmmWKEB9ZcShAWj7-mUNoyLyteGf2zjL-ABflcsCMZmSA_N2HOi2gnYICzBwVXDdaGSOUESZr46qDgW90rQzypWUrvdAZo1C0nI9S1mU3rLGlb2MPEtBepcys8PrDVxuZj-TiGElktBJLbzGrpyMLqlOSEjjnm-y-A%3D%3D&amp;amp;attredirects=0" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;[click to view full image]&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;You'll see that there are two interfaces involved in this implementation:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;IObservable &lt;/b&gt;- Any class that needs to be observable must implement this interface. It contains methods to attach() as a observer, detach() an observer and to notify() its observers of an event. Simply put,&amp;nbsp;if you think of a pub/sub technique, an object implementing IObservable will be the publisher.&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;IObserver &lt;/b&gt;- Any class that can attach itself as an observer to an an object that implements IObservable must implement this interface. It has the API that IObservable will call when it notifies its observers.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Now here is the UML with concrete implementations:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/Observer_concrete.png?attachauth=ANoY7cpBuO01hsZDh16vWIZ9EsF82Cr5q6jOf5KpLrVIuAILgVUPUdzn-PStdkUgLf3-zfmTaxkoI-SdXEWDbS0PoVx-Lw5UwL-HwqsnKb2JHWpNn9Jlc3ybjAfc7VGpc_DKyUVeP1XGdE3PDiEOopgaE76iRuFrwywtJ-uhCUDPbWCd4gIiHJXIE2LpYx5nKW47KU-H7UM98aeaVq0eq_HAuCX9HM5VRQ%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="131" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/Observer_concrete.png?attachauth=ANoY7cpBuO01hsZDh16vWIZ9EsF82Cr5q6jOf5KpLrVIuAILgVUPUdzn-PStdkUgLf3-zfmTaxkoI-SdXEWDbS0PoVx-Lw5UwL-HwqsnKb2JHWpNn9Jlc3ybjAfc7VGpc_DKyUVeP1XGdE3PDiEOopgaE76iRuFrwywtJ-uhCUDPbWCd4gIiHJXIE2LpYx5nKW47KU-H7UM98aeaVq0eq_HAuCX9HM5VRQ%3D%3D&amp;amp;attredirects=0" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;[click image for full view]&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Looking at this diagram you should be able to discern the following:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: small;"&gt;&lt;ul&gt;&lt;li&gt;We have a Person that has an Address - here's our composite relationship.&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;It's a one to many relationship. A Person can have multiple Addresses.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Private member - &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;observers&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt; - is of type IObservable[]. &lt;/span&gt;&lt;a href="http://mickydionisio.blogspot.com/2009/12/typed-arrays-in-coldfusionkind-of.html"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-size: small;"&gt;Whats the brackets for?&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;There is a save() method is each object. To keep things simple just imagine that save() is delegating to a DAO or using some snazzy ActiveRecord pattern to actual persist the record. Bottom line is don't worry about it for this example.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Person is observable by way of implementing IObservable. That little symbol with the interface name above each class is called a "lollipop", no joke. It means this class means &amp;nbsp;"implements" whatever name is shown.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Address is an observer by implementing IObserver.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;addEmail() has an optional second parameter "attachAsObserver" that is default = true.&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: blue;"&gt;Remember this, you'll see how this plays into a clean API when using this pattern.&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;A concrete implementation of Person might look like this:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/Person.png?attachauth=ANoY7cqeklLKGgoizjMcWheRYZvbmmalTQ-SgkNJ35RMfsVjPNFTYwx7a0ssX4sv1cYa2KUspEBAsiJMBUVu_x_VKPEkjYf_-y7yFykfUXw3kUxI3CECFWEhET9KRHr0Mc0RIuqtJlneRa6jKgcp2lEqC1STT9XFV_YKt8UIjJilrorWbJ5jkL7l09BqkICoeF2mfStc7MsoE36y8SPWlL6cZy8lpkjZPA%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="426" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/Person.png?attachauth=ANoY7cqeklLKGgoizjMcWheRYZvbmmalTQ-SgkNJ35RMfsVjPNFTYwx7a0ssX4sv1cYa2KUspEBAsiJMBUVu_x_VKPEkjYf_-y7yFykfUXw3kUxI3CECFWEhET9KRHr0Mc0RIuqtJlneRa6jKgcp2lEqC1STT9XFV_YKt8UIjJilrorWbJ5jkL7l09BqkICoeF2mfStc7MsoE36y8SPWlL6cZy8lpkjZPA%3D%3D&amp;amp;attredirects=0" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: x-small;"&gt;[click image for full view]&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;You'll notice that:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;ul&gt;&lt;li&gt;attach() will push an observer into the private subscribers array. This method is responsible for allowing observers subscribe to it (Person).&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;notify() loops over all observers and invokes update("some_event") on the observer that tells the observer, "hey dude, just fired "some_event". In the same breathe it is also inspecting the result of notify() that sniffs for a return of false which means something went wrong so return false and stop notify execution. I know that there are possible scenarios where you would not want to stop processing and move along but exploring that is out of the scope of this example. &lt;/span&gt;&lt;i&gt;&lt;span style="font-size: small;"&gt;Although if you go ahead and re-factor this example to do this I'd love to see it!&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;We've overridden addAddress() which manages our address collection. This is essentially the setter for Address but called it add instead of set because of the one-to-many relationship. Notice that the we've added a second parameter to this method called &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;attachAsSubscriber&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt; that has a default = true so its optional. In the logic, we're saying if attasAsObserver is true then automatically attach the Address as an observer to Person.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;save() calls super.save(). Make believe Person extends some base persistence object.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;K - on to some Address code:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/Address.png?attachauth=ANoY7cpGpJiKXPwY7eAbyvTh-F_1IyUVEmSgym6zJdCDYFJ5AzKyk4IaZcWPnKgoxtyp0DjgW9cJpurFzyZYT-FO7uh3DHVKbOzzSDpjHx_4_k4-YodVUYyzz_prkt5Av7iNjcPRw6019NkZSs6x-MKqeZSJTKCNTA7lfqsIz6BNZyHfIAl-hJCr_VZJjDwXTxEzZkEXEM922AGmkv5HT3kM-BKQAVdGOg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="331" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/Address.png?attachauth=ANoY7cpGpJiKXPwY7eAbyvTh-F_1IyUVEmSgym6zJdCDYFJ5AzKyk4IaZcWPnKgoxtyp0DjgW9cJpurFzyZYT-FO7uh3DHVKbOzzSDpjHx_4_k4-YodVUYyzz_prkt5Av7iNjcPRw6019NkZSs6x-MKqeZSJTKCNTA7lfqsIz6BNZyHfIAl-hJCr_VZJjDwXTxEzZkEXEM922AGmkv5HT3kM-BKQAVdGOg%3D%3D&amp;amp;attredirects=0" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: x-small;"&gt;[click image for full view]&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Here you'll notice that:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;update() will receive the event message and process accordingly. &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;Please&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;do &lt;/span&gt;&lt;span style="text-decoration: underline;"&gt;&lt;span style="font-size: small;"&gt;not&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt; confuse this with a CRUD operation.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt; As a best practice in you database layer there really shouldn't even be a method called update(), rather call it save(). Anyway, what update() will do is inspect the event that was just fired by IObservable and if it is a "save" event, then return save(). This is a very important piece right here! The return of save() gets bubbled up to the observer. This will ultimately determine the rollback which we'll get to in a second. You can optionally override Address.save() also do the same algorithm as Person.save() if Address also needed to be observable and notify its own observers.But thats up to your requirements. Just want to drive the point home that pattern can be implemented n-levels deep. D observes C who observes B who observes A. A = &lt;/span&gt;&lt;a href="http://www.urbandictionary.com/define.php?term=mack+daddy"&gt;&lt;span style="font-size: small;"&gt;mack daddy&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;update() by default will return true.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;update() uses the eventInfo structs observable key to get the Person that was just persisted. This allows Address to save() correctly. I chose to go with a struct for eventInfo because an event might be fired in the future that needed to pass a handful of additional info to its observers. This allows for future flexibility.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;And finally here is how you might possibly consume this API in its entirety. For the purposes of this example its in a cfm page but you'd probably want it somewhere in a persistence layer - perhaps a controller/service type object.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/ConsumeAPI.png?attachauth=ANoY7cqws-qQ-ooujYCl57wwdPI9aG9Yy1ZwezxnbJDbMS7ARVgSx01Mwi_y0XWGLH4JfZWuv0PeDr5FKgY7SCwHEJjHSt_9HBRnM2HO6bU64Tcf6AaWxRDl4o07NTrs68F7k_evowJA4rE_FMkYdhzF3Hojtok24Z8UAd7ZLsOl_3E690BNvE-IquqL2AD8hmwhyTI9loZbCRZvArP1dJfBXXQUxelkQw%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/ConsumeAPI.png?attachauth=ANoY7cqws-qQ-ooujYCl57wwdPI9aG9Yy1ZwezxnbJDbMS7ARVgSx01Mwi_y0XWGLH4JfZWuv0PeDr5FKgY7SCwHEJjHSt_9HBRnM2HO6bU64Tcf6AaWxRDl4o07NTrs68F7k_evowJA4rE_FMkYdhzF3Hojtok24Z8UAd7ZLsOl_3E690BNvE-IquqL2AD8hmwhyTI9loZbCRZvArP1dJfBXXQUxelkQw%3D%3D&amp;amp;attredirects=0" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: x-small;"&gt;[click image for full view]&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Here we have:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Created a new Person and Address.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Associated the Address to the Person. Under the hood this will also attach Address as an observer to Person but the API remains simple. Looks just like a simple setter - addAddress(in Address). It has no idea the observer pattern is going on in the background.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;We are simply making the entire save process transactional and when an observer fails to save or an exception is thrown, we handle it accordingly by rolling everything back.&amp;nbsp;You could have 100 objects in the queue to be save()'d, fail on save() #99 and it'll nicely rollback everything for you.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;And now since we've kept the Observer pattern extremely generic, you can feel free to leverage this implementation for &lt;/span&gt;&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;&lt;span style="font-size: small;"&gt;any other event&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt;, not just saving.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;There you have it. Observer pattern goodness that could hopefully make the GoF a little proud. I've implemented this technique both in .NET and CF and it works great for me. For my C# peeps, Microsoft is releasing an set of Observer Pattern interfaces that will support this type of usage out of the box. Check it out &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd990377(VS.100).aspx"&gt;&lt;span style="font-size: small;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;So in closing, this is just one technique of &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;many &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt;so I encourage you to explore some other ways and please point me to ways you've done it in the past. &lt;/span&gt;&lt;i&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;I'm interested in seeing it!&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Apologies in advance for any bugs in this code. Everything was typed on the fly but hopefully you get the idea.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Till next time my friends.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;-Mick&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;Resources:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;a href="http://www.dofactory.com/Patterns/PatternObserver.aspx"&gt;Design Patterns with C#&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;a href="http://www.dofactory.com/Patterns/PatternObserver.aspx"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Christopher_Alexander"&gt;&lt;span style="font-size: small;"&gt;Christopher Alexander&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;, founder of the design pattern in architecture.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Design_Patterns_(book)"&gt;&lt;span style="font-size: small;"&gt;GoF&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;you owe it to them so buy their book&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-4877772641425650037?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/4877772641425650037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=4877772641425650037' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/4877772641425650037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/4877772641425650037'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/using-observer-pattern-to-save.html' title='Using Observer Pattern to Save Composite Objects'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-696205184649663173</id><published>2009-12-04T22:10:00.000-08:00</published><updated>2010-02-19T16:02:57.354-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coldfusion'/><title type='text'>Typed Arrays in ColdFusion...kind of.</title><content type='html'>&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;You read it right but I'll warn you now it'll make you feel a little icky.If you are storing a composite relationship via a private array you've probably been using the type of "array" all these years. You can pseudo type your array in CF9 and I even think you could do this all the way back in &amp;nbsp;6.1 but back then an empty array would throw an error. Anyway,if you choose to do so you can pseudo-type your arrays in this fashion:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/typing_array_kindof.png?attachauth=ANoY7coaA-48RRN6aLNbui8F4Wl8SQJ2gwf5rKB8l-meavZTv1RyEPzeRucIHbcubYg9HOQoMecTZHqDHFSrPeiZXBDZKA-qCXkq8c3qHJz2Qmf0avkQ8ctNGd0d7fKYlcq4d_4YvzM1eqPdjyaWUSymZAlpsrwe5NKyszFqX7rsrFQ5l6gSWmANjAqSiJofWGAy-6YIE3rFot6IViv9f-tyCr_QeY_Hjg%3D%3D&amp;amp;attredirects=0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;img border="0" src="http://623576730636596139-a-1802744773732722657-s-sites.googlegroups.com/site/mickydionisio/fs-1/typing_array_kindof.png?attachauth=ANoY7coaA-48RRN6aLNbui8F4Wl8SQJ2gwf5rKB8l-meavZTv1RyEPzeRucIHbcubYg9HOQoMecTZHqDHFSrPeiZXBDZKA-qCXkq8c3qHJz2Qmf0avkQ8ctNGd0d7fKYlcq4d_4YvzM1eqPdjyaWUSymZAlpsrwe5NKyszFqX7rsrFQ5l6gSWmANjAqSiJofWGAy-6YIE3rFot6IViv9f-tyCr_QeY_Hjg%3D%3D&amp;amp;attredirects=0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Back in 6.1 if that array was empty, it would throw an exception but that doesn't seem to happen anymore. &amp;nbsp;Simple use the type and add the array notation (open-close brackets) and viola it works. I kinda have a type safe array... kind of. &lt;b&gt;&lt;i&gt;&lt;span style="color: red;"&gt;It only checks the type of the FIRST element in the array.&lt;/span&gt;&lt;/i&gt;&lt;/b&gt; So I could have an Address object in the first position and an int in the next and it will NOT fail.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Half kudos, half fail.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif;"&gt;&lt;span style="font-size: small;"&gt;PEACE.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-696205184649663173?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/696205184649663173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=696205184649663173' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/696205184649663173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/696205184649663173'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/typed-arrays-in-coldfusionkind-of.html' title='Typed Arrays in ColdFusion...kind of.'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8131994348885474777.post-7112093802660444582</id><published>2009-12-04T11:11:00.000-08:00</published><updated>2010-02-25T14:16:56.785-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><title type='text'>Mocking - An essential unit testing technique</title><content type='html'>&lt;span style="font-family: 'trebuchet ms'; font-size: 85%;"&gt;Oh the joys of unit testing. Brian C. and I are creating a new platform from the ground up. From the get go unit tests were a standard. You need to write em, if you don't its timeout in the corner for 10 minutes. We started this project about a year ago on CF8 but recently got approval to move over to CF9. Very cool. So we started our script conversion A fricking SAP since the sooner we could rid the codebase of&amp;nbsp;cftags the sooner my wrists and fingers can like me again.&lt;br /&gt;&lt;br /&gt;Within that year we wrote unit tests for every single method in our codebase and tried our best to have near 100% code coverage. Life was good, we felt protected. That is, until we started hearing about Mocking during our script conversion. Essentially we were refactoring code to script which made us take a deeper look at the quality of our unit tests - and ehhh it was mediocre. A majority of tests felt clunky, doing too much, finding assertions that were'nt needed in the unit test in question but rather that belonged somewhere else. We both heard about mocking and decided to dedicate a few days trying to understand it and see if it solved our unit test shady-ness. I first heard the term "mocking" by a good friend of mine, Shakti S. who is spearheading the JUnit unit testing effort over at his shop. I'd say within the first few minutes of the explanation my eyes glazed over and my brain was sizzling. During that discussion, one point (out of many of course) that resonated with me was when he said this, "You can see the true power of mocking when writing tests against objects that leverage DAO's". So I slept on it... Shot a few emails back to Shaks and eventually brought it up with Brian as well. Brian and I spent a good day researching mocking (EXCELLENT resource by Martin Fowler- &lt;/span&gt;&lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;&lt;span style="font-family: 'trebuchet ms'; font-size: 85%;"&gt;http://martinfowler.com/articles/mocksArentStubs.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 'trebuchet ms'; font-size: 85%;"&gt;) and exchanging conversations that resulted in many "I think I get it. Lets run some tests". About the 10th "I think I get it" later we came to an epiphany. Unit tests need to be as simplistic as possible right? At the end of the day software functions are no different that mathematical functions - you define the inputs therefore you can assert the output.&lt;br /&gt;&lt;br /&gt;OK so where does mocking come in? Well the object/method under test (coined &lt;strong&gt;System Under Test, SUT&lt;/strong&gt;) can be delegating to composite objects to get its ultimate result. These composite objects often have their own composition so you can imagine what that setup() of that test case would look like.You'd need to instantiate the SUT, its composite relationships and THEIR composite relationships just to get the SUT in a state where its testable - ugh no thanks. Herein lies the problem that Mocking solves. These composite method calls within a SUT are termed&amp;nbsp;&lt;strong&gt;collaborators&lt;/strong&gt;. You, &lt;strong&gt;as the developer who have access to the source code&lt;/strong&gt;, can mock/fake the results of a collaborator WITHIN that SUT. This is desirable because you &lt;strong&gt;&lt;em&gt;&lt;u&gt;should&lt;/u&gt;&lt;/em&gt;&lt;/strong&gt; know what a valid expectation can be for that collaboration method. Instead of manually injecting/constructing the proper dependencies every single time just simply mock it up. You should NOT be&amp;nbsp;manually injecting/constructing the proper dependencies&amp;nbsp;because it takes your focus off of the SUT and you end up with a handful of extra code that you don't need, compositions that don't need to happen and assertions that&amp;nbsp;belong somewhere else or worse,&amp;nbsp;doesn't even add value to the unit test.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'trebuchet ms'; font-size: 85%;"&gt; &lt;br /&gt;Back to how this mocking concept clicked as it pertains to the the DAO problem. In our new platform we leveraged an IoC container so we didn't have to manually construct dependencies every test case setup(). However we did have to inject the bean factory into each test case - so same problem, different dress. So how'd this epiphany apply to DAO's? Well when a test for a method that uses a delegate call to a dao method like dao.save(), that actually persisted a test record into the database. This should have just made you cringe... alot. You heard it right. Through each run of the build (firing unit tests) we were persisting test data to the dev database everywhere something.save() was called. This happens through local developer builds as well as continuous integration. We needed a way to make dao.save() return true but don't really go in there and persist records to the database. This is what integration tests are for, not unit tests. So after reaching mocking nirvana the solution was simple - mock the SUT's collaborator for dao, specifically the dao.save() method, to return true. Whatever dao.save() used to do is now overriden. If that save() went on and collaborated with 100 more objects, it no longer has any relevance here. We've mocked it. We've told you, dao.save(), what to return. We don't care how you really use 100 other objects to return true. You, dao.save(), are not the SUT. So I'll make you return true and you'll like it since I'm your daddy and my actual SUT execution path expects you to return true in order for me to assert properly.&lt;br /&gt;&lt;br /&gt;So to conclude just remember that whenever you run across a SUT that has collaborators (composition), chances are you'll want to mock it. This keeps your unit tests controlled, light and focused. Keep up with your unit tests as it's tremendously helped us with this tag to script conversion. We'd convert to script, run the unit test where it would sometimes blow up in our face because we wrote some logic incorrectly. Gotta love it.&lt;br /&gt;&lt;br /&gt;Hope this helped. I wanted to focus on the abstract and not show code however if you would like to see examples just let me know.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'trebuchet ms'; font-size: 85%;"&gt;Good resources:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mockobjects.com/"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: x-small;"&gt;http://www.mockobjects.com/&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: x-small;"&gt;Martin Fowler- &lt;/span&gt;&lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: x-small;"&gt;http://martinfowler.com/articles/mocksArentStubs.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: x-small;"&gt;Ask @marcesher on twitter - &lt;/span&gt;&lt;a href="http://twitter.com/marcesher"&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: x-small;"&gt;http://twitter.com/marcesher&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 'Trebuchet MS', sans-serif; font-size: x-small;"&gt; (MXUnit contributor)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8131994348885474777-7112093802660444582?l=mickydionisio.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mickydionisio.blogspot.com/feeds/7112093802660444582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8131994348885474777&amp;postID=7112093802660444582' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/7112093802660444582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8131994348885474777/posts/default/7112093802660444582'/><link rel='alternate' type='text/html' href='http://mickydionisio.blogspot.com/2009/12/unit-test-mocking.html' title='Mocking - An essential unit testing technique'/><author><name>Micky Dionisio</name><uri>http://www.blogger.com/profile/12849444647466518787</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Mko9LU1QibA/SuhzMgYK2gI/AAAAAAAAAls/gmo1iTC0xDQ/s1600-R/6aeeeed29682fc3c0b25ca0d8c43696e_bigger.jpeg'/></author><thr:total>2</thr:total></entry></feed>
