<?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-1603489865641920209</id><updated>2012-02-16T01:35:03.693-08:00</updated><category term='factory pattern OO software engineering'/><category term='machii OO design'/><category term='front end development'/><category term='machii listeners model core business'/><category term='patterns design'/><category term='Machii'/><category term='javascript'/><category term='refactoring'/><category term='objects'/><category term='oXmlHttp javascript'/><category term='AJAX'/><category term='software design'/><category term='application.cfc framework'/><category term='services model managers object reference'/><category term='debugging mvc object instantiation'/><category term='Gateway'/><category term='coldSpring'/><category term='objects reference value framework'/><category term='beans'/><category term='JSON and PHP'/><category term='people'/><category term='custom'/><category term='model refactoring domain logic coldspring'/><category term='good developer habits'/><category term='frameworks'/><category term='GetHttpObject'/><category term='Design Patterns in ColdFusion'/><category term='coldSpring pathing cfcs coldfusion'/><category term='anemic value beans design pattern'/><category term='Model Glue'/><category term='fckeditor - dynamic pathing uploading'/><category term='by reference'/><category term='OOP coldfusion'/><category term='software design patterns best practices abstraction'/><category term='objects composition inheritence'/><category term='CF'/><category term='counters'/><category term='DAO'/><category term='Prototyping'/><title type='text'>software design and other stuff</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>58</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-8065891357817528941</id><published>2011-12-14T11:55:00.000-08:00</published><updated>2011-12-14T12:49:37.585-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSON and PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><title type='text'>Class File PHP</title><content type='html'>I sent a few hours and came up with a Class file that would represent my counter:&lt;br /&gt;&lt;br /&gt;&lt;!--?php      include_once 'connect_db.php';         class Counter     {         // instance variables         public $counterName;         public $counterValue;         public static $id; //once set this wont change - dont want it to, like final in java                 //constructor         public function Counter($id){             $this---&gt;id = $id;&lt;br /&gt;     &lt;br /&gt;         //get recs from db&lt;br /&gt;         $rec = $this-&amp;gt;getRec();&lt;br /&gt;         $totalCount = $this-&amp;gt;getCounterTotal();&lt;br /&gt;     &lt;br /&gt;         //update instance vars&lt;br /&gt;         $this-&amp;gt;counterName = $rec-&amp;gt;name;&lt;br /&gt;         $this-&amp;gt;counterValue = $totalCount;&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     private function getRec(){&lt;br /&gt;     &lt;br /&gt;             $rec = mysql_query("&lt;br /&gt;             SELECT id, name&lt;br /&gt;             FROM tablename&lt;br /&gt;             WHERE id = $this-&amp;gt;id&lt;br /&gt;         ");&lt;br /&gt;     &lt;br /&gt;         return mysql_fetch_object($rec);&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     private function getCounterTotal(){&lt;br /&gt;         //select and count recs equal to id&lt;br /&gt;         $rec =  mysql_query("&lt;br /&gt;         SELECT COUNT(id) AS count, date&lt;br /&gt;         FROM tablename&lt;br /&gt;         WHERE counterid = $this-&amp;gt;id AND active&lt;br /&gt;         ");&lt;br /&gt;     &lt;br /&gt;         $row = mysql_fetch_object($rec);&lt;br /&gt;         return $row-&amp;gt;count;&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     // accessors&lt;br /&gt;     public function getCounterName() {&lt;br /&gt;         return $this-&amp;gt;counterName;&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     public function getCounterValue() {&lt;br /&gt;         return $this-&amp;gt;counterValue;&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     //mutators&lt;br /&gt;     public function incrementCounter() {&lt;br /&gt;     &lt;br /&gt;         //update db&lt;br /&gt;         mysql_query("&lt;br /&gt;             INSERT INTO tablename&lt;br /&gt;                 (counterid)&lt;br /&gt;             VALUES&lt;br /&gt;                 ($this-&amp;gt;id)    &lt;br /&gt;         ");&lt;br /&gt;     &lt;br /&gt;         //var_dump($this-&amp;gt;id);&lt;br /&gt;         //break;&lt;br /&gt;      &lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;     public function resetCounter(){&lt;br /&gt;         //get recs for the counterid&lt;br /&gt;         mysql_query("&lt;br /&gt;             UPDATE tablename&lt;br /&gt;             SET active = 0&lt;br /&gt;             WHERE counterid = $this-&amp;gt;id    &lt;br /&gt;         ");&lt;br /&gt;     &lt;br /&gt;         //var_dump($this-&amp;gt;id);&lt;br /&gt;         //break;&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     public function getAllRecs(){&lt;br /&gt;         $recs =  mysql_query("&lt;br /&gt;             SELECT c.name AS name, a.date AS date, a.schoolid AS schoolID, a.active AS active&lt;br /&gt;&lt;br /&gt;             FROM tablename a&lt;br /&gt;             join tablename c on c.id = a.counterid&lt;br /&gt;         &lt;br /&gt;             ORDER BY date DESC&lt;br /&gt;         ");&lt;br /&gt;     &lt;br /&gt;         return $recs;&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;br /&gt;While building my class file, I used a test.php file along with it to test it.  A common practice when building bus. classes.  Once the class was complete, I completed the DB table.&lt;br /&gt;&lt;br /&gt;I ended up creating two tables:&lt;br /&gt;&lt;br /&gt;tablename&lt;br /&gt;tablename_associations&lt;br /&gt;&lt;br /&gt;The tablename includes an id and a name for the counter.&lt;br /&gt;&lt;br /&gt;Most of the data storage is in the associations table, where i am storing the id, the date of the request and a boolean col representing if the col is active in the current count, since it can be reset.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-jVK9IthaeWg/TukBxAcLlWI/AAAAAAAAADY/wy6Wf-OsI_0/s1600/counterAdmin.gif"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 141px;" src="http://3.bp.blogspot.com/-jVK9IthaeWg/TukBxAcLlWI/AAAAAAAAADY/wy6Wf-OsI_0/s320/counterAdmin.gif" alt="" id="BLOGGER_PHOTO_ID_5686077945975379298" border="0" /&gt;&lt;/a&gt;Next, I build an administration page that would allow whoever we gave access to it to reset each of the counters.  Also on the admin. page is a report of each of the requested counts: see below&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now came the trickiest part of all.  The problem I ran into next, was my new learning of the week.  When using AJAX, which is essentially the &lt;a href="http://www.the-art-of-web.com/javascript/ajax/"&gt;XMLHTTPRequest object &lt;/a&gt;, that you CAN NOT remotely call a page on another server.  This is know as the&lt;a href="https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript"&gt; same server policy&lt;/a&gt;.  This was a big problem since the server that was serving up the counter requests was NOT THE SAME as the server that was hosting the class(s) and db that were storing the counter.  I had no way to reconcile this since I did not own the client server, only the serving server.&lt;br /&gt;&lt;br /&gt;Hmmmm, what to do next??&lt;br /&gt;&lt;br /&gt;This post got me started to what my option would be, which was basically two&lt;br /&gt;&lt;br /&gt;1 - create or use a proxy server to fool the client and server into thinking they were the same domain&lt;br /&gt;2 - use a different javascript notation called JSON, that would allow you to inject a script.&lt;br /&gt;&lt;br /&gt;Neither of these options seems too trivial, after about a day of reading up on the two, i choose option 2., JSON.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here is the JSON enabled call from the client side:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;function getCounterJSON(param){&lt;br /&gt;  $.getJSON('http://domainName/path/view.php?callback=?','counter=' + param ,function(res){&lt;br /&gt;      document.getElementById(param).innerHTML = '&amp;amp;nbsp&amp;amp;nbsp&amp;amp;nbsp' + res.counterValue + ' views';&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here is the view.php page and its callback function.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  //VERY sneaky JSON javascript object notation callback function - working around the security *blocks when ajaxing from one domain to another - which is illegal.&lt;br /&gt;  {&lt;br /&gt;      echo $_GET['callback'] . '(' . "{'counterValue' : $counterValue}" . ')';&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here is the rest of the view.php page preceding the callback function.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  //CounterBase creates the objects $marks, $attendance, $progress&lt;br /&gt;  include_once 'CounterBase.php';&lt;br /&gt;&lt;br /&gt;  //check to see if someone is requesting to update a specific counter&lt;br /&gt;  $counter = $_GET['counter'];&lt;br /&gt;  $counterValue =  0;&lt;br /&gt;&lt;br /&gt;  //var_dump($_GET['counter']);&lt;br /&gt;  //break;&lt;br /&gt;&lt;br /&gt;  if ($counter == 'marks') {&lt;br /&gt;      $counterValue =  $marks-&amp;gt;getCounterValue();&lt;br /&gt;  }elseif($counter == 'attendance'){&lt;br /&gt;      $counterValue =   $attendance-&amp;gt;getCounterValue();&lt;br /&gt;  }elseif($counter == 'progress'){&lt;br /&gt;      $counterValue =  $progress-&amp;gt;getCounterValue();&lt;br /&gt;  }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-8065891357817528941?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/8065891357817528941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=8065891357817528941' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8065891357817528941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8065891357817528941'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2011/12/class-file-php.html' title='Class File PHP'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-jVK9IthaeWg/TukBxAcLlWI/AAAAAAAAADY/wy6Wf-OsI_0/s72-c/counterAdmin.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7945069196372641889</id><published>2011-12-14T10:55:00.000-08:00</published><updated>2011-12-14T11:55:28.600-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON and PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='counters'/><title type='text'>counters, javascript, JSON and PHP</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-933Fxxm9eRo/Tuj79kv3HeI/AAAAAAAAADA/6BPOZv2sAxo/s1600/smpass.gif"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-mh0fJ-syPxw/Tuj7v9x08_I/AAAAAAAAAC0/Aw8QB1j6fD8/s1600/smpass.gif"&gt;&lt;/a&gt;&lt;br /&gt;I have a customer that forwarded me an email that said "can we create &lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);" class="" style="display: block;" id="formatbar_CreateLink" title="Link"&gt;&lt;img src="http://www.blogger.com/img/blank.gif" alt="Link" class="gl_link" border="0" /&gt;&lt;/span&gt;&lt;/span&gt;counters on our web page?" My first thought was, its not the 90's, people don't use counters anymore. So I did a little research, about 5 minutes, and found a couple web sites that create counters for you.  Like &lt;a href="http://www.e-zeeinternet.com/"&gt;this one&lt;/a&gt; and &lt;a href="http://www.web-design-factory.net/free-web-counter.html"&gt;this one&lt;/a&gt;.  I send a email back with links to these sites and said something like, its pretty easy.&lt;br /&gt;&lt;br /&gt;Then I got an email from my boss who said, "James, I think they want you to do it for them".  So, I spent about 1/2 hr and documented the steps necessary to create a counter using one of the two sites, mailed the steps to my customer and waited.  Here is a copy of my email with the steps:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Ellie, follow these steps for &lt;strong&gt;each page&lt;/strong&gt; you want to insert the counter code on.&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;go to e-zeeinternet.com site&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;1 - enter the page URL, like &lt;a target="_blank" href="https://smclassroom.naples.k12.ny.us/smclassroom/pass/smframe.htm"&gt;https://siteURL&lt;/a&gt; , into the Page Counter that it will be placed on:&lt;/div&gt; &lt;div&gt;2 - choose Numbers of digits to show&lt;/div&gt; &lt;div&gt;3 - Choose pageviews&lt;/div&gt; &lt;div&gt;4 - Choose No, twice&lt;/div&gt; &lt;div&gt;5 - Select the counter style you prefer&lt;/div&gt; &lt;div&gt;6 - scroll to bottom of page, click Get Counter Code&lt;/div&gt; &lt;div&gt;7 - copy the contents from the box&lt;/div&gt; &lt;div&gt;8 - using an html editor, open the page specified in step 1&lt;/div&gt; &lt;div&gt;9 - paste the code into the location where you want counter to appear&lt;/div&gt; &lt;div&gt;10 - save the page&lt;/div&gt; &lt;div&gt;11 - reload the page and you should see the counter&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;you can edit the code a bit, to remove the text, for example.&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;I tested out on an html page on this end and works fine.&lt;/div&gt; &lt;div&gt; &lt;/div&gt; &lt;div&gt;james&lt;br /&gt;&lt;br /&gt;Next, I got an email from a guy down the hall who supports this customer I had just emailed.  She emailed her contact, the guy down the hall, when she received this message from me.&lt;br /&gt;&lt;br /&gt;Toby, the guy down the hall, said "james, i tried doing something like this before, but i don't know where to put the code.  the plot thickens"...&lt;br /&gt;&lt;br /&gt;Once I spoke with Toby further, I found out that the customer wants to track the # of times 3 specific links are clicked in their existing system.  After clarifying a couple other issues, Toby gave me access to his test server and away I went back to my corner of the world to see about creating counters for the 3 links.&lt;br /&gt;&lt;br /&gt;I googled a bit for "creating web counters" and found almost all javascript solutions, many of which used cookies to store information for a user.  Cookies was a good solution, at least initially. You can see the alert() in the functions as debugging options.  This was enjoyable, tinkering around in javascript until I got the code working.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Javascript Cookies&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The basic premise of the cookie is a way for the browser to remember or persist information about the user when they come to a web page.  Great, perfect, if the requirement was for user to keep their own counters.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Three requirements I was solving:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1&lt;/span&gt; - adding a call to the incrementCookieCount function when the user clicked on a specific link.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2&lt;/span&gt; - call the getCookieCount function for the 3 links requested, outputting the value of the cookie next to the link.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3&lt;/span&gt; - creating a link that would allow the user to reset the cookie count, when they wanted.  This would basically delete the cookie and recreate it, setting its count back to 1.&lt;br /&gt;&lt;br /&gt;This was great, all this counting and incrementing and displaying and resetting was just fun, and I was able to do it all right in the client side browser.  I was very proud once I got everything working. I showed my customer, he was excited bla bla...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here is how I was calling the increment function:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;if(data_type == 2){&lt;br /&gt;//alert('attendance ' + data_type);&lt;br /&gt;incrementCookieCount('attendance');&lt;br /&gt;}else if(data_type == 3){&lt;br /&gt;       incrementCookieCount('marks');&lt;br /&gt;}else if(data_type == 8){&lt;br /&gt;    incrementCookieCount('progress');&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here is how I was displaying the count:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;getCookieCount('progress');&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here are the functions:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;function incrementCookieCount(cookieName){&lt;br /&gt;//alert('');&lt;br /&gt;var count = GetCookie(cookieName)&lt;br /&gt;if(count == null) {&lt;br /&gt;   SetCookie(cookieName,'1')&lt;br /&gt;   return 1&lt;br /&gt;}else{&lt;br /&gt;   var newcount = parseInt(count) + 1;&lt;br /&gt;   DeleteCookie(cookieName)&lt;br /&gt;   SetCookie(cookieName,newcount,exp)&lt;br /&gt;   return count&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getCookieCount(cookieName){&lt;br /&gt;//alert('');&lt;br /&gt;var count = GetCookie(cookieName)&lt;br /&gt;if(count == null) {&lt;br /&gt;   SetCookie(cookieName,'1')&lt;br /&gt;   return 1&lt;br /&gt;}else{&lt;br /&gt;   var newcount = parseInt(count);&lt;br /&gt;   DeleteCookie(cookieName)&lt;br /&gt;   SetCookie(cookieName,newcount,exp)&lt;br /&gt;   return count&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//these are like private functions, not called directly by the client.&lt;br /&gt;&lt;br /&gt;function GetCookie (name) {&lt;br /&gt;var arg = name + "=";&lt;br /&gt;var alen = arg.length;&lt;br /&gt;var clen = document.cookie.length;&lt;br /&gt;var i = 0;&lt;br /&gt;&lt;br /&gt;while (i &amp;lt; clen) {&lt;br /&gt;   var j = i + alen;&lt;br /&gt;   if (document.cookie.substring(i, j) == arg)&lt;br /&gt;   return getCookieVal (j);&lt;br /&gt;   i = document.cookie.indexOf(" ", i) + 1;&lt;br /&gt;   if (i == 0) break;&lt;br /&gt;}&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function SetCookie (name, value) {&lt;br /&gt;var argv = SetCookie.arguments;&lt;br /&gt;var argc = SetCookie.arguments.length;&lt;br /&gt;var expires = (argc &amp;gt; 2) ? argv[2] : null;&lt;br /&gt;var path = (argc &amp;gt; 3) ? argv[3] : null;&lt;br /&gt;var domain = (argc &amp;gt; 4) ? argv[4] : null;&lt;br /&gt;var secure = (argc &amp;gt; 5) ? argv[5] : false;&lt;br /&gt;document.cookie = name + "=" + escape (value) +&lt;br /&gt;((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +&lt;br /&gt;((path == null) ? "" : ("; path=" + path)) +&lt;br /&gt;((domain == null) ? "" : ("; domain=" + domain)) +&lt;br /&gt;((secure == true) ? "; secure" : "");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var expDays = 30;&lt;br /&gt;var exp = new Date();&lt;br /&gt;exp.setTime(exp.getTime() + (expDays*24*60*60*1000));&lt;br /&gt;&lt;br /&gt;function DeleteCookie (name) {&lt;br /&gt;var exp = new Date();&lt;br /&gt;exp.setTime (exp.getTime() - 1);&lt;br /&gt;var cval = GetCookie (name);&lt;br /&gt;document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function resetCookie(param) {&lt;br /&gt;//alert('resetting cookie... ');&lt;br /&gt;//var name = "marks";&lt;br /&gt;var exp = new Date();&lt;br /&gt;exp.setTime (exp.getTime() - 1);&lt;br /&gt;var cval = GetCookie (param);&lt;br /&gt;document.cookie = param + "=" + cval + "; expires=" + exp.toGMTString();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function getCookieVal(offset) {&lt;br /&gt;var endstr = document.cookie.indexOf (";", offset);&lt;br /&gt;if (endstr == -1)&lt;br /&gt;endstr = document.cookie.length;&lt;br /&gt;return unescape(document.cookie.substring(offset, endstr));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is what the web page looked like with my code in place:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-34QEuXptUsg/Tuj8SZVGNcI/AAAAAAAAADM/MAvR-A-ADCs/s1600/smpass.gif"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 162px; height: 244px;" src="http://2.bp.blogspot.com/-34QEuXptUsg/Tuj8SZVGNcI/AAAAAAAAADM/MAvR-A-ADCs/s320/smpass.gif" alt="" id="BLOGGER_PHOTO_ID_5686071922522469826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is what the output looked like from the web page.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;When I checked the layout in another browser, it hit me, that the solution I had created was not the one being asked for.  This solution would give every user in each unique browser their own counters.  What I needed was a solution that would persist outside of any browser and user.&lt;br /&gt;&lt;br /&gt;I would need a server side solution, and a database that would store the counter information, persist and read/reset. Hmmmmm&lt;br /&gt;&lt;br /&gt;I turned toward PHP, since I had a PHP server available and a mySQL database that could store the data. &lt;br /&gt;&lt;br /&gt;Step one:  Create a class that would represent the counter, using PHP.&lt;br /&gt;&lt;br /&gt;Step two: Build a persistence mechanism for the counter data.&lt;br /&gt;&lt;br /&gt;Step three: Modify the javascript to read PHP class file(s).&lt;br /&gt;&lt;br /&gt;Step four: Use an AJAX technique to call the counter update and increment functions, while outputting their results in the html page.  This would be tricky, but I had done similar things using AJAX and Jquery in the past.&lt;br /&gt;&lt;br /&gt;Continued in next post.....&lt;br /&gt;&lt;br /&gt;&lt;br /&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/1603489865641920209-7945069196372641889?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7945069196372641889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7945069196372641889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7945069196372641889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7945069196372641889'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2011/12/counters-javascript-json-and-php.html' title='counters, javascript, JSON and PHP'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-34QEuXptUsg/Tuj8SZVGNcI/AAAAAAAAADM/MAvR-A-ADCs/s72-c/smpass.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-183295622476203730</id><published>2009-10-08T12:02:00.000-07:00</published><updated>2009-10-08T12:11:03.592-07:00</updated><title type='text'>OOP, Beans, Gateways, Services</title><content type='html'>Today - i went into a very old part of an application and revised some very old bus. logic.  I am giving a facelift to part of a web site and while looking at a view page decided i would change a little logic.  There was a call to the database in one of the view pages, since the beans being served up via the application to the view did not have all the data needed.  This is a little lazy, to put a call to the db in a view, but understandable, especially if you do not have alot of background in MVC, Gateway, DAO, Front end controller design patterns, not to mention OOP.&lt;br /&gt;&lt;br /&gt;After of a bit of consternation about what to do and finding another place in a related view file where i needed a bit more data, i decided to do it right.  That meant going into the domain and finding the bean and dao responsible for getting and setting the data for the bean.&lt;br /&gt;&lt;br /&gt;First, i needed to be sure i could add the little "bits" of data needed before adding them to the bean and dao.  The data i wanted to add was from another database on the same server.  No server linking needed!  I spent a few minutes looking up how to do this and added the code to the read function of the dao that joined the existing table to a new one in onther db.  &lt;br /&gt;&lt;br /&gt;Next i added the getter and setter methods to  the bean, reloaded the controller - since they cache my beans (since im using Coldspring and machii) - a couple MVC / oop frameworks.&lt;br /&gt;&lt;br /&gt;Finally, i added the call to the new bit of data now being server up by the bean and whalla - im in busniess - logic all where it should be.&lt;br /&gt;&lt;br /&gt;amen&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-183295622476203730?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/183295622476203730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=183295622476203730' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/183295622476203730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/183295622476203730'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/10/oop-beans-gateways-services.html' title='OOP, Beans, Gateways, Services'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-5076365493456922444</id><published>2009-09-02T10:58:00.000-07:00</published><updated>2009-09-02T11:12:30.548-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OOP coldfusion'/><title type='text'>object programming coldfusion</title><content type='html'>I just spend about 3 hrs trying to figure out where a piece of output was coming from.  This is a bit of a rant against object oriented programming, at least in CF.  First off, the resome i was looking for this piece of code is to analyze a program area in the application.  For some users, who have alot of data, this list that is build and displayed to the user takes way too long to build.  Sometimes in excess of 60 seconds.  I think it has caused us to change the loop time out setting in the administrator.&lt;br /&gt;&lt;br /&gt;This application is build in a framework called machii.  Machii is capable enough framework, a bit heavy, meaning a lot of overhead and files that comprise the framework.  Machii makes it easy enought to know where to begin looking for the problem.  Follow the event, look for listeners that are calling into a service layer of some sort - follow the service layer into a gateway or DAO object - throw in another framework, coldSpring, and you can get pretty confused pretty fast.  Thats a different story.&lt;br /&gt;&lt;br /&gt;I traced down into the machii event and found the listener calls and the view files that appeared to be responsible for outputting this slowly developing content.  The view files did not have much content in it - just a mysterious call to an XML function.  My investigation then took me in another direction, until i found where the content was getting gathered, not displayed.  The output is stored in a group of Objects and then xmlized by another function.  Hmmmmm, is there a really compelling reason why this content was not simply being returned as a query object?  Light, easy... But not object pure.  I think this may be a case of the developer being a bit of a OOP purist and treating CF like Java.  And why are we xmling the result?  What is the gain here?  More overhead and complexity.  Perhaps its a case of "we may need this later in this portable format"...rather than YAGNI or KISS.  Anyway, this feels like alot of overcooking to me.  It took me way too long to find this class that was extending a base view event class - to just find about 15 lines of code responsible for actually outputting content. &lt;br /&gt;&lt;br /&gt;Bottom line - private functions in cfcs should not be outputting anything.  Let the cfcs do their job of getting data and making decisions about what to do - leave the view files to outputting the results.&lt;br /&gt;&lt;br /&gt;OOP is good, in the right places, but not always in every situation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-5076365493456922444?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/5076365493456922444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=5076365493456922444' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5076365493456922444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5076365493456922444'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/09/object-programming-coldfusion.html' title='object programming coldfusion'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-2019186609380520943</id><published>2009-04-02T13:01:00.000-07:00</published><updated>2009-04-02T13:41:00.091-07:00</updated><title type='text'>OO birds eye view</title><content type='html'>&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;OO&lt;/span&gt; - think in terms of objects&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OO&lt;/span&gt; - think in terms of data and functions together in a single entity&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;OO&lt;/span&gt; - think in terms of &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;reference&lt;/span&gt;, not value&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;OO&lt;/span&gt; - think in terms of encapsulation (self sufficiency)&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;OO&lt;/span&gt; - think in terms of&lt;br /&gt;&lt;br /&gt;OO - think in terms of singleton -vs- transient&lt;br /&gt;&lt;br /&gt;OO - think in terms of state of an object&lt;br /&gt;&lt;br /&gt;OO - think in terms of security (accessors and modifyers) - getters / setters&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Software Architecture (MVC)&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;think in terms of layers&lt;br /&gt;&lt;br /&gt;think in terms of separation of concerns&lt;br /&gt;&lt;br /&gt;think in terms of maintenance&lt;br /&gt;&lt;br /&gt;think in terms of clarity&lt;br /&gt;&lt;br /&gt;think in terms of sessions&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Desing Patterns&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;think in terms of DAOs, Gateways, Beans&lt;br /&gt;&lt;br /&gt;think in terms of anti pattern (3- 1) - not every entity needs its own service, gateway and DAO&lt;br /&gt;&lt;br /&gt;a service should serve more than just a single DAO and Gateway.&lt;br /&gt;&lt;br /&gt;think in terms of doctor - patient (a doctor has many patients)&lt;br /&gt;&lt;br /&gt;think of singletons -vs- transients&lt;br /&gt;&lt;br /&gt;singletons application wide, transients user wide&lt;br /&gt;&lt;br /&gt;transients (have state)&lt;br /&gt;singletons (no state)&lt;br /&gt;&lt;br /&gt;*for the singletons (many users using a single instance) think in terms of varing&lt;br /&gt;every variable in it. these are objects stored in application scope.&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Frameworks&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;think in terms of maintenance&lt;/p&gt;&lt;p&gt;thinks of tradeoffs&lt;/p&gt;&lt;p&gt;think of consequences&lt;/p&gt;&lt;p&gt;think of payoff (work up front, payoff later)&lt;/p&gt;&lt;p&gt;think of overhead&lt;/p&gt;&lt;p&gt;think of consistency - predicatability&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-2019186609380520943?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/2019186609380520943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=2019186609380520943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2019186609380520943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2019186609380520943'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/04/oo-birds-eye-view.html' title='OO birds eye view'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-1448850319836251701</id><published>2009-04-02T12:16:00.000-07:00</published><updated>2009-04-02T12:47:52.562-07:00</updated><title type='text'>OO programming from domain to presentation layer</title><content type='html'>I am always trying to get a better handle on OO programming techniques. I come from that produral background and i think it is always influencing the way i see layer and communication.&lt;br /&gt;&lt;br /&gt;If i can think of the objects as two types&lt;br /&gt;singletons - only one copy exists per session per user - these have no state&lt;br /&gt;(these are DOA's, Gateways, Services)&lt;br /&gt;&lt;br /&gt;transient - have state and need to keep the state while living in memory&lt;br /&gt;(these are beans or value objects)&lt;br /&gt;&lt;br /&gt;In my main application that i support, this means&lt;br /&gt;&lt;br /&gt;transient objects or beans that have state (specific data associated with them) are&lt;br /&gt;assessments&lt;br /&gt;standards (performance indicators)&lt;br /&gt;resources&lt;br /&gt;&lt;br /&gt;Each of these beans is updated when a new one is selected.&lt;br /&gt;&lt;br /&gt;For each &lt;strong&gt;user&lt;/strong&gt; a set of each is created (assesment, resourse, standard) value bean. They are created in the service that is used to communicate with them.&lt;br /&gt;&lt;br /&gt;There is only a single service object (a singleton) that is created once when the application starts. The singleton is placed in a application scope and is then accessible to every user who comes to the site. They all share the same instance of the object or class. There is no race concerns because the application (coldFusion) takes care of the threading.&lt;br /&gt;&lt;br /&gt;So - one instance of the services for all the users who come to the site. A collection of objects for each user when they initially hit a part of the site that uses the service for those objects.&lt;br /&gt;&lt;br /&gt;Also in the service, besides the instantiating of the transient objects, are the rules for when to call the other singletons. The service is the big DOG. It knows about the other services and the other singleton and transient objects. If you looked into the init() of the service.&lt;br /&gt;&lt;br /&gt;Again - think like this&lt;br /&gt;&lt;br /&gt;- whenever you have data to persist for a value object&lt;br /&gt;- ensure a copy of it exists in memory&lt;br /&gt;- use the DAO to get the updated data (if reading from table)&lt;br /&gt;- use the Form or URL parameters if updating to a table)&lt;br /&gt; - update the current bean in memory&lt;br /&gt;- pass a reference to the bean from the service into the DAO/Gateway when necessary&lt;br /&gt;- pass a reference back to the presentation layer when feasible.&lt;br /&gt;&lt;br /&gt;I dont think rules like this are always adviseable, some times it just makes sense to pass by value and not reference.  But, in the spirit of OO - think like this by default and work from that position.&lt;br /&gt;&lt;br /&gt;I did this in a couple view pages i was recently working on.  The the user clicked on a resource or assessment or standard, if the request was to view something - then i would go to the service who who use the id and existing reference to the value object, and pass them both into the DAO gto get the details from the DB.  If the request was a update, then i would use the updated values in the form fields and pass them along into the service and update the current bean using the arguments passed in and then pass back a reference to the value (bean) object.  now in my presentation layer im referencing the bean that is in memory.  Im not actually going back into the db (which is a no no from a MVC perspective) - but referencing the value bean via the object passed along.  Encapsulationa and OO techniques!&lt;br /&gt;&lt;br /&gt;Im not sure if this is really the smartest way to go about this, but it is my attemp to continue to push out OO concepts and challenge myself to learn to think in terms of Objects and encapsulation.&lt;br /&gt;&lt;br /&gt;cheers&lt;br /&gt;What i started to do recently, in the spirit of OO, is to return the pointer or reference to the presentation layer.&lt;br /&gt;&lt;br /&gt;&lt;cffunction returntype="resources.model.ResourceService" access="public" name="init"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;cfset gateway=" createObject("&gt;&lt;cfset dao=" createObject("&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;cfset webbean=" CreateObject("&gt;&lt;br /&gt;&lt;cfset pitbean=" CreateObject("&gt;&lt;br /&gt;&lt;cfset pibean=" CreateObject("&gt;&lt;br /&gt;&lt;br /&gt;&lt;cfreturn&gt;&lt;br /&gt;&lt;br /&gt;&lt;/cffunction&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-1448850319836251701?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/1448850319836251701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=1448850319836251701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1448850319836251701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1448850319836251701'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/04/oo-programming-from-domain-to.html' title='OO programming from domain to presentation layer'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-8895056338783696162</id><published>2009-02-03T11:45:00.001-08:00</published><updated>2009-02-03T12:56:25.609-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fckeditor - dynamic pathing uploading'/><title type='text'>3rd party editors - usability</title><content type='html'>Ive build a utlility application that uses a 3rd party editor called Fckeditor. Its a popular editor, that is implemented in each of the major platforms, java, coldfusion, asp, etc..&lt;br /&gt;&lt;br /&gt;I brought it into play originally for another utlitity application that i was working on. Each of the two utilities are about feeding data to a relational db.&lt;br /&gt;&lt;br /&gt;Each of the two utilities needs to upload files as part of their jobs. Lots of text, with images needed as well as other upload types. the challenge is that each utility needs to store the uploads in different places. I could, i suppose use different implementations, meaning give each utility its own set of core files (thats about 400 total) - seems a little overkill. What im looking to do is dynamically inform the path where the editor will upload the images to.&lt;br /&gt;&lt;br /&gt;Ive dug into the editor a bit and found the upload configuration file that is defining the path where the uploads are going. Now i need to figure out the smartest way to inform the editor where it being used from and pass that variable into the configuration file to dynamically set the userpath.&lt;br /&gt;&lt;br /&gt;If this gets too hairy, i can always use plan A, each utility having its own implementation of the fckeditor core files.....but i really dont want to do that.&lt;br /&gt;&lt;br /&gt;stay tuned&lt;br /&gt;&lt;br /&gt;Im back - im thinking i may try to scale down the size of the fckeditor core files - since alot of them are for implementations that i am not using.  Then each Utility could have its own version of the core files.  Then, each would have its own&lt;br /&gt;&lt;br /&gt;fckeditor.editor.filemanager.upload.cfm.config.cfm&lt;br /&gt;&lt;br /&gt;and i could set one where it is now and the other where it needs to be, including the dynamic updating still needed.&lt;br /&gt;Resources path = userfiles/image&lt;br /&gt;assessments path = assessment/assessmentID/&lt;br /&gt;&lt;br /&gt;perhaps...i need to continue my heavy lifting around this before moving into a implementation.&lt;br /&gt;&lt;br /&gt;Im thinking about creating a utility helper CFC where i could set a session variable or application and use that to inform the assessments *dynamic portion.  In the assessments app, im using a framework where i could use a build in plug in point to instantiate the helper object upon application startup. "bootstrapping".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-8895056338783696162?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/8895056338783696162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=8895056338783696162' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8895056338783696162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8895056338783696162'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/02/3rd-party-editors-usability.html' title='3rd party editors - usability'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-798090521825566732</id><published>2009-02-02T11:57:00.003-08:00</published><updated>2009-02-02T11:57:50.446-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='application.cfc framework'/><title type='text'>Application.cfc and Frameworks</title><content type='html'>im working on a utility and am setting up a little session state management.  I have a request from a customer like this "when we choose a question type of A, can it remember that for the next one record i add?".  Of course, a common request, what i would referr to as state management.  Keep the last answer provided by the user via the interface and use it to inform the state of the interface.  Session variables come immediatly to mind.&lt;br /&gt;&lt;br /&gt;I set off to implement this solution.  I thought about it for a little while first, heavylifting, my biggest question was where to lookup and update the session variable.  I did not want to do it on the view page, but rather somewhere in a *session object.  My thinking brought me into the Application.cfc, which is a special *framework like component that Coldfusion provides that have built in plugin points.  This means there are points in a request where the developer can interceed and do some kind of processing, testing etc.  These built in functions include application start and end, session start and end, request state and end.  This is pretty handy IF you ARE NOT ALLREADY using a framework.&lt;br /&gt;&lt;br /&gt;I am using machii and so have a means already to interceed where i need to.  Additionaly, the framework allows me to interceed in the event that i want, not all the events.  That feels a little better than sticking the test in a OnRequest function.  I could put logic in the OnRequest and have it only perform when needed - but even then, that wrapper logic would be read on EVERY request.  My framework allows me to place the same test in a listener or service request that is ONLY read when i explicitly call for it.&lt;br /&gt;&lt;br /&gt;The framework adds overhead, but pays for itself in many ways, including this one.&lt;br /&gt;&lt;br /&gt;Bottom line - dont expect to use Application.cfc or the old school Application.cfm IF you are using a framework.  This is a quote from mega smart Sean Corfield.&lt;br /&gt;&lt;br /&gt;"It doesn't really. Frameworks generally provide their own plugin points and ignore Application.cfm - and they pretty much ignore Application.cfc as well. Perhaps future versions of the frameworks will support / integrate with Application.cfc? "&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-798090521825566732?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/798090521825566732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=798090521825566732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/798090521825566732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/798090521825566732'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/02/applicationcfc-and-frameworks_02.html' title='Application.cfc and Frameworks'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-631751624064968689</id><published>2009-02-02T11:57:00.001-08:00</published><updated>2009-02-02T11:57:48.410-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='application.cfc framework'/><title type='text'>Application.cfc and Frameworks</title><content type='html'>im working on a utility and am setting up a little session state management.  I have a request from a customer like this "when we choose a question type of A, can it remember that for the next one record i add?".  Of course, a common request, what i would referr to as state management.  Keep the last answer provided by the user via the interface and use it to inform the state of the interface.  Session variables come immediatly to mind.&lt;br /&gt;&lt;br /&gt;I set off to implement this solution.  I thought about it for a little while first, heavylifting, my biggest question was where to lookup and update the session variable.  I did not want to do it on the view page, but rather somewhere in a *session object.  My thinking brought me into the Application.cfc, which is a special *framework like component that Coldfusion provides that have built in plugin points.  This means there are points in a request where the developer can interceed and do some kind of processing, testing etc.  These built in functions include application start and end, session start and end, request state and end.  This is pretty handy IF you ARE NOT ALLREADY using a framework.&lt;br /&gt;&lt;br /&gt;I am using machii and so have a means already to interceed where i need to.  Additionaly, the framework allows me to interceed in the event that i want, not all the events.  That feels a little better than sticking the test in a OnRequest function.  I could put logic in the OnRequest and have it only perform when needed - but even then, that wrapper logic would be read on EVERY request.  My framework allows me to place the same test in a listener or service request that is ONLY read when i explicitly call for it.&lt;br /&gt;&lt;br /&gt;The framework adds overhead, but pays for itself in many ways, including this one.&lt;br /&gt;&lt;br /&gt;Bottom line - dont expect to use Application.cfc or the old school Application.cfm IF you are using a framework.  This is a quote from mega smart Sean Corfield.&lt;br /&gt;&lt;br /&gt;"It doesn't really. Frameworks generally provide their own plugin points and ignore Application.cfm - and they pretty much ignore Application.cfc as well. Perhaps future versions of the frameworks will support / integrate with Application.cfc? "&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-631751624064968689?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/631751624064968689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=631751624064968689' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/631751624064968689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/631751624064968689'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/02/applicationcfc-and-frameworks.html' title='Application.cfc and Frameworks'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-1066097360014112035</id><published>2009-01-20T12:29:00.001-08:00</published><updated>2009-01-20T12:48:25.098-08:00</updated><title type='text'>Beans, DAOs, Services, applications</title><content type='html'>Im working on a Utility that does standard CRUD stuff. My brain got a little confused, again, in the area of relationships between services, beans and DAOs. Specifically, i could not decide the best way to implement the relationships between the three. In a SOA, we use the Service object as the laison between the application and the domain objects. Does the service also keep the responsibility of creating a persistence bean for a certain object? I think so, i added the instantiation of the resource persistence bean into the init() of the service. Now the service init() function instantiates DOA, Gateway and bean objects. I am using the variables scope in front of each and have tested the threading, which should not be a problem, since each user who instantiates their own service object gets there own copy of each of the other objects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In my service, I have a set bean method, that updates the "empty" bean object, by passing a objectID into the set bean method - which then goes to the DAO, since thats the object that should have the SQL or whatever DB code you are using. The bean itself should not know about the database that is being used to get its data so it can do its job of persisting. So, the service calls a getRecord method in the DAO, the DAO sends back a 1 record query to the service. Teh service checks to be sure it has a valid result and then passes the query result to the set bean method in the bean itself.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This seems to make sense - following these good OO practices.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Service creates objects needed to do the work requested by application&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Service asks the DAO to get a single record, passing in objectID&lt;br /&gt;&lt;/li&gt;&lt;li&gt;DAO returns a single record&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Service ensure the record returned is valid (this could be done in DAO too)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Service then calls the set bean method in the bean itself, passing in the record to update&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;In conclusion:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The DOA does not know about the beans&lt;/li&gt;&lt;li&gt;The beans do not know about the database&lt;/li&gt;&lt;li&gt;The service knows about beans and DAOs and Gateways and other services.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-1066097360014112035?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/1066097360014112035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=1066097360014112035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1066097360014112035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1066097360014112035'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/01/beans-daos-services-applications.html' title='Beans, DAOs, Services, applications'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-2609230527931835880</id><published>2009-01-13T08:54:00.000-08:00</published><updated>2009-01-13T09:41:13.886-08:00</updated><title type='text'>new development</title><content type='html'>Im about to begin development on a medium sized project and wanted to document some of the things i know i should be thinking about before i begin.&lt;br /&gt;&lt;br /&gt;Who is my customer - define this, have them in your mind.  You should be able to say in a couple works who they are.&lt;br /&gt;&lt;br /&gt;What do they want - get a requirements document nailed down.  Thats happening now, my customer is detailing the requirements from our meeting, he will share those back with me for agreement before giving to his client.  Be very specific about what the specs indicate will be done in the initial iteration.  We could use a front to back design methodology that gets the product in front of the client sooner than later.  We may still try to do this.  I am following the Agile approach, not the water fall.  In other words, create smaller more focused iterations of the product, rather than larger more consuming ones.  This is a tenent of good design or process.&lt;br /&gt;&lt;br /&gt;Getting down to business.  I will follow a mature design pattern, MVC.  This pattern will focus on the separation of functionality into three distinct pieces.  Think usability in the view layer.  Ensure the interface is easy to use, clean and reliable.  Not too much clutter or needing to dig to see things.  Provide immediate feedback in the interface.  Perhaps use AJAX type functionality.  This will be a data intensive application, so AJAX techniques would be valuable.  At the same time, be sure the application works in both IE and FF.  AJAX stuff sometimes is cross browser problematic.  I could use the built in CF8 AJAX libraries, but this would require that the hosting server would also be using CF8, which is not quite true, yet.  I should stay away from cf8 specific functionality for now.&lt;br /&gt;&lt;br /&gt;The controller.  I will probably use machii or some MVC framework.  Other utilities and the main application all use machii.  I *could be consistent or i could use as opportunity to try a different framework, like model glue or Tarten.  I could forgo a framework all together, but i like what the framework provides and I know that this application is going to grow in complexity.&lt;br /&gt;&lt;br /&gt;The model.  This is the part that is most interesting to me.  I do like the other layers, but the domain modeling and service, DAO, bean objects are of most interest.  I have implemented these patterns a few times now and each new opportunity provides more insight and hopefully a tighter design.   I could even try to use a ORM tool to stub out the intial domain objects.  The domain design includes how to manage the relationships between the collaborating entities.  I will probably use ColdSpring again, since i just think its a superb piece of engineering.  Maybe i wont use CS, and show how the objects themselves could keep that knowledge, via init and constructors.&lt;br /&gt;&lt;br /&gt;Ill return in a couple weeks when im done with the initial build of this Utility.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-2609230527931835880?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/2609230527931835880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=2609230527931835880' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2609230527931835880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2609230527931835880'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/01/new-development.html' title='new development'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-6379520699591770707</id><published>2009-01-07T10:01:00.000-08:00</published><updated>2009-01-07T10:18:50.766-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coldSpring'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns design'/><title type='text'>Reflection - training new developers</title><content type='html'>I have been helping a co-worker do some work that has really caused me to look at some high level principles.  I like this, and wanted to capture some of the thoughts.   first off, we are following the SOA design patterns in our development.  this to me means - creating a service oriented architecture, where the service objects are the big dogs in the playground.  they are at the conceptual front of the domain line.  They are who is called when some application wants to get at some data. &lt;br /&gt;&lt;br /&gt;In our application, we are using machii, so there are listeners that are registered as part of the application.  Whenever the application does something - it is funneled through the controller (a xml file) in the form of an event.  If the event needs to speak to the data layer - then is uses one of the registered listeners to do that. &lt;br /&gt;&lt;br /&gt;The listener has lots of functions in it and has *knowledge of the event and the arguments or parameters *URL variables that are passed around (this is usually either URL or form data served up by a view page.  The listeners job is primarily to pass things along - pieces of data that the service will need that determines what to do with it.&lt;br /&gt;&lt;br /&gt;This is know as the bus. logic and should live downsteam from the application and listeners.  The bus. logic should live in the service and in the persistance objects.&lt;br /&gt;&lt;br /&gt;So, while helping my co-worked to understand all this abstraction of layers - i found myself using works like design patterns, service oriented architecture and persistence beans - including anemic -vs- rich beans.   When you have to explain to someone why things are how they are, it makes you think very critically about the why portion - and you better have more than a "because thats how i found it" response.&lt;br /&gt;&lt;br /&gt;I am also using coldSpring - so i talked about where the service gets its knowledge of things from.  rather than the service objects creating its dependent objects itself - that knowledge is abstracted from the collaborating objects and into a *container xml file that does it for you.  Brilliant!.  I do like coldspring alot!  I  talked with her about where this new piece of bus. logic should go and where it should come from and why.  It was a neat experience.&lt;br /&gt;&lt;br /&gt;Im not saying that i have all the answers or that the answers that i have are perfect, im just saying it felt good to explain this stuff and to see her seem to get it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-6379520699591770707?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/6379520699591770707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=6379520699591770707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6379520699591770707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6379520699591770707'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2009/01/reflection-training-new-developers.html' title='Reflection - training new developers'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-1337286544788874200</id><published>2008-12-04T12:02:00.000-08:00</published><updated>2008-12-04T13:28:33.441-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coldSpring pathing cfcs coldfusion'/><title type='text'>Be a good investigator</title><content type='html'>We use a &lt;strong&gt;machII&lt;/strong&gt; framework around our application. We also use &lt;strong&gt;coldSpring&lt;/strong&gt; to manage the relationships and instantiation of collaborating components in our domain.&lt;br /&gt;&lt;br /&gt;A quick review, for my own brain too. Machii helps to organize large scale enterprise level applications and promotes OO design of the application, or at least promotes &lt;strong&gt;MVC &lt;/strong&gt;design pattern. There is no denying that, Machii forces the &lt;strong&gt;separation of concerns&lt;/strong&gt; between the &lt;strong&gt;presentation&lt;/strong&gt;, &lt;strong&gt;control&lt;/strong&gt; and (&lt;strong&gt;model&lt;/strong&gt;)domain layers of the application. It also promotes OO design by using &lt;strong&gt;listeners&lt;/strong&gt;, that do the &lt;strong&gt;requesting of data&lt;/strong&gt; from the domain. It is possible to use Machii and listeners and still be using &lt;strong&gt;prodedural&lt;/strong&gt; programming techniques, guity. Moving on.&lt;br /&gt;&lt;br /&gt;The application in question consumes lots of complex data that is served up by the domain via &lt;strong&gt;services&lt;/strong&gt;. This is in line with &lt;strong&gt;SOA&lt;/strong&gt; type architecture. &lt;strong&gt;Services oriented architecture&lt;/strong&gt;. The domain makes available services that the machii application listeners know about. The listeners have knowledge of services and can speak to them. The application does NOT KNOW ANYTHING about the domain or model layer that is providing or peristing the data that it needs.&lt;br /&gt;&lt;br /&gt;Picture machii doing its job, housing the &lt;strong&gt;views&lt;/strong&gt; and the &lt;strong&gt;events&lt;/strong&gt; and the &lt;strong&gt;listeners&lt;/strong&gt;, that know about &lt;strong&gt;services&lt;/strong&gt; that speak to the&lt;strong&gt; data model&lt;/strong&gt; layer. Whenever something happens in the application, an event is fired, the event has *commands that are part of it - like requests for data and calls to other listener funtions. The arguments or data provided during the event is passed along via the event to the listener who hands that off to a service. The service knows then what to do with it. Recall that the service HAS knowledge of who it is serving. The SOA architecture promotes the notion of the service as the &lt;strong&gt;SOCIAL&lt;/strong&gt; beast in the equation. The service will have much of the &lt;strong&gt;bus. rules&lt;/strong&gt; or logic contained within it. It does a lot of the heavy lifting or thinking for the other components in the domain. The &lt;strong&gt;service&lt;/strong&gt; knows what do do in this situation or that situation, when this piece of data is missing or if a specific type of data is encountered.&lt;br /&gt;Recall that a service probably has its own set of &lt;strong&gt;dependent components&lt;/strong&gt; that must exist for it to do its job. A common occurance is a &lt;strong&gt;DAO &lt;/strong&gt;or &lt;strong&gt;Gateway&lt;/strong&gt; or &lt;strong&gt;persistence bean&lt;/strong&gt; that the service relies on to do its job. If any of these other &lt;strong&gt;collaborating&lt;/strong&gt; components does not exist, the service fails.&lt;br /&gt;The SERVICES, being social, often need to know about &lt;strong&gt;other services&lt;/strong&gt;, not about the other services collaborating entities, just the service itself. This need to know about each other had much to do with the birthing of &lt;strong&gt;ColdSpring&lt;/strong&gt;. With, as the name implies, follows the concept of &lt;strong&gt;Spring&lt;/strong&gt; in the &lt;strong&gt;Java&lt;/strong&gt; world, which is a framwork that helps manage the complex relationships that exist between the &lt;strong&gt;collaborating entities&lt;/strong&gt; in the domain.&lt;br /&gt;&lt;br /&gt;ColdSpring "&lt;strong&gt;lifts&lt;/strong&gt;" the &lt;strong&gt;knowledge&lt;/strong&gt; of the collaborating entities out of the entities themselves and places them into a separate &lt;strong&gt;container&lt;/strong&gt;. This is &lt;strong&gt;abstraction&lt;/strong&gt; at its finest.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Tradoffs&lt;/strong&gt; - there is always tradoffs when you use a framework, like machii or coldSpring. In the case of coldSpring, that is a slight performance &lt;strong&gt;overhead&lt;/strong&gt; and the need to maintain a separate &lt;strong&gt;XML&lt;/strong&gt; style document. A little complexity at first. The gain is a one stop place to &lt;strong&gt;create&lt;/strong&gt; and &lt;strong&gt;manage&lt;/strong&gt; the relationships that exist between your &lt;strong&gt;services, DOAs, Gateways&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;We have two separate coldSpring xml files, one that is used by the application and another than is used by a sub- application. When i built the sub app, i originally had the domain components instantiating their own collaborating components, this is the natural way to build the app, not seeing the need for a framework initially, who needs it! Eventually, as the sub app grew in complexity and collaborating entities, the need became more clear. I created a new *bean building xml file (this is the container that holds all the bean definitions). The coldSpring configuration file consistes of bean definitions complete with references to dependent components. CS calls this dependency injection -this is usually reserved for those social services, who need to have their dependent DAOs and gateways and other services to work properly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;The problem&lt;/span&gt; &lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In my sub - app coldspring file, i named a bean the same as one that already existed in the root coldSpring config. file. Even though i &lt;strong&gt;pathed&lt;/strong&gt; the bean in the sub app to a different component, it seemed to ignore the bean def.  Seems if a beanname already exists in the current scope, it will not read the next.  It could be a problem with how i am using the scope? -&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;strong&gt;The symptom&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The problem reported as a failure to set an injection statement in # 2&lt;br /&gt;&lt;br /&gt;1 - model.questions.QuestionService.cfc&lt;br /&gt;2 - assessments.questions.QuestionService.cfc&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;strong&gt;The Diagnosis&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;I tried to path # 2 a little different, since I did not want to change the name of the service (this would require me to update the name in a couple other places), but was not successful.&lt;br /&gt;The config file in the sub app was pathed to # 2 but when it tried to do its injection of a DAO, it was reporting the failure in relation to # 1.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;strong&gt;The Test&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I changed the name of the component in # 2 and updated that name in the appropriate places, a listener, another reference in the CS config file and a reference in another service that was using this and walla - problem gone, lesson learned.&lt;br /&gt;&lt;br /&gt;Recall that when you are doing dependency injection in a bean definition in the CS config file, you need an equivently named funtion in the collaborating (injecting) component, with the letters set in from of it. In other words, if you have a service bean being in jected with a DAO, then the injecting DAO must have a setDAO funtion that allows the setting.&lt;br /&gt;&lt;br /&gt;&lt;cffunction name="setQuestionDAO" returntype="void" access="public"&gt;Like this - here is the bean defintion *&lt;em&gt;minus the brackets that the blogger does not like&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;bean id="AssessmentQuestionService" class="assessments.model.QuestionService"&lt;br /&gt;property name="QuestionDAO"&lt;br /&gt;ref bean="QuestionDAO"&lt;br /&gt;property&lt;br /&gt;bean&lt;br /&gt;&lt;br /&gt;Here is the function in the service that is being injected&lt;br /&gt;&lt;br /&gt;cffunction name="setQuestionDAO" access="public" returntype="void"&lt;br /&gt;cfargument name="QuestionDAO" type="assessments.model.QuestionDAO" required="Yes"&lt;br /&gt;cfset variables.QuestionDAO = arguments.QuestionDAO&lt;br /&gt;cffunction&lt;br /&gt;&lt;br /&gt;This is a little intimedating at first, but trust the technology and the beauty of the design. It becomes more clear as to its power and purpose over time, when you add more things to the application and more relationships between collaborating entities.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-1337286544788874200?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/1337286544788874200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=1337286544788874200' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1337286544788874200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1337286544788874200'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/12/be-good-investigator.html' title='Be a good investigator'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-5334357719977976901</id><published>2008-11-05T11:55:00.000-08:00</published><updated>2008-11-05T12:21:11.817-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='front end development'/><category scheme='http://www.blogger.com/atom/ns#' term='Prototyping'/><category scheme='http://www.blogger.com/atom/ns#' term='people'/><title type='text'>Prototyping</title><content type='html'>Ive been working on some new functionality the past couple weeks, which is nice, since it has been awhile since our project has seen any new functionality.  We used to use a process called FLIP, that Hal helms and Jeff Peters worked up awhile back, but the people, including the customers who were involved in this are gone, so i ended up thinking hard about what parts of that process worked and what parts could be left out.  A re-cap of that analysis follows.&lt;br /&gt;&lt;br /&gt;What works&lt;br /&gt;&lt;br /&gt;Front end development first.  That's a fine principle to follow while building new functionality.  What is the new stuff supposed to be doing? How should it do it, what should the interface look like, what kind of functionalily should be present.  All these things help the customer to see things that they are trying to describe.  Put something in front of them and let them see it in context of the system where it will be used.  I even heard one of my customers say "now that i can see it in place" the other day, more on that in a moment.&lt;br /&gt;&lt;br /&gt;Don't think implementation, at least not the database or model domain. Anther one of our developers at the presentation was asking questions about implementation.  This was the initial design and presenation of the design, there should be ZERO talk of implmentation.  We are focusing on what they client wants! &lt;br /&gt;&lt;br /&gt;Keep it light - do not attach the prototype to any real datam, fake it.  Hard code stuff in view pages, do not query or instantiate objects in any way in the prototype. When i could myself starting to think these things, i kicked myself.  This payed off immediately, since some of what i was prototyping was not needed, at least at this point.  &lt;br /&gt;Get it in front of the client, expect multiple iterations before they say "thats it".  Make sure that you get the people who are interested or who should have a say involved early.  I need to do that now.  One of my customers was not present at the meeting.  I need to get his input sooner than later.  &lt;br /&gt;&lt;br /&gt;I am prototyping the new code in the actual application, which required me to do a bit more work, that if i used the prototype toolkit that we used to use.  But its work it.  &lt;br /&gt;&lt;br /&gt;Elicit feedback.  In our previous prototyping cycles, we used a toolkit that allowed users to login and leave comments on each view page.  That was moderatetly useful.  Some of the customers understood what we were trying to do, but others did not get it and it was alot of work and a hassle.  The prototype toolkit would get in the way of what they were trying to do and confuse things.  They would leave comments on the wrong pages or the login would fail or something would go wrong.&lt;br /&gt;&lt;br /&gt;Now, i am putting the new code in the actual application on my localhost and showing it to the group.  My next step will be to put the revised content on our test server and give another presentation.  The feedback, which is so important will be handled via email via me asserting things back to them and them clarifying.  This is not perfect either, but is the way i am approaching.&lt;br /&gt;&lt;br /&gt;I am thinking some implementation.  The new functionality is a calendar that is showing release dates of critical information in our application.  Naturally, AJAX comes to mind, since i do not want to have to reload the application every time the user clicks a new month or year.  We just want to drill down into the data and update the calendar without reloading the application.  Im thinking this, but not implementing, since i am not doing any drilling into the domain at this point.  My prototype is using some javascript to automatically update the calendar when a select box is changed or a pre / next link is clicked, but no real AJAX yet.&lt;br /&gt;&lt;br /&gt;I want to be sure the customer says, "that's it for the initial release of the calendar functionality".  Then we can freeze things and i can implement the AJAX and other domain code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-5334357719977976901?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/5334357719977976901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=5334357719977976901' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5334357719977976901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5334357719977976901'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/11/prototyping.html' title='Prototyping'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7605109403144740165</id><published>2008-10-15T11:38:00.001-07:00</published><updated>2008-10-15T11:58:54.802-07:00</updated><title type='text'>Post mortem on major upgrade of application</title><content type='html'>Well, its october and we finally got all that re-factored code through our staging and production environments.  It was a pretty big move.  There were about 70 files to move around between the domain and presentation layers.  About 10 were simply moved to a new location, away from the domain objects.  this is a mach-ii application, which explicitly uses listeners.  since the listeners are part of the application and not part of the domain, i felt it warrented to move away from the *model folder.&lt;br /&gt;&lt;br /&gt;Some of the other components (cfcs) were moved from the model root into a specific folder that represented the object.&lt;br /&gt;&lt;br /&gt;I updated coldSpring with new definitions to some of the objects and updated paths to existing objects, to their new locations.&lt;br /&gt;&lt;br /&gt;I was also able to remove a couple object instantiations and use the coldSpring provided object reference.  this simplifies a bit and removes a little memory overhead but more than that it cleans up and organized the code base better.  I already had one new developer who is starting work on this application comment on how she likes the organization better, easier to find things etc.&lt;br /&gt;&lt;br /&gt;I also ended up splitting up some presentation code into smaller more singular entities.  Reuse in the presentation layer is overrated.  I had a single view file that was responding to 4 different types of data, which was cool, but in the end, became too difficult to maintain.  that reminded me of the fact that 75% of all programming or time that a developer spends is maintaining existing apps.  To that end, creating additional view files for each subject is a tradeoff worth taking.  The tradeoff is more code to maintain, but less complex, fewer dependencies.  In the domain, i did the same thing.  There was one of two functions that were responsible for getting lots of different variations of similar data.  Again, this is good programming to think re-use and not have 40 different functions that are all doing similar stuff, but as time goes by, you start to appreciate the ease of maintenance - which is supported by more functions that do less or even a single thing.  I can tell you that the trade off is worth it.  I always appreciate it when i enter the domain into a gateway query that is very specific and not loaded down with 8 arguments, where 4 are required and 4 are not packed with lots of conditional code in case arguments are passed in....where if you make one small change you worry about effecting the other 10 instances of how this function is called.&lt;br /&gt;&lt;br /&gt;Part of this move to staging then production also included the removal of deprecated files that were wither moved to a new location or re-factored.&lt;br /&gt;&lt;br /&gt;As i said, i think about 70 new files were moved and about 25 were deprecated.&lt;br /&gt;&lt;br /&gt;this move also included many updates to the central controller, where i was removing calls to old functions that had been re-factored or removed and updated paths to listeners, that are registered in the controller and removed references to view files that had been deprecated.  view files are also referenced in the controller.&lt;br /&gt;&lt;br /&gt;Thats it for now.  What a move, really minor problems while moving - biggest issues where keeping the labels, thats how we manage deployment, current and on the tip version of files.  I ended up missing a couple files, no label and did not move the tip of the label on a couple others.  these problems only took a few minutes to correct.  The most grueling part was when our testing general was looking real critically at the layout and recordsets of the views that i had re-factored that were being feed by re-factored queries.&lt;br /&gt;&lt;br /&gt;Good experience.  Looking forward to the next one, thought it be smaller.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-7605109403144740165?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7605109403144740165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7605109403144740165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7605109403144740165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7605109403144740165'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/10/post-mortem-on-major-upgrade-of.html' title='Post mortem on major upgrade of application'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-145102531551120854</id><published>2008-09-02T09:34:00.000-07:00</published><updated>2008-09-02T10:17:15.113-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='model refactoring domain logic coldspring'/><title type='text'>model refactoring project continued</title><content type='html'>Im working on a small update to some core logic in one of my frequently visisted objects.  A couple of the updates, including to the controller (this is a machii application) are requiring me to bring along some other changes i made a couple months ago and have been sitting waiting for something like this to come along.  I could have made a branch in our source control software to deal with only the changes to the current project, but chose not to.&lt;br /&gt;&lt;br /&gt;When i looked back at the changes i made a couple months back, i noticed the coldspring integration i had started. I had integrated a few components into the coldspring configuration file and injected them into their dependent service components.  All good!  I decided to integrate the current component and its dependent components too.  I was pleasently surprised when it only took me about 15 minutes to do this work.  Ive got my head around coldspring a bit now and new just what i wanted to do and why.  The changes are listed below.&lt;br /&gt;&lt;br /&gt;1 - identified the collobarating objects and gave them bean definitions in the config file&lt;br /&gt;2 - identified the dependent object and gave it a bean definition.&lt;br /&gt;3 - injected the two colloborating objects (components) into the dependent object&lt;br /&gt;4 - added set methods for the collaborating components in the dependent object that - removed the init method in the service&lt;br /&gt;6 - tweaked the colloborating components to not require a property on init, changed the default to no and provided a default value. If a value is passed, it will take it but does not require.&lt;br /&gt;&lt;br /&gt;Each of these components are singletons, which are perfect for the coldspring container.  They have no state and simply provided data that is kept in a related bean component. I caught myself trying to add the bean to the coldpring config. file, but stopped when i clued in to the bean is not a singleton, it has state that updates frequently.  I ended up with a method in the service to the bean that checks to see is a session scoped var exists, if not, creates one and used it to update the bean during the user session.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Then i moved into part 2 of this operation&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;As i am looking at the service, i see where i should have put certain methods into the DAO not the Gateway.  I think initially, i only had a gateway component, but as the requirements grew, so did the component.  Now i have a DAO and am putting requests for a single rec or data item into it, while leaving the gateway as the aggregator or record sets.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Finally, im looking at this wiht object eyes&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;and seeing what can i move to the bean and keep the persistence stored in the bean.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-145102531551120854?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/145102531551120854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=145102531551120854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/145102531551120854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/145102531551120854'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/09/model-refactoring-project-continued.html' title='model refactoring project continued'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-3450716407607250952</id><published>2008-08-29T07:05:00.000-07:00</published><updated>2008-08-29T07:22:32.097-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='good developer habits'/><title type='text'>Effective Developer habits</title><content type='html'>These are habits of effective developers.  I gleaned a lot of this from the helms and peters podcast.  I listened to this a couple years ago and again today.  Really good stuff.&lt;br /&gt;&lt;br /&gt;1 - Pursue professional growth.  Always make time to attend conferences, trainings etc.  Use the internet and its plethora of technical podcasts, articles, and blogs.  There are so many skilled smart people who have been down the same path that you are on and have documented their experience.&lt;br /&gt;&lt;br /&gt;2 - Think Google to help narrow down the search for related resources.&lt;br /&gt;&lt;br /&gt;3 - Blog yourself.  For me, its help A LOT to internalize things by writing them.  Thats why this blog exist.&lt;br /&gt;&lt;br /&gt;4 - Think user first.  Do not let your vision take precedence over the user or client vision.  Try to engage them as much as possible when gathering requirements.&lt;br /&gt;&lt;br /&gt;5 - Prototype.  If its a new product or functionality build the front end first.  There is a lot of smart people who advocate for this "front to back development approach".  Build the prototype, involve the client actively.  We used to follow a process called FLIP, that emphasized the prototype first while iterating frequently with the customer until they say "thats it".  There is no thought given to the implementation, language, DB or framework during the prototype.  This process takes at least half of the entire product development life cycle.&lt;br /&gt;&lt;br /&gt;6 - As a developer, do not assume superiority.  Be amiable, supportive, encouraging.  Believe that everyone who you come in contact with has something to offer.&lt;br /&gt;&lt;br /&gt;7 - Think first, code second.  Try to see the entire problem or big picture.  Seek the birds eye view before starting coding or database development.  &lt;br /&gt;&lt;br /&gt;8 - Document.  Not document your code, but code your documentation.  Think hard about what is good documentation.  Consider that someone else will be maintaining this code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-3450716407607250952?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/3450716407607250952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=3450716407607250952' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3450716407607250952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3450716407607250952'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/effective-developer-habits.html' title='Effective Developer habits'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-6485421029191928751</id><published>2008-08-28T08:52:00.000-07:00</published><updated>2008-08-28T09:07:54.244-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='objects composition inheritence'/><title type='text'>Object oriented design</title><content type='html'>Today, I was listing to Hal Helms and Jeff Peters discuss object oriented design.  They were talking about inheritance -vs- composition.  The main point was how composition has a is favored over inheritance, is a.  Ive been hearing this for awhile, but have not always understood, probably because its a little abstract, since im not doing much in the way of new object design or at least not with extending base classes.&lt;br /&gt;&lt;br /&gt;One concept was that base classes are really not ever instantiated, but extended.  This notion was further described this way:&lt;br /&gt;&lt;br /&gt;A goal of class programming, remember this is the model layer, not the view of controller, is to create stable reusable objects where commonality is captured in a base class that can be inherited or extended by a more specific class.  Another way to describe this base class is as a super class.&lt;br /&gt;&lt;br /&gt;The goal is to allow base classed to be easily extended (composition) to incorporate new behavior without modifying existing code.  This creates designs that are resilient to change and flexible enough to take on new functionality to meet changing requirements.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Design principle:&lt;/span&gt;&lt;br /&gt;Classes should be open to extension and closed to modification.&lt;br /&gt;&lt;br /&gt;These concepts where discussed around the context of the &lt;span style="font-style:italic;"&gt;Decorator Pattern&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Remember, when you abstract the differences by composition, you are adding complexity to the application.  Dont forget to think in terms of trade offs.  Nothing is free, when you build more extensible code, classes, by following this excellent principle, you are adding more complexity to your logic.  Only apply the "open closed" principle where needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-6485421029191928751?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/6485421029191928751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=6485421029191928751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6485421029191928751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6485421029191928751'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/object-oriented-design.html' title='Object oriented design'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-8144171020854217646</id><published>2008-08-27T11:11:00.000-07:00</published><updated>2008-08-27T12:47:09.963-07:00</updated><title type='text'>ColdFusion Frameworks, coldbox, tarten, MG, fusebox, machii</title><content type='html'>Today, i came across a number of helpful/interesting podcasts, articles.  First, the &lt;a href="http://www.helmsandpeters.com/"&gt;helms and peters &lt;/a&gt;podcast on Framework Shrink is both entertaining and informative.  During this cast, fusebox, MG and machii are all praised, frameworks in general are praised and people who program willy nilly are not praised.  They joke about the NMM (no methodology methodology) this is characterized by the developer who thinks they are too smart to have to use someone else ideas, why use a framework when i can solve the problem myself.  This brings to mind the debate between Hal Helms and Simon Horwith.  This was not so much a debate as a informative discussion about the pros and cons of frameworks.  With a decided edge going to the wisdom of using solid solutions created by others that follow best practices and encourage solid design for large applications that are scalable, maintainable, predictable (thats what the use of frameworks provide).&lt;br /&gt;&lt;br /&gt;I followed a thread to coldbox, another CF framework that lead to this discussion about the value of frameworks.  &lt;a href="http://rip747.wordpress.com/2006/10/24/whos-using-coldbox/"&gt;Who is using coldbox.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There was a mention of &lt;a href="http://www.tartanframework.org/tartan/"&gt;Tarten&lt;/a&gt;, which i had not hear of before.  Interesting, in my brief read, Tarten encourages a service oriented architecture, where the controller speaks only to a service that acts as a mediator to the bus. logic in the model.&lt;br /&gt;&lt;br /&gt;This is the common thread through all of the frameworks that i have been into and out of the past few months.  Each promotes the&lt;br /&gt;&lt;br /&gt;tiered architecture &lt;br /&gt;MVC design pattern to achieve separation of views and bus. logic via a controller&lt;br /&gt;OO design&lt;br /&gt;tight encapsulation&lt;br /&gt;loose coupling&lt;br /&gt;reuse of small singular type classes or objects or with CF, components&lt;br /&gt;the use of a controller to coordinate/direct requests made by application&lt;br /&gt;pushing of bus. logic into the model layer&lt;br /&gt;use of XML style controller&lt;br /&gt;preference for application to speak to the model via a service (tarten).&lt;br /&gt;&lt;br /&gt;I also found this useful &lt;a href="http://coldfusionportal.org/"&gt;cf portal site&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I really liked this part of the conversation, quoting Luis Majano.&lt;br /&gt;&lt;br /&gt;"Most major design patterns do apply to Coldfusion and decoupling and object oriented approaches are posible. Yes, they will make your application more complex, harder to grasp, and event WEIRD!! But that is the intent, to take your application to an Enterprise level. You can continue to build procedural code for certain applications, it doesn’t mean its bad. But for high availablity and enterprise applications, I would go with a framework. The flexibiliy and architectural extensibility that it will give you, cannot be found in other approaches. It will be hard to grasp and you might think, why do all this work, all these calls. Object Oriented architecture is not easy and you also have to note, that some complexity on these approaches, will make you sacrifice speed. But the benefits will be tremendous."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-8144171020854217646?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/8144171020854217646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=8144171020854217646' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8144171020854217646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8144171020854217646'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/coldfusion-frameworks-coldbox-tarten-mg.html' title='ColdFusion Frameworks, coldbox, tarten, MG, fusebox, machii'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-2483276478409254396</id><published>2008-08-20T13:01:00.000-07:00</published><updated>2008-08-20T13:32:03.136-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='custom'/><category scheme='http://www.blogger.com/atom/ns#' term='Machii'/><category scheme='http://www.blogger.com/atom/ns#' term='Model Glue'/><title type='text'>Frameworks, MG, Machii or Custom</title><content type='html'>I've been messing with MG the past couple days.  I have a small application im working on, and decided to give MG a go.  Things were going fine, it was taking me longer to solve the problem because i was learning the framework.  This is ok, acceptable when learning a new framework.  I spent a bit of time listening to podcasts, reading blogs and looking in the official Model-Glue documentation center.  Once i turned the corner on getting the MG controller to set the args properly from the event - i was on my way.  From this point, MG facilitating communication between my gui and model just fine.&lt;br /&gt;&lt;br /&gt;It was about this time that i started to feel like it was a bit overkill, the framework is pretty light, lighter than machii, but i still was not feeling good about the use of it in this case.  I just was not doing that much and felt like the overhead and increased complexity was not worth the cost.  Like a big brick, the vision of a streamlined *custom framework hit me in the head.  I could hear Simon Horwith whispering in my ear.  So, i decided to scale back a bit.  I used the index.cfm file to handle the bootstrapping and the rest of the setup work.  It reminded me of the fusebox settings file, where application level variables and pointers are set up. &lt;br /&gt;&lt;br /&gt;Index.cfm is now responsible for creating the object pointer into the service and also listens for actions (*events) such as insert, update or get.  Thats about all this GUI is doing. Depending on which action is executed (listened for) i am calling the appropriate service method and passing along form or URL vars appropriately.&lt;br /&gt;&lt;br /&gt;These are the following &lt;span style="font-weight:bold;"&gt;design principles&lt;/span&gt; adhered to:&lt;br /&gt;&lt;br /&gt;*MVC design pattern&lt;br /&gt;*separation of concerns (view just reacts to what is provided via the controller (index)&lt;br /&gt;*encapsulation of bus. logic (all in CFCs)&lt;br /&gt;*asynchronous calls, where helpful to user&lt;br /&gt;*no SQL in the views (see above)&lt;br /&gt;*safer from spammers and hackers, SQL is down stream protected by the service layer.&lt;br /&gt;*no extra overhead (MG or Machii or Fusebox)&lt;br /&gt;*intuitive - less complex&lt;br /&gt;&lt;br /&gt;tradoffs&lt;br /&gt;&lt;br /&gt;not as scalable as MG, Machii or fusebox&lt;br /&gt;&lt;br /&gt;If the requirements dictate, and a more scalable framework becomes necessary, i can simply trade in the index.cfm with its event and listening responsibilities for a MG  or MachII framework, where we can use an XML style central controller with specific listeners or messages.  Since i put the bus. logic in the services and the database interactions in the DAO, Gateway - its a can of corn.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-2483276478409254396?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/2483276478409254396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=2483276478409254396' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2483276478409254396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2483276478409254396'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/frameworks-mg-machii-or-custom.html' title='Frameworks, MG, Machii or Custom'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7683052368605795757</id><published>2008-08-14T13:21:00.000-07:00</published><updated>2008-08-14T13:22:11.561-07:00</updated><title type='text'>Model Glue</title><content type='html'>I ran across a ModelGlue folder on our test server today.  I have been hearing about MG for a couple years.  An easy to use CF framework that promotes MVC.  I decided to take a look.  I found a read me file in a predictable location and opened it.  It had excellent instructions about how to copy a certain folder into your web root, open a controller and change a couple properties in the xml config. file.  I did all this, made a silly mistake and corrected it and had the sample RD site up and running in 20 minutes.  Impressive.  Not me, it.&lt;br /&gt;&lt;br /&gt;I recall the setup and initial forays into fusebox and machii and neither was anywhere near as easy as this.  Granted, it looks a lot like machii with the xml controller, events and such, but still, 20 minutes from start to end.  I must say, i am impressed by how easy that was.  I will have to give this a ride in the future.  &lt;br /&gt;&lt;br /&gt;I sent &lt;a href="http://www.firemoss.com/"&gt;Joe Rinehart&lt;/a&gt; a note saying as much.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Model-Glue"&gt;ModelGlue&lt;/a&gt;, coming to a theater near you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-7683052368605795757?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7683052368605795757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7683052368605795757' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7683052368605795757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7683052368605795757'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/model-glue.html' title='Model Glue'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-8921913641660527108</id><published>2008-08-14T09:58:00.000-07:00</published><updated>2008-08-14T10:12:29.714-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oXmlHttp javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='GetHttpObject'/><title type='text'>AJAX - javascript little opps</title><content type='html'>I have been using a little AJAX technique in a couple places and was having two separate problems that i worked out.  &lt;br /&gt;&lt;br /&gt;First issue: i have 2 separate html divs that were being reloaded on the same page.  The problem i was having is the second call that was informing the second div on the page was sacking the first.  In other words, I had come like this calling two different jscript methods&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function loadQuestionsStandards(assessmentID,category,type,level){&lt;br /&gt; showStandards(category,type,level);&lt;br /&gt; showQuestions(assessmentID);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Each function showStandards() and showQuestions() contains code like this&lt;br /&gt;&lt;br /&gt;var url="views/filterQuestions.cfm?&amp;assessmentID=" + AID + "&amp;showAllQuestions=" + flag ;&lt;br /&gt; oXmlHttp=GetHttpObject(updateQuestionList);&lt;br /&gt; oXmlHttp.open("GET", url , true);&lt;br /&gt;&lt;br /&gt;where updateQuestionList is the name of a layer in the page called by the url var.&lt;br /&gt;&lt;br /&gt;The results of the second call to showQuestions was polulating both divs on the page.  Finally, i changed the true property to false in the first method call and it worked.&lt;br /&gt;&lt;br /&gt;In other words, the reload of the page only occured once, not twice and it correctly reloaded both layers.  I did not find any help around this problem in the blogshere.  &lt;br /&gt;&lt;br /&gt;The second problem only showed itself in our production environment.  Hmmmm, did not occur in our test or staging environments.  That remains a puzzle to me.  The problem was in the same line of code as the first problem.&lt;br /&gt;&lt;br /&gt;oXmlHttp.open("GET", url , true);&lt;br /&gt;&lt;br /&gt;When i was trying to solve the first problem, i changed the GET to POST for one of the functions and forgot to change it back.  Probably forgot because it did not make a difference until it made it way to production, where it failed gracefully.  I got a message back from the Jscript API, i presume, that said Length Required.&lt;br /&gt;&lt;br /&gt;I was able to trace the problem back to a specific function where i had made this GET to POST change.  &lt;br /&gt;&lt;br /&gt;Moral of the story? not sure, but both of these issued had to do with the &lt;br /&gt;&lt;br /&gt;oXmlHttp object.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-8921913641660527108?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/8921913641660527108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=8921913641660527108' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8921913641660527108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8921913641660527108'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/ajax-javascript-little-opps.html' title='AJAX - javascript little opps'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-1489250246377569764</id><published>2008-08-13T13:08:00.000-07:00</published><updated>2008-08-14T06:21:57.757-07:00</updated><title type='text'>CF Conversation</title><content type='html'>I listened to this &lt;a href="http://www.cfconversations.com/index.cfm/2008/7/23/009_Nick_Kwiatkowski"&gt;podcast &lt;/a&gt;today.  This interview highlighted a couple things that i have been into and out of in other blogs, podcasts about the CF community, perception of CF as a light weigh tool, frameworks etc.&lt;br /&gt;&lt;br /&gt;CF has come along way, especially with the last couple of releases that make CF much more object like.  I can see how CF has grown up over 10 years, from its initial release which really was alot like HTML with its tag based format.  It was easy to use and easy to create dynamic content.  CF excels at hiding much of the complexity of what it does in the tags.  This results in users being able to *just do their work.  In the past couple years, i have been working more in the architectural side of things than in the front, so i appreciate the emphasis on CFCs and OO techniques.  &lt;br /&gt;&lt;br /&gt;There is a perception that many of the CF developers, because of it ease of use, do not have the traditional CS type background and consequently are sloppy programmers who rely too much on frameworks.  An interesting point.  CF's own efficiency has spawned lots of programmers who otherwise may have never been programmers.  Folks who only dealt with static content, layout and design had access to programmatic tools that were once exclusive territory of programmers.&lt;br /&gt;&lt;br /&gt;There is the perception among programmers that the within the CF community, there is not enough emphasis or development integrating CF with other more mature back end solutions, like Java or PHP, for example.  Andrew Powell is a guy who has been working to bridge that gap. This is a good &lt;a href="http://www.adobe.com/devnet/coldfusion/articles/java.html"&gt;ADOBE sponsored article&lt;/a&gt; around this type of integration. If CF is to continue its acceptance into the *big players sphere, it must play better with other technologies. Matt Woodward posts a &lt;a href="http://www.mattwoodward.com/blog/index.cfm?event=showEntry&amp;entryId=0192F7BF-DF0D-1EDB-8F8708E69A9874F6"&gt;helpful article&lt;/a&gt; around Java integration.&lt;br /&gt;&lt;br /&gt;The discussion also talks about the proliferation of CF frameworks and despite the backing of the CF *elite, are overused and are a crutch to many CF programmers.  Is there a perception in the CF community that if you are not using a framework, you should be? Hal Helms and Simon Horwith have this &lt;a href="http://cfunited.com/blog/enclosures/026_death_match.mp3"&gt;debate &lt;/a&gt;about frameworks.&lt;br /&gt;&lt;br /&gt;The frameworks include, machii, coldBox, model glue, fusebox, coldSpring.  Each of these were mentioned.  There was a good discussion of trade offs and what that means.  &lt;br /&gt;&lt;br /&gt;For me, i started CFing without using any frameworks.  In a perfect world, CFers would have a change to program without any *overhead of a framework.  This aids in the understanding of variables, scopes, and other application wide settings and how the whole bootstrapping process occurs.  The frameworks hide many of these concepts and could create a programmer who does not really get some of the crucial concepts behind the code.  This could result in programmers who cannot program outside a given framework. I think the frameworks are very useful in some applications and perhaps a bit overkill in others.  The size of the app is a big factor.  I like the idea of a framework because it creates predictability in the application.  This is important for the future of the application and as new people come into it to support it.&lt;br /&gt;&lt;br /&gt;There was also some good discussion around the software life cycle.  A good reminder that we should do our heavy lifting before we start programming and that we should not start the development in the database.  FLIP was mentioned, since there was discussion of frameworks. I think i heard these numbers:&lt;br /&gt;&lt;br /&gt;50% time gathering requirements and prototyping&lt;br /&gt;30% implementing the prototype&lt;br /&gt;20% testing and documenting&lt;br /&gt;&lt;br /&gt;Was a mention that Flex has really become a popular prototyping tool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-1489250246377569764?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/1489250246377569764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=1489250246377569764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1489250246377569764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1489250246377569764'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/cf-conversation.html' title='CF Conversation'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7798000893170200202</id><published>2008-08-13T08:00:00.000-07:00</published><updated>2008-08-13T08:49:29.433-07:00</updated><title type='text'>ColdFusion Growing Up</title><content type='html'>I listened to a podcast today about something i have been reading in blogs a bit the past couple months.  Old news to some, but new to me and important to understand the larger picture.&lt;br /&gt;&lt;br /&gt;Once upon a time, ColdFusion was just a little player on the larger scene.  the Allaire brothers created the initial taging language way back in 98,99?  It is telling now that ColdFusion has 3 different rendering engines and a couple open source projects and is in discussion with educational groups for free liscensing and curriculum, to start offering as college curriculum.&lt;br /&gt;&lt;br /&gt;There are 3 different organizations that are offering a ColdFusion rendering engine.&lt;br /&gt;&lt;br /&gt;Adobe - with &lt;a href="http://www.adobe.com/products/coldfusion/"&gt;Coldfusion&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.newatlanta.com/products/bluedragon/index.cfm"&gt;Blue Dragon - new Atlanta&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.railo-technologies.com/en/index.cfm"&gt;Railo&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I was listening to &lt;a href="http://www.cfconversations.com/index.cfm/2008/7/28/CFConversations-10-Interview-6--Gert-Franz-of-Railo--072808"&gt;this podcast&lt;/a&gt; today where they discussed Railo in detail and the need to have a standard CF rendering engine, since there are now multiple players.  the idea of a CF core that was implemented by each engine with plugins or addons or lib functions or something like this to allow diff. additions by diff. engines.&lt;br /&gt;&lt;br /&gt;Its all good - the maturation of a platform like ColdFusion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-7798000893170200202?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7798000893170200202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7798000893170200202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7798000893170200202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7798000893170200202'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/coldfusion-growing-up.html' title='ColdFusion Growing Up'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-3285460200511518968</id><published>2008-08-13T06:37:00.000-07:00</published><updated>2008-08-13T06:57:21.143-07:00</updated><title type='text'>Refactoring Bus. Logic</title><content type='html'>The past couple weeks have had me back into old problems.  I had been in each of these holes before, but was back with new requirements.  As i looked at both of the functions in the CFCs, i found myself struggling to add the new requirements because the way the functions were defined was not intuitive.  In one case, i ended up refactoring the way the logic was working.  I should say i separated the logic into two different queries and then used a union to join the result set if needed.&lt;br /&gt;&lt;br /&gt;It took me a couple days of going into and out of this function before i was able to see the solution that i ended up using.  I was talking to another developer about this and concluded that we need to see things in our own model to understand them before we can enhance something.  I was temped at one time to create a new function and simply leave this one that way it was, but i fought that urge and eventually saw a cleaner way to solve the same problem.  Be a technician, bot a demolition man. I added a comment in the function to the effect that i hoped the next time someone traveled down this path into this function, that the bus. logic would be clear to them.  &lt;br /&gt;&lt;br /&gt;Good code to me means clear code, not necessarily fewer lines or clever, but clear to the next person who may be coming into the code to try to enhance it.&lt;br /&gt;&lt;br /&gt;The greatest threat to maintainable software?  Complexity!  Someone said that once.&lt;br /&gt;&lt;br /&gt;Moral to the story.  Be patience and if code smells, give yourself ample opportunity to re-factor the code in a way that does not smell, is easier to understand and enhance for the next Joe who comes along after you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-3285460200511518968?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/3285460200511518968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=3285460200511518968' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3285460200511518968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3285460200511518968'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/refactoring-bus-logic.html' title='Refactoring Bus. Logic'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-6757616443439507261</id><published>2008-08-13T05:40:00.000-07:00</published><updated>2008-08-13T06:37:47.193-07:00</updated><title type='text'>Blogs and Podcasts</title><content type='html'>As a developer, there are many ways to approach solving the problems that you encounter.  One of the primary points i am making is where do we find inspiration and ideas for how to solve things.  I have been making alot of rounds lately in the blog sphere. I cannot stress enough how much outstanding fodder is available in peoples blogs.  Someone, Brian Hegeman, once encouraged me to use the blog sphere to find answers to questions but more than that to stretch my understanding of the bigger picture.  I was not ready at that time, probably because i was too busy just trying to understand the code base i was working on, supporting ect.  I was fortune enough to work with a couple guys who were very talented programmers/architects.  There was much for me to learn.  &lt;br /&gt;&lt;br /&gt;I made a decision after the cf-objective conference this year to spend more time stretching my brain with other peoples perspectives and ideas.  Over the past 3 months I have been almost daily going to blogs not looking for a specific answer to a problem, but just to listen in on some conversations.  I also joined a couple specific groups, where the conversation is specific about a framework, machII and a model layer manager called ColdSpring.  These are specific frameworks that the main application i support uses. As part of this blogging experience, i have created a public space trying to share the learning and organize some of the blogs i have visited.  &lt;br /&gt;&lt;br /&gt;I have found myself also listening to a few podcasts.  Some people may prefer to read, but the podcasts are very useful and pretty focused on relevant topics for the ColdFusion developer.  I have found that a couple different CF related podcasts have been around for a few years.  &lt;a href="http://helmsandpeters.com"&gt;Hal helms and Jeff Peters&lt;/a&gt; have been doing one for awhile as have &lt;a href="http://www.coldfusionpodcast.com/"&gt;Bryan Kaiser and Michael Kaynie&lt;/a&gt;. This format starts out discussing relevant CF related news, then typically has someone interviewed.  In 2006 Matt WoodWard and Peter Ferrel of machii and CF fame started a podcast called &lt;a href="http://www.coldfusionweekly.com/"&gt;ColdFusion Weekly.&lt;/a&gt;.  The ColdFusion weekly has recently stopped creating new podcasts but a couple others have just began.  &lt;a href="http://www.cfconversations.com/"&gt;CF conversations&lt;/a&gt; is more of a round-table interview format.&lt;br /&gt;&lt;br /&gt;Here is a short list of topics that i have been plugging into the past couple weeks in various blogs and podcasts.&lt;br /&gt;&lt;br /&gt;SQL injection and protection&lt;br /&gt;Marketing CF&lt;br /&gt;Creating more CF developers by giving CF away to educational institutions (ADOBE)&lt;br /&gt;Creating an official curriculum for Universities to adopt&lt;br /&gt;CFAJAX, built in ajax tags for CF8&lt;br /&gt;Krugle.com - code search engine&lt;br /&gt;FLEX -vs- AJAX debate&lt;br /&gt;Framework or no-framework debate&lt;br /&gt;Flex as the view layer, CF as the model layer, machii or model glue as controller&lt;br /&gt;&lt;br /&gt;If you wanna be a developer, then pull your head out of the hole and embrace the blog sphere that has so much to offer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-6757616443439507261?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/6757616443439507261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=6757616443439507261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6757616443439507261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6757616443439507261'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/08/bus-logic-and-multiple-trips-throught.html' title='Blogs and Podcasts'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7672850707939019772</id><published>2008-07-29T13:15:00.003-07:00</published><updated>2008-07-29T13:41:00.646-07:00</updated><title type='text'>AJAX mussings</title><content type='html'>Today, I spent the better part of the day following a path i had previously blazed, AJAXing.  I was looking at a specific request that my user made regarding a form that needed a little new functionality.  I knew i had used AJAX techniques previously.  This is a form with a lot of filtering option and a lot of data, idea for AJAX or asynchronous communication.  This form needs to be able to make requests and have the data update without having to load the entire form or page again.  I am also maintaining a lot of state in the page, so keeping previous selection is important.  &lt;br /&gt;&lt;br /&gt;It took me awhile to get my head back around how the AJAX was working, which told me i had not really internalized it that well, so here goes a little blogging on how it works, at least how i am using it.&lt;br /&gt;&lt;br /&gt;I have a container.cfm page that has html controls in it.  The controls i am using are select lists and radio buttons.  I have javascript method calls i am making on the clicking of these controls, also on the loading of the page, to handle initial state.  The controls call the jscript method and pass a parameter or two.  The jscript method used some fancy schmancy script reload a portion of the page, which includes a call to the server (db) via a oXmlHttp request.  That code looks like this&lt;br /&gt;&lt;br /&gt;function showQuestionsForItemMapping(AID, flag){&lt;br /&gt; //alert('in ' + AID + flag);&lt;br /&gt; var url="views/filterQuestions.cfm?&amp;assessmentID=" + AID + "&amp;onlyNotMapped=" + flag ;&lt;br /&gt; //alert(url);&lt;br /&gt; oXmlHttp=GetHttpObject(stateChangedQuestions);&lt;br /&gt; oXmlHttp.open("GET", url , true);&lt;br /&gt; oXmlHttp.send(null);&lt;br /&gt;}&lt;br /&gt;function stateChangedQuestions(){&lt;br /&gt; if (oXmlHttp.readyState==4 || oXmlHttp.readyState=="complete"){&lt;br /&gt;    document.getElementById("questionsToMap").innerHTML=oXmlHttp.responseText;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In the example, the jscript method showQuestionsForItemMapping() is called from a container.cfm page that has a &lt;div&gt;&lt;/div&gt; named questionsToMap, which is where the results of the page processing display.  Notice the file &lt;span style="font-style:italic;"&gt;views/filterQuestions.cfm&lt;/span&gt; is called and processes with new parameters passed in from the container file.  The URL, which is set to the filerQuestion.cfm page is reloaded via the cool oXmlHttp.open line and then the stateChangedQuestions() method is called and the questionsToMap div is repopulated.  Sweet stuff - a little more complex than if you are reloading the entire page with an http request or reloading the entire event in a machii framework, but worth the responsiveness improvement.&lt;br /&gt;&lt;br /&gt;There is lots of sample AJAX like code avail, but the key thing to get is that you can access the back end of your application and get refreshed query data without reloading the entire page.  This results in a significant improvement in the responsiveness of the form.&lt;br /&gt;&lt;br /&gt;I had to draw a picture on a piece of paper earlier this am when i was struggling to get my head back around this.  I ended up drawing something like a container with a couple div tags included in each.  With arrows indicating that the div tag include stuff was populated with the container and its link off to an external jscript file.&lt;br /&gt;&lt;br /&gt;This also helped me to understand better the nature of asynchronous call -vs- a synchronous call.  Flex too uses the asynchronous model with ActionScript rather than javascript to communicate with the server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-7672850707939019772?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7672850707939019772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7672850707939019772' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7672850707939019772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7672850707939019772'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/07/ajax-mussings.html' title='AJAX mussings'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-4081139489427530999</id><published>2008-07-28T13:27:00.000-07:00</published><updated>2008-07-29T06:42:35.666-07:00</updated><title type='text'>Refactoring MVC</title><content type='html'>I am continuing work refactoring a fairly large amount of code.  Initially, i added ColdSpring to manage the model objects relationships, dependencies etc.  As i moved toward completion of this work, i started looking more closely at a couple of the DAOs and Gateways that i had rewired.  I noticed a bit of code left over from the initial incarnations of these components.  These components have been around a long time and are used in the *main application differently than in this *sub application.  I thought it a good idea to create a components and store them within the model path of the sub application, rather than in a more generic /org. path.  I copied the components from the /org. path, rewired their init() methods, actually removed them since ColdSpring is now managing them, and removed a good deal of the existing functions that were needed in the main app but not the sub app, and added a couple new methods that were previously in a cfm that i was including.  I could have continued to add more methods to the existing old bloated cfcs in the /org path, but decided for a clean break.  As i was refactoring today, it felt like the right decision. &lt;br /&gt;&lt;br /&gt;I have a couple view pages that are using AJAX techniques, so the event context or que is not reloading - so i had the lookup code in a cfm file.  I moved that code into the respective Gateways (one for item mapping, the other for assessment questions).  I added methods to their respective services and called the services from the view page, using the object pointer provided by the ColdSpring framework. &lt;br /&gt;&lt;br /&gt;I need to figure out how to direct the AJAX calls via the machii framework - so i could use the listeners to get the updated request sets.  I don't think this is possible, since we are not and do not want to reload the entire event framework on each of the requests - thats the gain provided by AJAX.  So, i use the ColdSpring provided pointer and call the service directly from the view page without reloading the event que. This is still not perfect, but moves the SQL back into the gateway where it belongs and allows me to reuse that code if i swap out the current view with another, say a swf.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-4081139489427530999?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/4081139489427530999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=4081139489427530999' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/4081139489427530999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/4081139489427530999'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/07/refactoring-mvc.html' title='Refactoring MVC'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-2105147141098954213</id><published>2008-07-23T13:10:00.000-07:00</published><updated>2008-07-23T13:42:47.657-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='machii OO design'/><title type='text'>I stumbled across a blog today...</title><content type='html'>Written by a former co-worker.  Turns out he wrote the blog application using machii.  As i dug down into the application, i was pleased to see so many best practices in play.  Just a few:&lt;br /&gt;&lt;br /&gt;the application uses filers and plugins wisely, uses event-args in view pages, this creates a single point of edit - so we always know where to find variables defined in view pages in the event that is including the event.&lt;br /&gt;&lt;br /&gt;view, controller(s) tightly coupled, along with the plugin and filter CFCs - they are part of the application.  &lt;br /&gt;&lt;br /&gt;A sub application to handle administration duties.&lt;br /&gt;&lt;br /&gt;The model layer contains the listeners, which i prefer to store in a separate physical folder - since they are part of the application, not part of the model.  The *entities modeled in the application are organized by entity folder with a bean, manager (i would have used service) DAO and Gateway in each folder.  One of the entity folders did not contain a bean, so the developer was not blindly following the 4:1 design pattern, thats a good thing.  He could have had combined service or manager responsibility for a couple of the entity managers.  They are similar and both are a little light.&lt;br /&gt;&lt;br /&gt;The listeners seem to be only passing control along to its respective manager, while the managers are instantiating their dependent DAO and Gateway objects.  There is no ColdSpring or other model manager at play.  As a consequence, the collaborating components have knowledge of each other sprinkled in to each other.  Listeners are instantiating managers, managers instantiating DAOs, Gateways and other managers.&lt;br /&gt;&lt;br /&gt;Listeners are referencing controller properties to pass along as args to managers.  If a model manager was in play, it would be doing this, promoting lesser coupling between the listener and manager (application and model).&lt;br /&gt;&lt;br /&gt;Objects treated as objects, passing by reference.  The DAO is passed in a reference to its bean and uses it when updating the database.&lt;br /&gt;&lt;br /&gt;Filters with configure methods, like listeners, they use configure not init for initialization and reference controller properties, since the filters, plugins and listeners are all registered in the controller - they all can access the properties.  One difference is listeners extend listeners, filters extend filters and plugins extend plugins, all different parts of the machii framework.  Remember to think of the plugins as cross cutting - or needed across all events in the application.  In the plugin configure method, there is a UDF object created that is called in the pre-process of each event to get a tick count - what a geek.  Interesting too that the developer stored the UDF.cfc with the views?  &lt;br /&gt;&lt;br /&gt;Remember each non-correlation table *should have its own bean to represent a record from the table when that record is in play.  That bean should contain its own validation logic, avoiding the lean bean syndrome.  A gateway to aggregate larger number of records from the table and a manager to handle requests of the bean, DAO or gateway.&lt;br /&gt;&lt;br /&gt;In summary, lots of abstraction and encapsulation - promoting reuse and ease of maintenance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-2105147141098954213?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/2105147141098954213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=2105147141098954213' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2105147141098954213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2105147141098954213'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/07/i-stumbled-across-blog-today.html' title='I stumbled across a blog today...'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-3494782727960946267</id><published>2008-07-16T10:41:00.000-07:00</published><updated>2008-07-17T13:22:53.201-07:00</updated><title type='text'>ColdSpring OO design refactoring</title><content type='html'>Today, i begin a minor - major rework of a piece of software that i created about a year ago.  The primary areas where i intend to do this work is in the model layer of the application.  I plan to re-factor code by moving bus. logic further down stream into the bus object bean.  I actually need to use that too, i am not really using the bean to do the CRUD work.&lt;br /&gt;&lt;br /&gt;I plan to use ColdSpring to create the bus object, the service and its dependencies and to tweak the controller to use the service where necessary.  I will tweak the service to utilize the CRUD methods in a more pure OO implementation.  This means passing around the reference to the bus object and using it when performing the CRUD operations.  The refactoring in the service, DAO and Gateway will include removing init methods, since ColdSpring will be handling the creation, initialization and dependencies.  As a result, the knowledge of the collaborating entities will be lifted from the collaborators and placed in an abstract container, ColdSpring.  This again promotes reuse of the tighly cohesive objects with little coupling.  The coupling is abstracted away.&lt;br /&gt;&lt;br /&gt;The results of this refactoring will not be evident on the user side, there will not be any changes to the GUI, probably a bit to the API, but the actual changes to the application front end will come later.  &lt;br /&gt;&lt;br /&gt;I will check back in with progress later.&lt;br /&gt;&lt;br /&gt;Hi level steps:&lt;br /&gt;&lt;br /&gt;1 - create a new services configuration file in the sub app for the objects to be created and managed in the assessments subapp.&lt;br /&gt;&lt;br /&gt;2 - plug coldspring into the machii controller&lt;br /&gt;&lt;br /&gt;3 - point the plugin at the services file&lt;br /&gt;&lt;br /&gt;4 - add the objects to the services file&lt;br /&gt;&lt;br /&gt;5 - modify the objects added to the services file, removing the knowledge of each other, remove the init methods.  Create setter methods in services, so dependency injection references will work!  Remember to name the setter method the same as the injecting method, like setBeanName.  For objects that have init() methods left, DAOs, Gateways, Utils, if instantiating from CS, pass in required parameters using CS provided tool, $varname.  For now, i decided to not require the parameter and gave it a default value, this way, i can simply add the parameter in the CS container at any point and it will just work!&lt;br /&gt;&lt;br /&gt;b - other things i needed to clean up in prepping objects for CS and OO purity included; removing extends from two of the objects, these are old from years ago, i copied into my application space and noticed they were extending listeners, opps - i noticed a bunch of extra methods after i had created and dumped the bean, when i looked more closely, i noticed that the objects (assessmentDAO, assessmentGateway) where extending the listners - that was a mistake and highlights the fact that these two objects have sat out in space and not be used.  One of the objects was not returning itself either.&lt;br /&gt;&lt;br /&gt;6 - I currently have the bootstrapping code in the index.cfm file in the root of the sub-application.  I wanted to follow the best practice from CF objective machii training where we would use Application.cfc and load all the bootstrapper code in it, and leave a empty index.cfm file.  I tried that and had problems, and was not willing to look further into it.&lt;br /&gt;&lt;br /&gt;7 - I also spend time in the listeners, removing object creation code from the configure method.  Im still not totally clear what the best practices are for referencing bootstrapper variables created pointing to the coldspring created objects from within the machii listeners.  I am currently using variables.amanager = application.CSBeanFactory.getBean("beanName");.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-3494782727960946267?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/3494782727960946267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=3494782727960946267' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3494782727960946267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3494782727960946267'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/07/coldspring-oo-design-refactoring.html' title='ColdSpring OO design refactoring'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-2071289553107765490</id><published>2008-07-09T09:36:00.000-07:00</published><updated>2008-07-09T11:01:45.157-07:00</updated><title type='text'>Java Coldfusion Spring Coldspring</title><content type='html'>I was reading Brian Kotek blog today and came across posting about CF objective - in his post he mentioned Andy Powell session about using a Java Model and a CF controller and view.  I just happened to listen to the podcast on this the other day, it was a CF weekly podcast from 2008 with Andy, Matt and Peter.  The valuable grok?&lt;br /&gt;&lt;br /&gt;Coldfusion and Java are becoming more and more interchangeable - not competing, eachother, but integrating better.  CF is still the faster way to go from a-z and has better integration with stuff like Flex and other tools.&lt;br /&gt;&lt;br /&gt;CF has frameworks specific to it, like machii, Coldspring, Transfer. &lt;br /&gt;&lt;br /&gt;Java has frameworks too, lots of them, notably, struts, Ruby, Spring.&lt;br /&gt;&lt;br /&gt;CF = ColdSpring to manage model&lt;br /&gt;Java = Spring to manage model&lt;br /&gt;&lt;br /&gt;Another interesting point from Joe Rinehart regarding coldfusion, java, html and flex.&lt;br /&gt;&lt;br /&gt;"As I've been moving away from doing HTML UI's, my perspective on CF has changed a good deal. While I think ColdFusion is top-notch for doing HTML UIs and the whole view/controller side of the equation, modeling applications in CFCs has become both a hassle (typing them kills me now that I'm used to other languages) and a liability (they're _still_ not terribly performant in comparison to raw Java, where I can still go dynamic via Groovy). Because a good deal of my work is now in Flex, I have less and less of a reason to use ColdFusion unless I need to render HTML - at which point it's simply the best tool for the job and definitely worth its price a few times over."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-2071289553107765490?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/2071289553107765490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=2071289553107765490' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2071289553107765490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2071289553107765490'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/07/java-coldfusion-spring-coldspring.html' title='Java Coldfusion Spring Coldspring'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-3524809756118779409</id><published>2008-07-09T07:15:00.000-07:00</published><updated>2008-07-09T07:36:04.082-07:00</updated><title type='text'>ORM transfer</title><content type='html'>I'm reading a post by &lt;a href="http://www.briankotek.com/blog/"&gt;Brian Kotek&lt;/a&gt; today and came across a link to another blog about ORM.  I have been hearing about ORMs for a long time, i recall when Tracy Logan, a former co-worked and extremely talented programmer, brought this up a couple years ago.  Something about Transfer automatically generating cfcs for you and basic SQL.  My initial reaction was defensive "why would i want a program that does my job for me? - thats my job".  I suspect that is a typical reaction when one does not really understand something, disparage it since you do not understand it.  Anyway, I have heard other coldfusion developers talking about ORMs in the past but it has remained to me an abstract concept.  &lt;br /&gt;&lt;br /&gt;Today, when i when to this &lt;a href="http://docs.transfer-orm.com/wiki/Overview.cfm"&gt;Transfer ORM site&lt;/a&gt;, i was ready to listen.  The high level statement about developing OO web applications was very succinct.&lt;br /&gt;&lt;br /&gt;"When developing an Object Oriented web based application, it is normal to have a database with relational tables and a series of objects that represent that data."&lt;br /&gt;&lt;br /&gt;First off, i did not know that Transfer was written for ColdFusion, i learned that ORM means "Object Relational Mappers".  It may be that until now, my OO skills where lacking and i was not ready to see this for what it is.  It may also be that i am currently not doing much new development, most is refactoring. I will take the same approach i have regarding OO design, machii, coldspring, design patterns - slow and in small bits.  I think too that once you have *struggled with CFC plumbing in DAOs and Gateways and experienced enough create, edit, delete, read method writing including the tedious SQL then you are ready to see this type of tool as an asset.&lt;br /&gt;&lt;br /&gt;Just the intangible gain of having worked with an ORM is valuable. There is always something to glean when trying new technologies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-3524809756118779409?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/3524809756118779409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=3524809756118779409' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3524809756118779409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3524809756118779409'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/07/orm-transfer.html' title='ORM transfer'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7725414149814302387</id><published>2008-07-08T11:15:00.000-07:00</published><updated>2008-07-08T11:49:22.556-07:00</updated><title type='text'>Refactoring, OO design, abstraction</title><content type='html'>I came across a &lt;a href="http://www.silverwareconsulting.com/index.cfm/2008/6/23/How-I-Use-Transfer--Part-I--Introduction"&gt;blog &lt;/a&gt;today that informed my understanding a bit...here is the &lt;br /&gt;&lt;br /&gt;The author speaks of good OO principles regarding model design.  He specifies 4 layers or tiers, with the service tier as the primary that the controller speaks to.  He talked about the problem that occurs when one dogmatically applies the 4:1 ratio, a service, bus. object, DAO and gateway for every entity in the model.  This is what Sean Corfield also said to me about avoiding the anti - pattern.  &lt;br /&gt;&lt;br /&gt;Its real hard to see this at first, when you are simply trying to get your head around why you need all these tiers and specialized objects in the first place.  Eventually, this stuff begins to sink in and you state to see the beauty of the OO designed model, then you can start to consider that sometimes you don't need a specific service for each bus. entity.  In fact, you probably do not and a single service could serve like minded objects.  This could also be true around DAO's and Gateways.  Use the 4:1 approach as a guideline, not a dogmatic rule.&lt;br /&gt;&lt;br /&gt;I read a good Hal Helms &lt;a href="http://coldfusion.sys-con.com/read/45978.htm"&gt;article &lt;/a&gt;yesterday about the workings of an OO designed model and how its really a bunch of little encapsulated objects collaborating with each other as needed to get the work done.  Think of an ant hill and how each ant has its own special little thing it does, when looking at it from ground level, its very intimidating, trying to figure out who is doing what, but lift up a few feet, take a more global view and you can see the entire orchestra of work.&lt;br /&gt;&lt;br /&gt;Another good point was the refactoring that occurs as you work through a model over time.  He describes his experience this way, I started seeing logic in my controller that belonged in the model, so i would move it into the service layer.  Then i would see the logic in the service layer really belonging to the bus. object, so i would move it into there.  His definition of refactoring then sounded like pushing logic further downstream, where it belonged creating rich bus. objects that took care of themselves and leaner service entities that took care of calling other objects and directing traffic with a smaller amount of bus. logic.  Its totally legit to have bus. logic in the service, since the service is part of the model layer, while listeners in frameworks should not have bus. logic, since they are part of the application, but alot of that logic really should be in the bus. objects.&lt;br /&gt;&lt;br /&gt;Then he went on to talk about the abstraction of the service layer into a base or super service object that could handle calls to like methods across similar services.  This is applying the principle of if its the same, then pull it out of the two places and put into a single place and use it as a base.  This abstract service would then be extended by the concrete services with the ability to override the base method if needed.  This is good, but does add a bit more complexity in the base class.   &lt;br /&gt;&lt;br /&gt;I also listed to a &lt;a href="http://media.libsyn.com/media/coldfusionweekly/cfweekly_3.08_final.mp3"&gt;podcast &lt;/a&gt;today about CF and Java working together, which reminded me that CF is still not a pure OO language, its like an OO language, this technique of basing and extending is very much a core OO principle.&lt;br /&gt;&lt;br /&gt;Finally, the author discussed the use of ORMs like transfer to automate the creation of the bus. objects - relieving the pain of having to do the plumbing of each of those objects.  This reminded me of previous readings about programs like reactor that would do a reverse engineering and read the database and create sub. object stubs for tables int he DB., hopefully skipping over association tables.  This stubbing likely includes an init method that sets the tables cols to some value and creates getter and setter methods for each.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-7725414149814302387?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7725414149814302387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7725414149814302387' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7725414149814302387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7725414149814302387'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/07/refactoring-oo-design-abstraction.html' title='Refactoring, OO design, abstraction'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-3117381958567468934</id><published>2008-07-07T10:45:00.000-07:00</published><updated>2008-07-07T11:15:35.871-07:00</updated><title type='text'>Problem solving Coldspring</title><content type='html'>I had been experiencing a little problem with my ColdSpring code.  It took me three attempts to see what the problem was. I had been coldspringing a couple services in our main application, meaning i was removing the object creation code from the services, and placing in the ColdSpring container.  The trend chart has a service, DAO and Gateway object.  The trend chart also uses questions from assessment exams - the question object has its own service, bean, DAO, and Gateway.  The trend chart service has a dependency on all three of these other objects or collaborators, trendDAO, trendGateway and QuestionService.  &lt;br /&gt;&lt;br /&gt;I first created the 'beans' for the question then for the trend chart.  Then i wired up the questionService with a reference to the questionGateway and the trendService with the trendDAO, trendGateway and questionService. &lt;br /&gt;&lt;br /&gt;Once the wiring was done, i went about setting up the service objects to allow them to be &lt;span style="font-weight:bold;"&gt;injected &lt;/span&gt;.  Starting with the questionService, i added a setQuestionGateway method - thats the object that the questionService is dependent upon and the services file is trying to inject during the questionService creation.  Then i added three setter methods to the trendService, setTrendDAO, setTrendGateway and setQuestionService - these three dependent objects are injected when the trendService is created.&lt;br /&gt;&lt;br /&gt;Once this was completed, i was getting an annoying init() method error in my trendService object upon creation...hmmmm.  I looked at this over a couple days, tried messing with the services file definition and with the depend objects but to no avail.  After my vacation, i opened the offending trendService file and almost immediatly saw that my service was extending a the listener class.  Opps! - The service does not extend a listner class, its not a listener.  Once i removed that, it exposed another small error, which was a pathing problem to one of the dependent cfcs.  Now thats its cleared up, its so obvious and reminds me to not be careless with cutting and pasting and typing.&lt;br /&gt;&lt;br /&gt;Finally, once the wiring was working, i removed the init() method from both of the service objects, i had commented them out during this phase - since all the initialization is not handled by ColdSpring.  Thats the payoff - there is less coupling and knowledge sprinkling between the collaborators.  &lt;br /&gt;&lt;br /&gt;Moving on to ColdSpring ize more objects....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-3117381958567468934?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/3117381958567468934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=3117381958567468934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3117381958567468934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3117381958567468934'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/07/problem-solving-coldspring.html' title='Problem solving Coldspring'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7790820869958791400</id><published>2008-06-23T07:57:00.001-07:00</published><updated>2008-06-23T08:14:35.247-07:00</updated><title type='text'>programming problem solving</title><content type='html'>I have been working on my little developers application, with the intention of implementing pure OO techniques and coldSpring.  I am also implementing machii framework version1.6.  I will start to exploit the new machii features later in this process.  For now, its more about proper modeling of classes or components.  Keeping things where they belong. I mean keeping the model layer agnostic of the application that is using it, keeping bus logic in the service or model layer.  Keeping validation logic in the beans, avoiding anemic bean syndrome.  &lt;br /&gt;&lt;br /&gt;Initially, i put the object creation code in the service for its dependent dao and gateway objects, got that working, then plugged coldSpring into the machii framework,  ensured that was ok by creating the pointer object into the coldSpring bean factory (the CS black box).  Once that worked, i added the acual bean creation code to the services.xml file (thats the one cs consumes to read your component definitions.  I defined the service, DAO and Gateway components in the services xml file, with the DOA and Gateway as ref. objects within the services object.  I then added the setxxx methods to the service object and finally removed the code from the init method in the service.&lt;br /&gt;&lt;br /&gt;Once that was working, yea! I ran across a blog where someone mentioned creating a utility debugger and using it to dump from within a cfscript block.  I probably read something like this before, but i was not ready to grok it.  Now, i groked it.  I set up a utility cfc and registered it in the coldSpring container (services.xml) and referenced it from the bootstrapper object, Application.cfc.  I created a application  scope on it, so i could reference it from any objects in the model.  Ive used it a couple times already, and find it very useful.  Brilliant!&lt;br /&gt;&lt;br /&gt;Think of coldSpring as an attachment to the model layer.  At application start, there has to be some instruction that says reference and scope the beans that are defined by the coldSpring framework in the services.xml file.  This does create a thin layer of coupling between the application and the model layer, but its contained to a single bootstrapper object that has the knowledge of the coldspring framework.&lt;br /&gt;&lt;br /&gt;Think abstraction.  The more abstraction, the better.  Abstraction = less knowledge of the collaborating entities.  There will always be some coupling, but it is favored to reduce that coupling to its purest form.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-7790820869958791400?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7790820869958791400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7790820869958791400' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7790820869958791400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7790820869958791400'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/programming-problem-solving.html' title='programming problem solving'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-6950452022081610196</id><published>2008-06-17T11:59:00.000-07:00</published><updated>2008-06-17T13:38:08.169-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='objects reference value framework'/><title type='text'>framework OO design debugging</title><content type='html'>I got my developer app working today.  This is my new app. that is utilizing pure OO techniques.  It is still a shift for me, as i struggle, i see this more. Think in terms of objects, encapsulated objects, that contain their own data.  Pass around a reference to this object, rather than passing along pieces of data by value.  How does the object serve the application?  Does the object know anything about what application is using it (lets hope not).  Let the object take care of itself, keeping its own state and not reaching out to other objects (loosely coupled).&lt;br /&gt;&lt;br /&gt;Its not ok to create just tiered applications anymore.  I am thinking now more about objects and their state, relationships and bus. logic (which object should it belong, bean, service, DAO/Gateway) and even if i need a bean or service for an object.  Could the entity be served by an existing object.  I *should have less services than actual beans, as the application progresses.  Its ok to start with the 4:1 (entity in your domain has bean, service, DAO, Gateway) - but this is a guide,not a rule!  As Sean Corfield said, dont create an anti- pattern.  &lt;br /&gt;&lt;br /&gt;Anther problem i was running intois the mach-ii framework masking the errors (that i created first in my listener, then in my service, then in my DAO).  The experience of stepping through the event flow is always valuable, but the framework was not helping by reporting a very unhelpful message.  Is the framework really to blame for masking my mistakes?  I think without a framework, i would have at least had a better path to follow regarding where CF was failing (in the listener, service, DAO/Gateway or somewhere else.&lt;br /&gt;&lt;br /&gt;Anyway, i have worked my way through the problem.  I have a listener that is handing off to a service.  The service method requires a struct(listener passing in event.getArgs() ), takes the arguments passed in and calls a private method in the service that instantiates a new object and used the setter methods on that object to update with the arguments passed in from the listener. When the private method is complete creating and updating the object, it passes it back to the main method, who then calls the DAO to it its work.  The resulting object reference passed back by the helper method is used as an arg to the DAO.  Passing by reference, not value.&lt;br /&gt;&lt;br /&gt;This is a big leap for me.  I am not passing around a bunch of data, but rather an object reference that is resp. for keeping its own data.  Object = encapsulation of its own methods AND its own data.&lt;br /&gt;&lt;br /&gt;Im still not sure if my service is real smart, but i am passing by reference now.  In my DAO create method, i will keep the validation logic around the actual SQL insert.  This is keeping with the fat bus. ready object (non anemic).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-6950452022081610196?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/6950452022081610196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=6950452022081610196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6950452022081610196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6950452022081610196'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/framework-oo-design-debugging.html' title='framework OO design debugging'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-8124504374115239867</id><published>2008-06-14T06:32:00.000-07:00</published><updated>2008-06-14T07:28:02.999-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='patterns design'/><title type='text'>Design Patters (official)</title><content type='html'>Gleaning from Sean Corfield &lt;a href="http://corfield.org/articles/DesignPatterns.pdf"&gt;presentation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Pattern: Composite View&lt;br /&gt;A composite view is a view that includes other views&lt;br /&gt;&lt;br /&gt;Patterns have four parts:&lt;br /&gt;• Name - the common vocabulary&lt;br /&gt;• Problem - “forces” that determine when the&lt;br /&gt;pattern is applicable&lt;br /&gt;• Solution - a template for solving the problem&lt;br /&gt;• Consequences - “pros and cons”&lt;br /&gt;&lt;br /&gt;APPLICATION / onApplicationStart()&lt;br /&gt;is a singleton pattern (once entity accessible from one place)&lt;br /&gt;&lt;br /&gt;problem (trade off) is breaks encapsulation when object x needs to reference some application scoped variable.  A solution is to use something like CS, that injects object X at instantion with the application scoped variable (which is no longer application scoped at this point).&lt;br /&gt;&lt;br /&gt;A common problem&lt;br /&gt;&lt;br /&gt;I have components that make up my user&lt;br /&gt;security logic but I don't want to expose them to&lt;br /&gt;other code, in case I want to change how its implemented.&lt;br /&gt;&lt;br /&gt;Create a new component that has a simple&lt;br /&gt;API that calls the security components.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Think in terms of trade / offs (pros and cons) a pattern has both!&lt;/span&gt; For example&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Application code no longer needs to know about the&lt;br /&gt;internals of your security system (+)&lt;br /&gt;&lt;br /&gt;Application code can still get at the “low-level”&lt;br /&gt;components if it needs to (+/-)&lt;br /&gt;&lt;br /&gt;Some redundancy of methods between the API and&lt;br /&gt;the underlying components (-)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Pattern - Facade ( common very helpful)&lt;/span&gt;&lt;br /&gt;Problem - as a subsystem grows, it becomes more&lt;br /&gt;complex with a large number of smaller objects&lt;br /&gt;&lt;br /&gt;Solution - introduce a single component that&lt;br /&gt;provides a simple API to the set of components&lt;br /&gt;within the subsystem&lt;br /&gt;&lt;br /&gt;Consequences - shields clients from the inside of the&lt;br /&gt;subsystem, reducing complexity and coupling; does&lt;br /&gt;not prevent access to subsystem if needed&lt;br /&gt;&lt;br /&gt;Often only one instance of a facade is needed(singleton)&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Pattern Name: Front Controller&lt;/span&gt; - like fusebox or machii or global index, each of these frameworks is a front controller pattern.&lt;br /&gt;&lt;br /&gt;Problem - need to apply consistent logic across all&lt;br /&gt;requests in an application (security, layout etc)&lt;br /&gt;&lt;br /&gt;Solution - route all requests through a single file that&lt;br /&gt;decides how to process the request&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Singleton and Facade&lt;/span&gt; refer to objects, most design patterns are focused on OO design&lt;br /&gt;&lt;br /&gt;Consequences - centralized control, easy to change&lt;br /&gt;how requests are handled in a consistent manner,&lt;br /&gt;moves logic out of individual pages into controller&lt;br /&gt;(which can become complex)&lt;br /&gt;&lt;br /&gt;cfinterface specifies the methods a component provides (API) but not how they behave. cfcomponent *implements* the interface to specify the behavior. An interface can have many implementations. But duck typing is more powerful and appropriate for&lt;br /&gt;ColdFusion - onMissingMethod() lets you implement any methods dynamically.&lt;br /&gt;&lt;br /&gt;-- Sean Corfield&lt;br /&gt;&lt;br /&gt;However, this is starting at the wrong end. When you&lt;br /&gt;learn patterns by focusing on the solutions they&lt;br /&gt;present, it makes it hard to determine the situations in&lt;br /&gt;which a pattern applies. This only tells us what to do&lt;br /&gt;but not when to use it or why to do it.”&lt;br /&gt;-- Alan Shalloway&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Creational patterns&lt;/span&gt;&lt;br /&gt;Abstract Factory, Builder, Factory Method,&lt;br /&gt;Prototype, Singleton&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Structural patterns&lt;/span&gt;&lt;br /&gt;Adapter, Bridge, Composite, Decorator, Facade,&lt;br /&gt;Flyweight, Proxy&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Behavioral patterns&lt;/span&gt;&lt;br /&gt;Chain of Responsibility, Command, Interpreter,&lt;br /&gt;Iterator, Mediator, Memento, Observer, State,&lt;br /&gt;Strategy, Template Method, Visitor&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Frameworks&lt;/span&gt; are designed to solve common problems&lt;br /&gt;• Application frameworks usually implement several patterns&lt;br /&gt;• Front Controller - everything goes through index.cfm&lt;br /&gt;• Model-View-Controller - segregation of the presentation and&lt;br /&gt;business tiers&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ColdSpring&lt;/span&gt;&lt;br /&gt;• Chain of Responsibility - each “aspect” calls methods on the next&lt;br /&gt;“aspect” until the underlying business object is reached&lt;br /&gt;• Identity Map - cache of objects accessed by “id” (bean name)&lt;br /&gt;• Proxy - same API as your business objects but intercepts method&lt;br /&gt;calls to execute before, after or around “advice”&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-8124504374115239867?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/8124504374115239867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=8124504374115239867' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8124504374115239867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8124504374115239867'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/design-patters-official.html' title='Design Patters (official)'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-8261401955090032970</id><published>2008-06-13T10:53:00.000-07:00</published><updated>2008-06-13T11:13:20.384-07:00</updated><title type='text'>MachII 1.5</title><content type='html'>When we upgrade our machii framework code to version 1.5 (released a year ago) there are several changes to note.&lt;br /&gt;&lt;br /&gt;First, our existing code should not be effected.  Although when i tried this briefly a couple weeks ago, i had a problem with one of the application controllers that was using a .dot notation in the event names.  For example; in one of our sub-app controllers, most of the event names look like this;&lt;br /&gt;&lt;br /&gt;event-handler event="somename.somethingelse.somethingelse" access="..."/&lt;br /&gt;&lt;br /&gt;I have posted this question in the machii google group to see if any known problems with this notation exist.&lt;br /&gt;&lt;br /&gt;Also, i have been running across the concept of a "bootstrapper" file or process in a number of blogs recently.  The &lt;a href="http://greatbiztoolsllc-trac.cvsdude.com/mach-ii/ticket/5"&gt;bootstrapper &lt;/a&gt;is the start-up routine or file that is responsible for doing application startup configuration.  In the old school, no framework world, this would be the index.cfm file.  I used to call this the driver, from my days as a procedural programmer.  CF also has long supported the notion of an Application.cfm file, work done here has the application scope. With machii, there is the concept of the Application.cfc file and the index.cfm file.  Prior to version 1.5 or machii, there was often setup code in the index.cfm file, including the include of the actual framework.  In mach1.5, this goes away and no code lives in the index.cfm file, it all goes in the Application.cfc, which is actually extending the machii framework.&lt;br /&gt;&lt;br /&gt;When we upgrade the machii framework code to 1.5, we will have to be careful to move that important bootstrapper info from the index.cfm file to the Application.cfc file.  &lt;br /&gt;&lt;br /&gt;When looking critically at this new bootstrapper file, think in terms of these areas:&lt;br /&gt;&lt;br /&gt;application wide properties&lt;br /&gt;machII specific properties&lt;br /&gt;public functions, like&lt;br /&gt;onRequestStart&lt;br /&gt;&lt;br /&gt;Once this is done, we should not have too many other issues, then we can start taking advantage of the new 1.5 features, like the include functionality, that will allow us to break up the controllers into smaller pieces.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-8261401955090032970?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/8261401955090032970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=8261401955090032970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8261401955090032970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8261401955090032970'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/machii-15.html' title='MachII 1.5'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-6920007237733616421</id><published>2008-06-13T07:11:00.000-07:00</published><updated>2008-06-13T12:13:15.243-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='machii listeners model core business'/><title type='text'>Where to put listeners and model code</title><content type='html'>I ran across a blog &lt;a href="http://groups.google.com/group/mach-ii-for-coldfusion/browse_thread/thread/8f3d858a619d67d9#"&gt;discussion&lt;/a&gt; today about best practices regarding locations of mach-ii listeners -vs- model code. &lt;br /&gt;&lt;br /&gt;A summary.&lt;br /&gt;&lt;br /&gt;Listeners are not part of your model layer, so keep them separate from the model code.&lt;br /&gt;&lt;br /&gt;Put listeners into a /listeners folder.&lt;br /&gt;&lt;br /&gt;Put model code in a /model folder.&lt;br /&gt;&lt;br /&gt;In the model layer, some suggested organizing the cfcs like this:&lt;br /&gt;&lt;br /&gt;/model/Beans&lt;br /&gt;/model/Services&lt;br /&gt;/model/DOA&lt;br /&gt;/model/Gateway&lt;br /&gt;&lt;br /&gt;This is know as grouping by functionality.&lt;br /&gt;&lt;br /&gt;Most of the expert opinion (Matt Woodward, &lt;a href="http://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/FAQWhereShouldFrameworkExtensionsLive"&gt;Peter Farrell&lt;/a&gt;) favored this approach for the model layer.&lt;br /&gt;&lt;br /&gt;/model/busObject/&lt;br /&gt;&lt;br /&gt;where the bean, service, DAO and Gateway objects were grouped by type.  Since these objects comprise the abstract concept of a package, store them as a package.  This seems more intuitive, as other programmers come into the application, they will take the approach of what bus objects are there and see what pieces of that package exist.&lt;br /&gt;&lt;br /&gt;This is a quote from P Farrell "Otherwise, you are breaking objects into&lt;br /&gt;directories based on object type (pattern/functionality of the object)&lt;br /&gt;instead of the object's purpose (having to do with "user" stuff).  This&lt;br /&gt;is counter-intuitive as a developer would have to scan through a&lt;br /&gt;"beans", "gateways", "services" and "daos" directories to see if the&lt;br /&gt;User (bean) has a corresponding service, dao, gateway, etc..  Much&lt;br /&gt;easier (and it makes more sense in the long run) to group by object&lt;br /&gt;group instead of object type (pattern/function). "&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-6920007237733616421?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/6920007237733616421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=6920007237733616421' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6920007237733616421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6920007237733616421'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/where-to-put-listeners-and-model-code.html' title='Where to put listeners and model code'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-760388085219405288</id><published>2008-06-11T11:12:00.000-07:00</published><updated>2008-06-11T19:40:50.147-07:00</updated><title type='text'>A ColdSpring conversation between Mex and Lex</title><content type='html'>A hypothetical conversation between, a lesser experienced developer, Lex, and a more experienced developer Mex.&lt;br /&gt;&lt;br /&gt;Lex, "what the heck is coldspring?"&lt;br /&gt;&lt;br /&gt;Mex, "a framework that helps manage the model layer of your application"&lt;br /&gt;&lt;br /&gt;Lex, "whats a model layer"&lt;br /&gt;&lt;br /&gt;Mex, "the part of your programming that contains the bus. logic used in the program"&lt;br /&gt;&lt;br /&gt;Lex, "how do i know if i have a model layer? and what is the bus. logic"&lt;br /&gt;&lt;br /&gt;Mex, "does your application follow the MVC design pattern?"&lt;br /&gt;&lt;br /&gt;Lex, "whats MVC?"&lt;br /&gt;&lt;br /&gt;Mex, "a way of building your application so the view code is separated from the database and bus. logic code"&lt;br /&gt;&lt;br /&gt;Lex, "i think we follow that, i have only really worked on the view side, thats coldfusion .cfm files, right?"&lt;br /&gt;&lt;br /&gt;Mex, "yes, cfm files are usually a big part of the view layer, if your using ColdFusion.  The model layer which contains your bus. logic are stored in coldFusion files called CFCs.  The CFCs are the classes, like in Java."&lt;br /&gt;&lt;br /&gt;Lex, "so what does ColdSpring do again?"&lt;br /&gt;&lt;br /&gt;Mex, "Coldspring managers the model layer and helps with the relationships, or dependencies that exist between CFCs that collaborate in your model layer".&lt;br /&gt;&lt;br /&gt;Lex, "You mean like a service or manager CFC that uses a DAO or Gateway CFC?"&lt;br /&gt;&lt;br /&gt;Mex, "exactly like that.  The service component or CFC is dependent on the DAO and Gateway to do its job.  The way that is typically handled is when the service object is created, it has an init method or function that is called that creates the other objects it needs.  In a larger application that has lots of services, this can become a big headache to keep track of."&lt;br /&gt;&lt;br /&gt;Lex, "I think i heard some of the other programmers i work with complaining about this and how you have to open a bunch of files to track down what is being created and where."&lt;br /&gt;&lt;br /&gt;Mex, "right, CS reduces that complexity by putting all that object create code into a single file or container.  That file is responsible for defining all singleton objects in the application."&lt;br /&gt;&lt;br /&gt;Lex, "instead of putting create object code in the init method of the service for the DAO and Gateway, you put it in a coldspring file? I could do that for all the services in the application in this one file?"&lt;br /&gt;&lt;br /&gt;Mex, "yes and yes"&lt;br /&gt;&lt;br /&gt;Lex, "Is the coldspring file magic?"&lt;br /&gt;&lt;br /&gt;Mex, "sort of, seriously, its just a xml style file, its really not that complicated, once you understand what its doing"&lt;br /&gt;&lt;br /&gt;Lex, "ok, im in, lets get down to some nitty gritty"&lt;br /&gt;&lt;br /&gt;Mex, "i thought you would never ask"&lt;br /&gt;&lt;br /&gt;Mex.....&lt;br /&gt;&lt;br /&gt;CS is a framework, a black box, with a lot of code that you never touch, you simply use it.  If you are using a framework like mach-ii, fusebox or model-glue, you have specific "plug ins or hooks" that connect CS to your model.  Mach-ii has a plug-in architecture that connects CS to your application.&lt;br /&gt;&lt;br /&gt;You write a little code upon application start that executes and creates an object pointer to the black box (CS).  Then you use the CS object passing into it the file path to your bean definition file to load the definitions. Each of the beans (objects) is loaded in the application scope. This is really the only file that CS interacts with.&lt;br /&gt;&lt;br /&gt;If the object that you are creating has no dependencies, its very simple to create the object with a xml style notation.  If the object needs arguments passed in upon instantiation, use the arguments parameter to pass that data along.  If the object has dependencies on other objects, use the &lt;property&gt; tag to &lt;span style="font-weight:bold;"&gt;inject &lt;/span&gt;the dependency into the parent dependent object.  Think of this as an "inner-bean".  If the injected object is only used by the parent object, then define the collaborating objects like this:&lt;br /&gt;&lt;br /&gt;bean id="someService" class="somepath.someService"&lt;br /&gt;   property name="someGateway"&lt;br /&gt;     bean id="someGateway" class="somepath.someGateway"&lt;br /&gt;   /property&lt;br /&gt;/bean&lt;br /&gt;&lt;br /&gt;When someService is created, it is injected with the someGateway object.  The someGateway object is only available to the someService object.  Sometimes, the object needs a more global scope, so other objects can reference it as an injection.&lt;br /&gt;&lt;br /&gt;If the object being injected is already defined, use this notation to inject:&lt;br /&gt;&lt;br /&gt;bean id="someService" class="somepath.someService"&lt;br /&gt;   property name="someGateway"&lt;br /&gt;     ref bean="someGateway"/&lt;br /&gt;   /property&lt;br /&gt;/bean&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;The difference is that you are not injecting a new object&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;   &lt;br /&gt;     property name="someGateway"&lt;br /&gt;     bean id="someGateway" class="somepath.someGateway"&lt;br /&gt;   /property&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;but are injecting an existing object&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;   property name="someGateway"&lt;br /&gt;     ref bean="someGateway"/&lt;br /&gt;   /property&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ya dig?&lt;br /&gt;&lt;br /&gt;More to follow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-760388085219405288?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/760388085219405288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=760388085219405288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/760388085219405288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/760388085219405288'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/coldspring-conversation-between-mex-and.html' title='A ColdSpring conversation between Mex and Lex'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-1712422366274559408</id><published>2008-06-10T12:20:00.000-07:00</published><updated>2008-06-10T12:37:50.091-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='anemic value beans design pattern'/><title type='text'>Anemic  Domain Model</title><content type='html'>I was reading an article by Sean Corfield in &lt;a href="http://www.fusionauthority.com/index.cfm"&gt;Fusion Authority&lt;/a&gt; today.  I have read this article before, but my brain was not ready to &lt;a href="http://en.wikipedia.org/wiki/Grok"&gt;grok&lt;/a&gt; it, today, it grokked.&lt;br /&gt;&lt;br /&gt;The main concept is that too often we load up bus. logic in the service object instead of the bean or value object where it belongs.  If you think critically on this, it makes sense that since the data and methods of an object are encapsulated into the value or bean object, so too should the bus. rules around it.  &lt;br /&gt;&lt;br /&gt;The anemic model is one where the value beans are just containers with state and getter and setter methods - not much else, the bus. rules are stored in the service object.  &lt;br /&gt;&lt;br /&gt;Sean makes a good point that many of our web applications are getting record sets, presenting in a collection, hiding detail, proving details about one record when requested, not alot of bus. logic to fill up our value beans.  But, a good candidate is validation logic when dealing with single or groups of recs, rather than putting that logic in the service, leave it in the value bean - let it live along with the data and methods that it works on.&lt;br /&gt;&lt;br /&gt;I recently completed grokking why bus. logic should be in the service and not the listener (model layer, not the application).  I supplemented my understanding by going through a few of the older listeners and moving bus. logic out of and into related service object.  Perhaps i will iterate again, moving small amount of logic from the services into the beans.&lt;br /&gt;&lt;br /&gt;Lets turn those anemic value objects into rich domain objects!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-1712422366274559408?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/1712422366274559408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=1712422366274559408' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1712422366274559408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1712422366274559408'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/anemic-domain-model.html' title='Anemic  Domain Model'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-3129958270968325108</id><published>2008-06-06T10:21:00.000-07:00</published><updated>2008-06-06T10:53:49.871-07:00</updated><title type='text'>hard core refacoring</title><content type='html'>I have spent the past 2 days retooling the model layer of a mach-ii application.&lt;br /&gt;&lt;br /&gt;I have renamed numerous listeners and moved then into a new listeners folder.  I am really trying to promote the idea of model and application autonomy.&lt;br /&gt; &lt;br /&gt;/listeners/ objectNameLister1, ... objectNameListerx&lt;br /&gt;&lt;br /&gt;/model/objectName/ service, bean, DAO, Gateway &lt;br /&gt;&lt;br /&gt;Each time i renamed a listener, i did a careful search of the controller to update all instances of the old listener name.  In some cases, this was only a couple instances, in others, there were many.  This also gave a sense of what parts of the application are more widely used.&lt;br /&gt;  &lt;br /&gt;In a few cases, i renamed a manager that was really a listener, moved it into the listener folder and created a new service cfc.  The new listener should only speak to its registered service, so i had additional refactoring to do in the listener.  I updated methods that had knowledge of the DAO and Gateway moving that into the respective service.  This supports best practices of the listener being coupled to the application and bus. logic living in the model layer, not the listener.&lt;br /&gt;&lt;br /&gt;Think about the model layer as application agnostic.  Your model layer should be usable by another application. Imagine there is no mach-ii framework with listeners to invoke services.  Another application may want to use the objects in your model layer.  I moved ALL knowledge of DAO, Gateway and other services from the listeners into their service.  The service is the king of the jungle, not the listener.  The listener just passes things along.&lt;br /&gt;&lt;br /&gt;There were a few listener methods where i left bus. logic in place, but that logic is dealing with announcing of events, making it application logic, which belongs in the listener NOT the service.&lt;br /&gt;&lt;br /&gt;Changing the location of the listeners required me to update the path in one place, the mach-ii listeners configuration.  If i changed the location of the model classes, i had to change the path of the object invocation (init) method in the service, DAO and Gateway.  After doing this a few times, i really stated to see the beauty of the coldSpring layer, which encapsulates this type of change into a single entity, the coldSpring.xml file.  I also saw that some of the objects are not taking advantage of the coldSpring framework.  These are candidates for coldSpring.&lt;br /&gt;&lt;br /&gt;When i encountered listeners and services that had an empty configuration or init method, at least in terms of object creation, and i would see pointer references in class methods, i knew those pointers were defined somewhere, who would have knowledge of such pointers?  I also noticed a set method that accepted the object itself at the bottom of those classes.  Each of these things is a clear indicator that there is an object management framework in play.&lt;br /&gt;&lt;br /&gt;I am still getting my head around how coldSpring is doing things, i thought i would deploy all these changes first, then work on a coldSpring deployment separately. &lt;br /&gt;&lt;br /&gt;Things are jelling now, jellin like a felon, architecturally speaking.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-3129958270968325108?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/3129958270968325108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=3129958270968325108' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3129958270968325108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3129958270968325108'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/hard-core-refacoring.html' title='hard core refacoring'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-1616399052613712376</id><published>2008-06-04T10:05:00.000-07:00</published><updated>2008-06-04T11:02:23.229-07:00</updated><title type='text'>Evolution of a MVC application</title><content type='html'>I have been tasked the honor of bringing others into or up to speed with a big MVC application.  That's ok, i used to be a teacher and trainer, part of my brain enjoys the mentoring role.&lt;br /&gt;&lt;br /&gt;I have been studying the architecture of the application, doing some reverse engineering for awhile and have a little summary i would like to share.  Blogging this stuff helps me internalize and forces me to think more critically.&lt;br /&gt;&lt;br /&gt;In the beginning our application did not use services.  Most entities were created following the&lt;br /&gt;&lt;br /&gt;Bean&lt;br /&gt;Manager&lt;br /&gt;DAO&lt;br /&gt;Gateway&lt;br /&gt;&lt;br /&gt;design patten.  Which is fine, except the managers are actually the listeners, they are extending the mach-ii framework listener.  All of these files are located in the root of the application in the model folder.  Object instantiations to the DAO/Gateway occur in the managers (listener) constructor.  The manager is trying to act like a manager (service) by creating its dependency objects (DAO, Gateway) in its constructor.  Thats fine, good practice.&lt;br /&gt;&lt;br /&gt;As the application grew, real managers started appearing, but not in the model folder (that should just be listeners) in a org. path.  The idea of the org. path is to promote the concept that the model or bus. layer is application agnostic.  It should not live in the same file structure as the applications listeners.  Ill buy that. &lt;br /&gt;&lt;br /&gt;The managers, playing the service role, live in the org path along with the other depenency objects, DAO, gateway and Bean (value bean). The managers (services) are responsible for instantiating their dependency objects (DAO, Gateway and bean). The listeners in the model path are only instantiating their manager or service object. &lt;br /&gt;&lt;br /&gt;As sub applications start appearing, listeners are where they should, in the model layer and in a couple cases,  the related bus. logic (bean, service, DAO, Gateway) appear in a folder beneath the model layer.  This is ok, but does not seem to promote the idea of reusable model layer components or agnostic model layer.  &lt;br /&gt;&lt;br /&gt;In most cases, the listeners are instantiating their service object in their constructors while the service is instantiating their dependent objects in the init functions.&lt;br /&gt;&lt;br /&gt;Eventually, ColdSpring was introduced to start managing all these object and dependency object creation.  ColdSpring is a framework that abstracts the knowledge of dependencies from the actual objects.  Ill study more on this as it appears some objects are not yet utilizing this feature.&lt;br /&gt;&lt;br /&gt;Most of the application is following OO practices, meaning that object references are being passed along to service and DAO funtions that are requiring them and using the reference to the bean to handle updating or persistence requirements.  Gateway functions are typically accepting values, not references and returning queries.&lt;br /&gt;&lt;br /&gt;Some of the application functionality, like the stuff i wrote, is using object wrappers but is too often using procedural pass by value and not object reference.  It was not until recently that i really started looking critically at this and reading in blogs why this is problematic.&lt;br /&gt;&lt;br /&gt;As i continue to stretch my brain and teach others about this application architecture, i will continue to re-factor and implement OO practices.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-1616399052613712376?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/1616399052613712376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=1616399052613712376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1616399052613712376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1616399052613712376'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/evolution-of-mvc-application.html' title='Evolution of a MVC application'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-8317151287851970145</id><published>2008-06-04T06:13:00.000-07:00</published><updated>2008-06-04T06:31:37.587-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='by reference'/><category scheme='http://www.blogger.com/atom/ns#' term='beans'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><category scheme='http://www.blogger.com/atom/ns#' term='CF'/><title type='text'>Refactoring with on eye on patterns</title><content type='html'>I have been looking with a different eye at existing code in our applications.  Refactoring code is an important part of any programmers job.  I hear the stats about 75% of programmers time is spent maintaining existing systems.  That seems about right to me.  I have spent a lot of time the past month studying design patterns and best practices for CF developers, since the excellent CF Objective conference in May.&lt;br /&gt;&lt;br /&gt;I have been looking at listeners in our mach-ii application and their managers (services) with an eye for moving  bus. logic out of the listener and into the service.  We actually had a cfc that was named a manager, but was actually a listener, it was extending the machii listener framework and was referencing event args. but did not have a service layer at all.  I have been refactoring, renaming the manager to listener and creating a service layer between the listener and DAO/Gateway.  It has taken me a long time to really get my head around why we would need all these layers, but i think its finally starting to jell.&lt;br /&gt;&lt;br /&gt;I have spent lots of time in blogs, tutorials, books and existing code, learning from the experts, standing on the shoulders of giants, as my former co-worker liked to say.&lt;br /&gt;&lt;br /&gt;I will continue looking at the listener and moving bus. logic out and into the service layer repeating the mantra "the listener only passes data to the service layer", its a traffic cop, not a problem solver.  The listener can contain logic that directs the flow of the application, but not any logic that pertains to the bus. objects.  The bus. objects are application agnostic!&lt;br /&gt;&lt;br /&gt;I woke up this am thinking and repeating this to my 11 year old son.&lt;br /&gt;&lt;br /&gt;"The bean is a container, that holds data and instructions about something, an object". When the application needs to reference the data or behaviors of the bean, it asks the service layer  to do it.  The service layer instantiates the bean and passes references to the bean into DAO which will operate on the bean."  In others words, a reference to the bean is passed along to service who then passes where it needs to.  Any functions that manipulate the data stored in the bean do so by reference.  A DAO method requires a object be passed in and references the attibutes of the object via the argument reference passed in." &lt;br /&gt;&lt;br /&gt;We are no longer passing values around from one function to another, but rather passing references to a bean.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-8317151287851970145?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/8317151287851970145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=8317151287851970145' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8317151287851970145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8317151287851970145'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/06/refactoring-with-on-eye-on-patterns.html' title='Refactoring with on eye on patterns'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-5069416670717434261</id><published>2008-05-30T08:53:00.000-07:00</published><updated>2008-05-30T09:10:30.582-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debugging mvc object instantiation'/><title type='text'>Evils of debugging tiered software</title><content type='html'>Typically, one of the payoffs of a tiered MVC designed application is ease of maintenance. I'm not so sure awhen it comes to debugging.  If you are familiar with the application architecture and the application is consistent in how it models objects then the debugging is easier.&lt;br /&gt;&lt;br /&gt;I just spend about 3 hrs trying to solve a bug that i introduced while refactoring.  I am refactoring some code in a pair of collaborating objects a listener and a service .&lt;br /&gt;&lt;br /&gt;I am moving bus. logic from the listener into the service.  My listener instantiates the service in its configure method.  I created the problem in the one of the service functions, but the error was being reported by CF in the listener constructor at the line number where the instantiation to the service was being called.  Eventually, i was able to track the error down in the service function that was using the same variable name for both an argument and a locally vared variable.  The error was reported  correctly but it took me way too long to figure out that the reporting of the error in the listener constructor was caused by a function in the service.  Seems obvious in hindsight, that the listener constructor was failing because it was creating the new object that had to parse the entire cfc before it would create a new instance of itself. &lt;br /&gt;&lt;br /&gt;Moral - if the error is occurring in a constructor or init function, then look carefully down stream into the instantiated objects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-5069416670717434261?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/5069416670717434261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=5069416670717434261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5069416670717434261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5069416670717434261'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/evils-of-debugging-tiered-software.html' title='Evils of debugging tiered software'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-1703115155003857130</id><published>2008-05-27T13:19:00.000-07:00</published><updated>2008-05-27T13:40:00.088-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='machii listeners model core business'/><title type='text'>Listener -vs- service layer</title><content type='html'>Ok, ive been feeling this question for awhile in one of our main applications DataMentor.  We have a machii implementation around the application.  I am seeing more clearly the reason that we should put our business logic in a service and not a listener.  The listeners are part of the application, and our service layer should be application agnostic.  I can look back at early design decisions and see bus. logic in the listeners, and even listeners that were playing the role of service or manager.  As we build new features into DataMentor, we can follow the best practices of services -vs- listeners and we can continue to re-factor  code as we make smaller changes to  legacy logic.&lt;br /&gt;&lt;br /&gt;Here are a few &lt;span style="font-weight: bold;"&gt;excerpts &lt;/span&gt;from some respected machii architects, Sean Corfield and others.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"If you built a service layer that is independent of the framework that orchestrates actions taken against the model and then you built one or more listeners that mostly just delegate to that service layer, you'll be in good shape."&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"&lt;/span&gt;Don't think it won't happen to you! I guarantee that you'll find yourself putting a Flex front-end on a legacy Mach II application at some point and you'll wish you too had done a better job of separating your business model from your listeners!&lt;span style="font-style: italic;"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"&lt;/span&gt;Right, a web service front end will also show the same issues. And just to be clear, Flex, Flash and Web Services all rely on the model portion, the CFCs, and not Mach II (or Model-Glue) which is why separating the framework from the model is so important.&lt;span style="font-style: italic;"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;See full discussion &lt;a href="http://http//corfield.org/blog/index.cfm/do/blog.entry/entry/Mach_II_Some_Advice#postcomment"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;This is from the machii&lt;a href="http://livedocs.adobe.com/wtg/public/machiidevguide/models.html"&gt; developers guide&lt;/a&gt; on listeners: &lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;Mach II interacts with the Model portion of your application using components that extend &lt;code&gt;MachII.framework.Listener&lt;/code&gt;. In a simple application, all of your business logic might be implemented in such listeners but this approach does not scale well with increasing application complexity because, amongst other things, it introduces a tight coupling between the elements of your business logic and the Mach II framework.&lt;/p&gt; &lt;p&gt;You are much better off ensuring there is only a thin layer of coupling between   the framework and your application - if necessary, create new components that   extend the Mach II listener component, whose sole purpose is to communicate   those events to the components within your business model.  In other words,   try to&lt;span style="font-weight: bold;"&gt; isolate your business components from the framework&lt;/span&gt; components as much   as possible: only &lt;span style="font-weight: bold;"&gt;listener components should know about the framework&lt;/span&gt;; only   listener components should access Mach II properties; only listener components   should announce events. &lt;span style="font-weight: bold;"&gt;The core business components should know nothing about   Mach II&lt;/span&gt; and have no dependencies at all on the framework.&lt;/p&gt;&lt;br /&gt;In our cfobjective class last month we had a spirited discussion about this.  One of the principles i recall was the listeners job being to pass along data to the service layer. The only logic that should be in the listener is logic pertaining to program flow.  The listener could announce other events, reference controller properties and set event arguments.  When it was done doing these things, it simply handed the event args off to the service. The listener knows nothing about the model layer and the model layer knows nothing about the listener, excepts the names of methods exposed via the API.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-1703115155003857130?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/1703115155003857130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=1703115155003857130' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1703115155003857130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/1703115155003857130'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/listener-vs-service-layer.html' title='Listener -vs- service layer'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-8619812151935355735</id><published>2008-05-27T12:21:00.000-07:00</published><updated>2008-05-27T12:57:18.979-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns in ColdFusion'/><title type='text'>Design Patters - more details</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Design Patterns in ColdFusion         &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Content paraphrased from http://www.jroller.com/page/kwiersma.&lt;br /&gt;&lt;br /&gt;I keep coming back to these patterns because I support a large application that implements all of them and have been asked to share my knowledge.   This is the knowledge!  Granted, there is a lot of business logic in the application, but the architecture of the application follows closely the the principles found in these patterns.&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Beans ( Business Objects or Value Objects)&lt;br /&gt;DAOs (Data Access Objects)&lt;br /&gt;Gateways (Data Gateway Objects)&lt;br /&gt;Services (Manager Objects)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Bean&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Typically represents a specific entity in your model&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Carries "encapsulated" data between the different layers of your application&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;like a structure, instead of directly accessing data with a key you call a method&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Helps organize data structures instead passing structures around ad-hoc&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Has a consistent and simple interface (Controllable API)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Has methods called getters/setters (aka accessors) to access data [getFirstName() / setFirstName()]&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Might be composed of other beans&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Easily created with a code generator&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;DAO (data access object)&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;DAOs only interact with one row of data via the primary key&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Used to save/load objects from data storage&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;A DAO could interface with: Database / Legacy persistent data storage (XML / Text File)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Usually have ScRuD method that &lt;span style="font-weight: bold;"&gt;take a bean&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;(ScRuD - Save | (create) | Read | (update) | Delete)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Gateways (Aggregated Data)&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;return one or more rows of data&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Typically returns a cfquery object&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Rarely it can return a bean (Querying by User/Pwd)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Performs functionality that may affect one or more rows&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Services: (Kings of the Jungles)&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Contains your business logic:&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Bean Validation / Creation&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Application specific business logic&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Save / Load / Delete from DAO (via the facade pattern)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Gateway Interaction (via the facade pattern)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Usually depends on a DAO and Gateway&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Services can consume other services (very social)         &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-8619812151935355735?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/8619812151935355735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=8619812151935355735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8619812151935355735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/8619812151935355735'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/design-patters-more-details.html' title='Design Patters - more details'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-6622802984245853181</id><published>2008-05-12T07:23:00.000-07:00</published><updated>2008-05-12T07:57:23.037-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='services model managers object reference'/><title type='text'>Value objects, Services and Objects Frameworks</title><content type='html'>Still internalizing.&lt;br /&gt;&lt;br /&gt;Suppose in your application you deal with assessments, standards and resources.  Each of these entities would be modeled by a value bean and each of the value beans would have their own service which would have its own DAO and Gateway objects.&lt;br /&gt;&lt;br /&gt;A quick review of the &lt;span style="font-weight: bold;"&gt;value beans&lt;/span&gt; reminds use that each has its own constructor method that returns a reference to itself (passing by reference).  This provides a complete blue print of the object, with attributes and methods to the requesting entity.  Best practices suggest requiring as little as possible to instantiate a object.  Define the arguments as optional with default values.  Each value object has matching getter and setter methods for each attribute defined by the value bean.  The setter methods do not return any values or references, they simply update a instance value.  The getter methods return a granular value, string, integer, boolean (passing by value). &lt;br /&gt;&lt;br /&gt;A quick review of a &lt;span style="font-weight: bold;"&gt;service &lt;/span&gt;object reminds us that the constructor method also returns a reference to itself.  The constructor method would likely have object instantiations to the dependent DAO and Gateway objects and methods to call the DAO and Gateway methods.  The service would likely have a utility methods that would create a new instance of its value bean&lt;br /&gt;, which would return a object reference.  The service may also contain other utility type methods like data validation on a form.  The service methods will likely contain your business logic or rules and may need to reference data in other value objects.  Remember to think of your services as the social entities in your software ecosystem.  They are the glue between your application and model layer and contain most of the business specific rules that your objects must obey.&lt;br /&gt;&lt;br /&gt;In this example, suppose the &lt;span style="font-weight: bold;"&gt;assessment service&lt;/span&gt; needs to know something about the standard bean, it would need to talk with the &lt;span style="font-weight: bold;"&gt;standard service&lt;/span&gt;, now the assessment service needs to instantiate a pointer to the standard service.  Suppose the &lt;span style="font-weight: bold;"&gt;assessment service&lt;/span&gt; also needs to know something about the resource bean, now the assessment service must instantiate a pointer to the&lt;span style="font-weight: bold;"&gt; resource service&lt;/span&gt;.  This type of dependency is common and can become difficult to manage and debug when things go wrong.  Architects often ask who's job is it to keep track of these things?  Why does &lt;span style="font-weight: bold;"&gt;service a&lt;/span&gt; need to create pointers to &lt;span style="font-weight: bold;"&gt;service b or c&lt;/span&gt; and vice versa for objects b and c needing pointers to services a and b.  This is complex and tricky and has given rise to &lt;span style="font-weight: bold;"&gt;model layer managers&lt;/span&gt;.  The model layer managers, like &lt;span style="font-weight: bold;"&gt;ColdSpring &lt;/span&gt;or &lt;span style="font-weight: bold;"&gt;Livewire &lt;/span&gt;abstract knowledge from the service layer.  The model layer manages the creation of objects and their dependencies.  These objects are all &lt;span style="font-weight: bold;"&gt;singletons &lt;/span&gt;and need only be created once during a given session.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-6622802984245853181?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/6622802984245853181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=6622802984245853181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6622802984245853181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6622802984245853181'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/value-objects-services-and-objects.html' title='Value objects, Services and Objects Frameworks'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-5347824471674239208</id><published>2008-05-09T08:45:00.000-07:00</published><updated>2008-05-27T11:24:32.990-07:00</updated><title type='text'>design patterns - A walk through</title><content type='html'>I may be a little redundant here, but it really helps me to write it down, and if im blogging here, i am forced to think and articulate a little more critically.&lt;br /&gt;&lt;br /&gt;This week, I am walking through a sample application provided by the good folks at &lt;a href="http://cfobjective.com/"&gt;cfobjective&lt;/a&gt;.  I have my eye on the familiar data patterns and how they are implemented in a typical CF application.  The application is not using a model manager like ColdSpring or LiveWire, nor is it using a application framework like machII, fusebox or coldbox.  You could say its a little more clean this away and allows you to focus on the design of the objects (beans) and its interactions with its service, the application and model layer.&lt;br /&gt;&lt;br /&gt;The application is following the MVC pattern and is using a &lt;span style="font-weight: bold;"&gt;service &lt;/span&gt;layer to interact with the &lt;span style="font-weight: bold;"&gt;DAO &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;Gateway&lt;/span&gt; and a facade to encapsulate the session scope.&lt;br /&gt;&lt;br /&gt;The application.cfm file is creating the service object and other app. level setup work.  The creation of the &lt;span style="font-weight: bold;"&gt;service object&lt;/span&gt; in the application scope allows it to be avail and used for the creation of a value or bean object and subsequent writes to the persistence layer via the DAO and Gateway.&lt;br /&gt;&lt;br /&gt;The init() method of the&lt;span style="font-weight: bold;"&gt; service object&lt;/span&gt; is returning a reference to itself &lt;span style="font-style: italic;"&gt;after &lt;/span&gt;it creates objects for both its DAO and Gateway.  This is a case of the service object having state and knowing about other objects.  If there was a model management tool, it would be responsible for keeping the state or dependencies, also referred to as CFC wiring.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;service &lt;/span&gt;contains all the methods to both the &lt;span style="font-weight: bold;"&gt;DAO &lt;/span&gt;and the &lt;span style="font-weight: bold;"&gt;Gateway&lt;/span&gt;.  The service also contains the method to create a new &lt;span style="font-weight: bold;"&gt;value bean, &lt;/span&gt;which returns an instance of itself.  In other words, the service is not only responsible for speaking to the data layer, but also for creating instances of the value beans that it is servicing.&lt;br /&gt;&lt;br /&gt;If you need to create a value bean then find its service and call its public method that returns an instantiation of the bean.  You are not returning just data like a string or a query, but the entire object, including the methods that are avail. in it.  If you need to reference or update part of that value bean, then use its avail. getter or setter methods.  This is clean object notation and usage.&lt;br /&gt;&lt;br /&gt;For example, lets say we are dealing with a person bean or object.&lt;br /&gt;A user has supplied details via a webform, those details have passed the submission filters and a new person object has been created and its attributes updated via bean setters.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;cfset variables.person = CreateObject("component", "Person").init()&lt;br /&gt;   cfset variables.person.setFirstName(form.firstName)&lt;br /&gt;   cfset variables.person.setLastName(form.lastName)&lt;br /&gt;   cfset variables.person.setAge(form.age)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next, call a addNewPerson function in the service, passing in the object reference and do a little error checking prior to calling the DAO function;&lt;br /&gt;&lt;br /&gt;cfset variables.errors = application.personService.addNewPerson(variables.person)&lt;br /&gt;&lt;br /&gt;If no errors result, call the addNewPerson function and require the object be supplied.&lt;br /&gt;&lt;br /&gt;cffunction name="addNewPerson"...&lt;br /&gt; cfargument name="person" type="Person" required="true" ...&lt;br /&gt;&lt;br /&gt;If everything is in order, call the createPerson function, passing in the object reference, which will call the related DAO function.&lt;br /&gt;&lt;br /&gt;cffunction name="createPerson" access="public"...&lt;br /&gt; cfargument name="person" type="Person" required="true"&lt;br /&gt;   cfreturn variables.dao.create(arguments.Person)&lt;br /&gt;&lt;br /&gt;In the create function of the DAO, require the person object be passed in and insert the record using the getter method for the person to get the actual value to write into the table.&lt;br /&gt;&lt;br /&gt;cfargument name="Person" type="Person" required="true"&lt;br /&gt;&lt;br /&gt;  cfqueryparam value="#arguments.Person.getFirstName()#&lt;br /&gt;  cfqueryparam value="#arguments.Person.getLastName()#&lt;br /&gt;&lt;br /&gt;This is a change of thinking for me, not easy, since i have treated CF in a procedural manner, where i am simply passing in args by value, not by object reference.  I am trying to get my head around the benefit, which is trying hard to hide itself behind the added complexity, maybe its not really more complex, im just conditioned to think the other way and so think it more complex.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-5347824471674239208?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/5347824471674239208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=5347824471674239208' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5347824471674239208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5347824471674239208'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/design-patterns-still-internalizing.html' title='design patterns - A walk through'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-6219793891980320032</id><published>2008-05-08T09:12:00.000-07:00</published><updated>2008-05-27T10:32:07.747-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DAO'/><category scheme='http://www.blogger.com/atom/ns#' term='software design patterns best practices abstraction'/><category scheme='http://www.blogger.com/atom/ns#' term='Gateway'/><title type='text'>Design pattern DAO -vs- Gateway</title><content type='html'>I thank the GOF (gang of four) authors, Matt Woodward, Brian and Sean Corfield.&lt;br /&gt;&lt;br /&gt;nuggets as follow&lt;br /&gt;&lt;br /&gt;right off the bat, we realize this is not trivial stuff,&lt;br /&gt;&lt;br /&gt;"&lt;span style="font-style: italic;"&gt;Designing object-oriented software is hard, and designing reusable object-oriented software is even harder.&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;define a pattern:&lt;br /&gt;&lt;br /&gt;"&lt;span style="font-style: italic;"&gt;An object that encapsulates access to an external system or resource.&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;"&lt;span style="font-style: italic;"&gt;Pattern: Bridge. Intent: Decouple an abstraction from its implementation so that the two can vary independently&lt;/span&gt;."&lt;br /&gt;&lt;br /&gt;I agree with Matt Woodward, who says;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"The DAO and the Gateway, from a pattern standpoint, serve exactly the same purpose. They both encapsulate access to a database. The Gateway pattern is used by many ColdFusion developers to contain methods that handle multiple records. The DAO, on the other hand, is used in many ColdFusion applications to deal solely with single records; many ColdFusion DAOs contain only create(), read(), update(), and delete() methods (affectionately referred to as "CRUD").&lt;span style="font-style: italic;"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;This is an excerpt from the mach-II devlopers guide, this version written by Sean CorField and provides great differenciation of the gateway and DAO design patterns and how they should be used.  I have struggles to see this, even to explain it, but Sean seems to nail it down very well.  Specifically the part about returning query sets from gateways but objects from DAO.&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;  --- Begin quote from the Mach-II Development Guide ---  &lt;p style="font-style: italic;"&gt;There are two basic patterns of access to persistent data within most applications:&lt;/p&gt;  &lt;ul style="font-style: italic;"&gt;&lt;li&gt;aggregated access - reporting, searching, listing multiple rows,&lt;/li&gt;&lt;li&gt;per-object access - creating, editing, working in depth with a single row       (object).&lt;/li&gt;&lt;/ul&gt;  &lt;p style="font-style: italic;"&gt;ColdFusion has a great built-in idiom for dealing with the first type of access  - the query - which is an efficient way to manipulate (potentially large) sets of data rows retrieved from a database (or other data sources, since you can easily create a query object and populate it with your own data). When you are dealing with aggregated access, it does not make sense to convert every row returned into a fully-encapsulated object (CFC instance) when all you are likely to do with the data is display a few fields with a link to a detail page that will focus on the selected row.&lt;/p&gt;  &lt;p style="font-style: italic;"&gt;On the other hand, when you are focusing on a single row it usually does make sense to work at the fully-encapsulated object level since you are usually interested in object behavior at that point. This is also the level where you need the standard CRUD (Create, Read, Update, Delete) operations.&lt;/p&gt;  &lt;p style="font-style: italic;"&gt;Recognizing these two basic patterns, you should design your components accordingly by providing separate components for each pattern. This is best explained through an example:&lt;/p&gt;  &lt;ul style="font-style: italic;"&gt;&lt;li&gt;If we have a business model object called Order, then we would provide an OrderGateway component for aggregate access and an OrderDAO component for per-object access (or build the per-object access into the Order object - but see below).&lt;/li&gt;&lt;li&gt;The OrderGateway component would provide methods like findAll(), findWhere(), findByID() and they would all return standard query objects (even findByID() which returns a single row).&lt;/li&gt;&lt;li&gt;The OrderDAO component would provide CRUD methods like store(), load(), update(), delete() and they would operate on a specific Order object exchanging data via getters/setters on the Order component or via some sort of snapshot of the Order's data, e.g., a bean: the Order component could implement methods like getSnapshot() returning a bean and setSnapshot() taking a bean as an argument - the bean containing the core persistent data for the Order object. Sometimes a more direct data transfer between the business object and the data access object is needed for performance reasons (or because the application can 'trust' the components to exchange less encapsulated data, such as a struct or some opaque data structure e.g., the Memento design pattern). Such optimizations are beyond the scope of this document.&lt;/li&gt;&lt;/ul&gt;  &lt;p style="font-style: italic;"&gt;Separating out these operations from the business model object helps it stay persistence-neutral. The gateway components can be optimized for retrieving large record sets, caching etc. The DAO components can be optimized for dirty data updates, pooled object access and so on. Again, the details of these optimizations are beyond the scope of this document but providing for the two distinct patterns of data access will get you started on the right road.&lt;/p&gt;  --- End quote from the Mach-II Development Guide ---&lt;br /&gt;&lt;br /&gt;This wisdom i am paraphrasing from Matt Woodward blog entry, &lt;a href="http://www.mattwoodward.com/blog/index.cfm?event=showEntriesByCategory&amp;amp;categoryId=084929C5-CC35-853B-AE77E3FC2C11024F&amp;amp;categoryName=Design%20Patterns"&gt;read entire post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;I like knowing that my DAOs deal with CRUD and that's it. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; Gateways, on the other hand, are far more nebulous and end up changing much more during application development.  I find that I add, remove, and alter methods in my Gateways pretty regularly right up until the application is complete. My DAOs, on the other hand, are built at the outset and they just sit there doing their job.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; I also like knowing that when I call methods in my DAOs, they take in an instance of the object with which they are concerned (i.e. the bean) and don't return anything since they're operating directly on the objects passed in. Gateways, by contrast, typically return query objects or, when necessary, collections of beans. Some suggest that if you don't return a collection of objects, we aren't using this pattern "properly." Says who? Fowler? Sun? Maybe in Java the convention is to return a collection of objects.  In ColdFusion we have the query that is efficient and easy to use. If all I want to do is loop over a query and display the data, and I don't need to interact with each individual object, why on earth would I make things more complex and less efficient just so I'm better meeting another technology's definition of how a Gateway is supposed to behave? Pure nonsense. When I need to deal with each individual object in an aggregate dataset, I can quite easily return an array of CFCs. When I don't need to do that, I won't bother. Some call that bad programming; I call it practical.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;A paraphrase of a Sean Corfield post as response to this post, &lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;"I still maintain that in ColdFusion it makes sense to keep per-object operations separated from aggregate operations because ColdFusion provides a wonderful abstraction called "query" :)&lt;/span&gt;  &lt;p style="font-style: italic;"&gt;With the rise of ORM frameworks, it makes even more sense to keep "DAO" and "Gateway" separate because the ORMs replace the DAOs completely but only partially replace Gateways, if at all."&lt;/p&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-6219793891980320032?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/6219793891980320032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=6219793891980320032' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6219793891980320032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/6219793891980320032'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/design-pattern-nuggets.html' title='Design pattern DAO -vs- Gateway'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-5702111667043696781</id><published>2008-05-08T08:12:00.000-07:00</published><updated>2008-05-27T09:57:44.152-07:00</updated><title type='text'>Leveraging Design Patterns</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29"&gt;Design patterns&lt;/a&gt; (DP) are helpful, especially once you start to see them in action and recognize them as such.  DP convey standard ways of solving problems encountered by software architects.  Once you have build and maintained applications for awhile, you see "cowboy coding" for what it is, lazy or perhaps uninformed approaches to solving problems.  The MVC pattern is one of the first that you need to grok or get your head around. This mature pattern promotes solid tiered or layered programming where the key parts of your application are separated (data, bus logic and presentation).  Design patters are not a solution to a problem but a way of viewing the problem and seeing its solution.&lt;br /&gt;&lt;br /&gt;Do not be discouraged if you do not immediately see the payoff or even the need for a pattern at first, these are not always obvious and take time to internalize before you see them or the payoff in following or implementing one.&lt;br /&gt;&lt;br /&gt;ColdFusion has evolved into a OO language that lends itself to design patterns.   If you use cfinclude &lt;cfinclude&gt; &lt;cfinclude&gt; in your programming then you are already following a design pattern of reuse.  If you see the benefit of putting code into a file and sharing that file in multiple places, rather than retrying the code in each place, you are on your way to being a better programmer or architect.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Singleton Pattern&lt;/span&gt; - Some objects only need to be created once during the life of the user session, objects like services or application setup services are called singletons.  They do not have to keep any state.  For example, if i am tracking site visits in a log file or DB, i would only want a single record of that visit, not each time the user does something during their visit.  When a user logs into a system, their information is retrieved and stored only once during their visit.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Factory pattern &lt;/span&gt;- Just give me what i need and its dependencies.  I build objects and their dependency objects.  If i am creating a DAO or Gateway object, then i will create also its service object.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Facade pattern&lt;/span&gt; - a front end that encapsulates dependencies with object dependencies.  When creating a API or interface to my objects, i don't need to share all the details about how things work, just how to use it.  The facade is a happy public face that hides the real complexity of the object.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Data Access pattern&lt;/span&gt; - data access objects like DAOs only know about the persistence layer or database.  The data access pattern often includes helper methods to simplify the way the service layer see it and calls it.&lt;/cfinclude&gt;&lt;/cfinclude&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-5702111667043696781?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/5702111667043696781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=5702111667043696781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5702111667043696781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/5702111667043696781'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/leveraging-design-patterns.html' title='Leveraging Design Patterns'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-3254204835232462321</id><published>2008-05-08T07:22:00.001-07:00</published><updated>2008-05-27T09:49:31.772-07:00</updated><title type='text'>SOA architecture</title><content type='html'>I attended &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;cfobjective&lt;/span&gt; this month, great conference.  One of the sessions i attended was &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;ColdSpring&lt;/span&gt; by Chris Scott.  He gave a very conceptual overview of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;SOA&lt;/span&gt; principles.  I would like to internalize these better, so ill put them into my own words.&lt;br /&gt;&lt;br /&gt;Here is the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;wikepedia&lt;/span&gt; definition of &lt;a href="http://en.wikipedia.org/wiki/Service-oriented_architecture"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;SOA&lt;/span&gt;.&lt;/a&gt; These principles are relevant to OO design in general.  Try to build your CFC's in such a way that they can be used by more than just the application you are currently working on.  Its easy to develop tunnel vision and only think about the task at hand when building and creating CFCs.  It may be a little easier to think only in the moment, but that is junior league. &lt;br /&gt;&lt;br /&gt;Think instead of who else could use this object and if someone else where to use it, what do they have to know about it.  Think of the object as a small part of a larger system or environment.  Think ecosystem and one plant or animal in that system.  With that mind set, consider these principles in more detail.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Encapsulate &lt;/span&gt;- which means hide the complexity of its inner workings from the rest of the ecosystem. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Think black box, others do not need to know how it works, just that it does.  &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Think happy face to the rest of the world where the face is the API or interface.  The API should show all interested parties how to interact with itself, what questions it can ask of it or what services it provides to the ecosystem and what information must be provided for the request to be understood and carried out by the object.  &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Try to keep the knowledge of the environment out of the data access objects and only operate on data passed into it, do NOT rely on data that exists somewhere else, like in application or session scope. No reaching out.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Loose Coupling &lt;/span&gt;- This means minimum dependencies on other things in the environment.  Let each thing be self sufficient. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Objects in general have inherent dependencies, especially data service objects like DAOs and Gateways.  Try to minimize these dependencies and even put them into a single place, like a object management service, like ColdSpring.  At least then the coupling is managed and defined all in a single place and does not leak into the service layer.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Contract &lt;/span&gt;- This is an agreement that exists between two objects that interact. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Think of this as a handshake or agreement that defines how communication  occurs.  This contract exist between two objects and should not change without informing both parties.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Abstraction &lt;/span&gt;- objects hold logic that is not exposed - only a contract is required to use it. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Object a says to object b, i would like to call your method "get widget" where you require me to provide a widgetID.  Object B says ok object a, you asked a question that i understand and provided me with the correct ID, so here it is - don't worry, i wont tell you about any of the gory details about how i completed this request for you.  What? you want to know what else i can do for you? Ok, here is my API.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Re-usability&lt;/span&gt; - a holy grain of software design. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Write code once and try to use it as much as possible.  Some objects are inherently not too re-usable, like listeners and view files and controllers - they are all part of a specific application.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The service layer and it dependent DAOs and Gateways are better candidates for reuse (IMHO).  So, try to keep the knowledge of the environment out of the data access objects and only operate on data passed into it, do NOT rely on data that exists somewhere else, like in application or session scope.  No reaching out.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Composition &lt;/span&gt;- collection of like services. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;This is the has a relationship that is referred to in UMLing.  This is also how many APIs are wired together, via packages.  Packages are like minded services.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cohesion&lt;/span&gt;- a service, object or method is good at doing one thing.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Do not try to be the doing of all things.  Think in terms of small and numerous, not few and beefy.  This is applicable to object design and method design.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Discover ability&lt;/span&gt; - the service should be able to be found. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Especially if it is a public service, it should be findable.  Using the hint property in CF is a good way to expose the intention of the object.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-3254204835232462321?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/3254204835232462321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=3254204835232462321' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3254204835232462321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/3254204835232462321'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/soa-architecture.html' title='SOA architecture'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7000193931034575215</id><published>2008-05-07T11:51:00.000-07:00</published><updated>2008-05-27T09:27:42.743-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='factory pattern OO software engineering'/><title type='text'>Object differentiation</title><content type='html'>Thanks again to &lt;a href="http://corfield.org/articles/cfobj_factories.pdf"&gt;Sean CorField  &lt;/a&gt;for his great explanation on this topic.  I will try to explain for my own internalization.  Objects are the heart of a OO system, the way we see and understand their similarities and differences informs how we build them.&lt;br /&gt;&lt;br /&gt;There are two types of objects that we model in our CFCs.&lt;br /&gt;&lt;br /&gt;1 - Value objects (beans)&lt;br /&gt;&lt;br /&gt;Things, nouns (person, place or thing) that make up our domain.&lt;br /&gt;&lt;br /&gt;Value objects or beans are the traditional objects that represent things in your domain.  For example, one of our applications is called DataMentor, these things comprise its domain,&lt;br /&gt;&lt;ul&gt;&lt;li&gt;assessments&lt;/li&gt;&lt;li&gt;resources&lt;br /&gt;&lt;/li&gt;&lt;li&gt;users&lt;br /&gt;&lt;/li&gt;&lt;li&gt;standards&lt;br /&gt;&lt;/li&gt;&lt;li&gt;institutions&lt;br /&gt;&lt;/li&gt;&lt;li&gt;scores&lt;br /&gt;&lt;/li&gt;&lt;li&gt;examples&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Each of these value objects has getter and setter attributes that allow the outside world to see or update them.  Each of the value objects has a constructor method that initializes the object and sends back a reference to it. The constructor methods usually also sets the values of the attributes referenced by the getter, setter methods.&lt;br /&gt;&lt;br /&gt;Typically, each value object has a service object that is referenced by the application who requests to communicate with it. Remember that value objects are not very social, they only like to be spoken too by their own service.  The service is the more social of the two, it likes to talk to its own value bean but also to other services too.&lt;br /&gt;&lt;br /&gt;Value objects have 'state' which means they change within a session (the time a person spends using our application).  In our application, we use state assessments.  If a teacher is looking at different assessments, each time one is chosen,  its 'state' should change, the details of the assessment would come from the database and the getter methods for each of the attributes would be called, updating the state of the object.&lt;br /&gt;&lt;br /&gt;In our application, a user chooses an institution, a request is made to the database to get the details of the institution.  Then the institution service is called to update the state of the institution value object (bean).  The service calls the DAO which calls the setter methods for the institution value bean.   This process of getting and updating institution details via services, DAO and value beans is repeated whenever a new institution is selected.&lt;br /&gt;&lt;br /&gt;2 - Service or Infrastructure&lt;br /&gt;&lt;br /&gt;These objects are singletons and have no state.  They exist to serve the value objects.  They are created once and do not change during the user session, used per-application.  They may cache data, because once its state is created, it does not change, requests to refresh itself do not occur.&lt;br /&gt;These objects live to serve the value objects in step 1.  If a value object needs to be written to a database or refreshed from a database, the value object speaks to the service layer which speaks to the data access layer which speaks to the database.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Service layer objects are social, they like to speak to other objects, like listeners, controllers, data access models and other services.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are inherent dependencies between the value and service objects.  A value object needs a service object, a DAO needs a service object and the DAO object may need a data source object.  These dependencies are difficult to manage, a object management framework like coldSpring can help.  A common problem is tight coupling between the objects which means knowledge of each other is required to operate.&lt;br /&gt;&lt;br /&gt;Often we use design patterns like Factory Pattern to solve common problems like this.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Factory Pattern&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A factory makes things, like widgets, wadgets and objects.  The factory knows about dependencies and manages them.  The objects in your application DO NOT need to know about each other.  The factory creates the objects and the dependency objects.  This pattern reduces coupling between dependent objects.  &lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;The question arises, who's job is it to know about the other.  For example, who's job is it to ensure that when a service calls a DAO, that the DAO object exist?  Typically, you see code in the constructor of the service that creates the object to the dependent DAO.  This builds coupling between the two and forces the service to maintain application state, which is a best practice no no.  Since the service object has a natural relationship with its DAO or Gateway, a better example might be the service needing information from another object, not its own.  How does the service know if that object exists?  Whose job is it to know this?  Let the factory pattern implemented in a framework like ColdSpring manage the dependency and object creation. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-7000193931034575215?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7000193931034575215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7000193931034575215' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7000193931034575215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7000193931034575215'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/object-differentiation.html' title='Object differentiation'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-2319717362976685295</id><published>2008-05-07T09:40:00.000-07:00</published><updated>2008-05-27T08:22:10.916-07:00</updated><title type='text'>coldspring</title><content type='html'>One of the challenges of a larger &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;OO&lt;/span&gt; application is tracking and managing the state of objects.  I think in many cases objects are created when they &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;dont&lt;/span&gt; need to be, but the developer is not sure or cant find the scope of the current object, so they instantiate a new one (guilty).&lt;br /&gt;&lt;br /&gt;Following &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;OO&lt;/span&gt; best practices like loose coupling (minimal dependency among interacting objects),  promotes object creation and managing of its own state.  In other words, I better be creating a object pointer to other objects that I depend on.  The classic case is a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;DAO&lt;/span&gt; or Gateway data access object that has a service that manages it.  The data access object has a dependency to the service layer.  Without the its service, the application could never use the data access object.  This dependency is often managed in the constructor method of the service.  When the constructor method is called, object pointers are created to the data access layer objects.&lt;br /&gt;&lt;br /&gt;If your application consists of a lot of objects, then lots of these type of dependencies are created and lots of object instantiation calls are made.  Enter &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;coldSpring&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.coldspringframework.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Coldspring&lt;/span&gt; &lt;/a&gt;is itself a framework that plugs into another framework, like mach II.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;ColdSpring&lt;/span&gt; helps to manage all this object instantiation and dependency stuff.  The creation and dependency relationships are removed from the service layer and abstracted away into a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;coldSpring&lt;/span&gt; configuration file, that is registered in the mach ii controller file.&lt;br /&gt;&lt;br /&gt;Read &lt;a href="http://www.briankotek.com/blog/index.cfm/2006/5/31/Why-Use-ColdSpring"&gt;this article&lt;/a&gt; and follow others from this blog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-2319717362976685295?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/2319717362976685295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=2319717362976685295' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2319717362976685295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/2319717362976685295'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/coldspring.html' title='coldspring'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-9109280737102432095</id><published>2008-05-07T08:56:00.000-07:00</published><updated>2008-05-07T09:30:57.997-07:00</updated><title type='text'>machii framework</title><content type='html'>&lt;a href="http://www.mach-ii.com/"&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;Mach II&lt;/span&gt;&lt;/a&gt; is framework that is designed to help manage the complexity of large application design.  &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;Mach II&lt;/span&gt; is the first &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;OO&lt;/span&gt; framework design for &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;Cold Fusion&lt;/span&gt;.  &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;Fuse Box&lt;/span&gt; is an earlier &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;Cold Fusion&lt;/span&gt; framework that was more procedural or linear, using circuits and actions.  &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;&lt;br /&gt;&lt;br /&gt;Mach II&lt;/span&gt; uses a XML based notation that uses a central controller as the &lt;span style="font-weight: bold;"&gt;road map&lt;/span&gt; for the application.  The controller (/config/mach-ii.xml) holds definitions to other parts of the application, like listeners, filters, plug ins and view files.  The main workhorse of the controller is the event.  The application has lots of events, each of which contains all the "work" needed to complete the event request.  Each event is like a small little &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;autonomous&lt;/span&gt; part of the application.  Events lend themselves to web development because almost every action taken in a GUI can be thought of as an event, like clicking a button or choosing from a list or clicking a link.  The directions needed to complete the request are encapsulated in the mach II event. &lt;br /&gt;&lt;br /&gt;The mach II controller file has listeners, filters and plugins registered as part of its configuration.  The Listener, filter and plugin registrations are conceptual pointers to CFC files in the application.  Best practices suggest that the listeners be registered to Services. &lt;br /&gt;&lt;br /&gt;Filters and plugins are special types of CFCs that can be registered within specific events to automate frequently needed code, like login check.&lt;br /&gt;&lt;br /&gt;The controller also has a properties section that contains hard coded values that are used and referenced throughout the application.&lt;br /&gt;&lt;br /&gt;If the event requested needs data then a listener notification is made and a service manager is called, possibly with some arguments or parameters (data needed to process the request).  The service or manager would call into the data access layer which would then in turn call to the persistence layer or the database.  In many cases, the data is then returned from the database to the data access object to the service back to the controller who stored the result in an event argument (variable) that is then consumed or displayed by the presentation layer or view  file.&lt;br /&gt;&lt;br /&gt;MachII implements this type of MVC design patten and is specifically designed to work best with well defined objects that adhere to these principles.&lt;br /&gt;&lt;br /&gt;Event arguments are event specific or scoped variables defined in the event that are available to the listeners and view pages to help control flow or make decisions during execution of the event.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-9109280737102432095?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/9109280737102432095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=9109280737102432095' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/9109280737102432095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/9109280737102432095'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/machii-framework.html' title='machii framework'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-7322399889998587739</id><published>2008-05-07T08:25:00.000-07:00</published><updated>2008-05-07T08:48:10.235-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software design patterns best practices abstraction'/><title type='text'>software design ecosystem</title><content type='html'>Thanks to &lt;a href="http://corfield.org/blog/index.cfm?"&gt;Sean Corfield&lt;/a&gt; for his excellent breakdown and discussion of this topic.  I would like to internalize these concepts more by writing about them in my own words.&lt;br /&gt;&lt;br /&gt;I like the ecosystem analogy that shows the relationship of the parts of a software system or application.  The ecosystem has discrete parts that function independently from the system, but also contribute to the overall health of the entire system.  Each role plays its part and contributes to the general health of the application. &lt;br /&gt;&lt;br /&gt;In the software ecosystem, there are parts such as a database (persistence layer), the model(data layer), with its data access objects like DAOs and Gateways and their services, the controller  (road map to the application and manages requests and directs program flow) and the presentation layer (view files or GUIs).&lt;br /&gt;&lt;br /&gt;Specifically - the controller has registrations or pointers to the presentation files and to the listeners  that then point into the model layer.  The listeners speak to the model layer via a service layer.  The service layer is not really part of the application aside from being registered in the controller.  The service layer should be application agnostic (like Sgt Shultz of Hogens Heroes fame - "i know nothing").  If the service layer only worries about the data layer beneath it, and not about maintaining state for the application, it is much more reusable to other applications and follows design best practices by modeling loose coupling.&lt;br /&gt;&lt;br /&gt;This tiered ecosystem promotes individual health in  each discrete part but also promotes the overall health of the system.  Healthy organs = healthy body.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-7322399889998587739?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/7322399889998587739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=7322399889998587739' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7322399889998587739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/7322399889998587739'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/software-design-ecosystem.html' title='software design ecosystem'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-91444424091499110</id><published>2008-05-07T07:40:00.000-07:00</published><updated>2008-05-27T08:07:03.972-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software design'/><category scheme='http://www.blogger.com/atom/ns#' term='objects'/><title type='text'>Internalizing - software design</title><content type='html'>I attended the cfObjective conference where lots of good new content was presented.  The sessions were packed with details and concepts.  To really grok or get something, you must internalize it, put it into your model, see it the way your brain likes it.  For me, writing it down is the best way to achieve that.  I also like to talk out loud, even more than just thinking about it in my head.  Strange i suppose, but verbalizing does help, writing helps more.  This is one of the main motivations i have to blog stuff.  One of the primary concepts at any software engineering conference would be around OO programming.  Object Oriented.  That means thinking about things in your problem domain as object, not data containers.  I work in education, so i see things like, assessment exams, scores, resources, standards and assets.  Think of them as objects that have attributes that define them and actions that they do.  Think of the attributes as things that describe the object and the actions as things the object can do.  Think of the object and what it does as its interface.  The actions start to inform the interface.  Think of the interface as the way other objects, including you, see the object.  The interface becomes like a public face that is exposed to the outside.  You and other objects can talk to and modify the object through its public face.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Design patterns&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Once you start to build objects you see commonality among them and the need to predict or manage their interactions.  Design patterns help the architect to build predictable manageable scalable solutions.  In other words, use patterns to help build great flexible code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-91444424091499110?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/91444424091499110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=91444424091499110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/91444424091499110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/91444424091499110'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/internalizing-software-design.html' title='Internalizing - software design'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1603489865641920209.post-9189138955642342261</id><published>2008-05-06T12:32:00.000-07:00</published><updated>2008-05-06T12:33:31.542-07:00</updated><title type='text'>design patterns</title><content type='html'>I recently attended the cfobjective conference.  Blogging helps me internalize concepts presented, so here goes.&lt;br /&gt;&lt;br /&gt;First thanks to Kurt W, Peter and Matt Woodward for the workshop in machii.  Also, Sean Corfield for the excellent description and illustration around design patterns.&lt;br /&gt;&lt;br /&gt;Why design patterns?&lt;br /&gt;&lt;br /&gt;Promote tiered development, which promotes the separation of parts of the application.  The bus. logic is separated from the database logic which is separated from the presentation logic.  This makes the application easier to troubleshoot, support, add new things to etc.&lt;br /&gt;&lt;br /&gt;A very common design pattern is &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;MVC&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Programmers can work on different areas of the same application at the same time.  One programmer can work on the bus. logic while another is working the presentation layer while a third is working in the database.&lt;br /&gt;&lt;br /&gt;Less experienced programmers will typically not see the value in the tiered approach to software design.  They will put the logic or code into a single of set of files, grouping together database, business and presentation layer code or logic.  This approach is adequate if the application is a one time shot, never to be added to or updated again.  If the application grows, the code becomes more difficult to maintain and troubleshoot as new code and logic is added.  If a new programmer comes on to maintain, more difficulties arise because there are no standards followed.&lt;br /&gt;&lt;br /&gt;More experienced programmers see the pay off and need for a well tiered application.  As new requirements come along and new programmers are introduced to the application, code separation and predictability become more valued.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1603489865641920209-9189138955642342261?l=james-softwaredesign.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://james-softwaredesign.blogspot.com/feeds/9189138955642342261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1603489865641920209&amp;postID=9189138955642342261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/9189138955642342261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1603489865641920209/posts/default/9189138955642342261'/><link rel='alternate' type='text/html' href='http://james-softwaredesign.blogspot.com/2008/05/design-patterns.html' title='design patterns'/><author><name>james</name><uri>http://www.blogger.com/profile/15146587870971426549</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
