<?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-21981243</id><updated>2011-11-27T15:14:46.689-08:00</updated><category term='DataClass'/><category term='DataConstructor'/><title type='text'>Max Guernsey, III</title><subtitle type='html'>Suffer not a fool to live</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>73</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-21981243.post-8377238473591749897</id><published>2011-11-13T22:43:00.001-08:00</published><updated>2011-11-13T22:47:38.873-08:00</updated><title type='text'>Liberate Wall Street</title><content type='html'>Are you tired of the Occupy movement? &amp;nbsp;I am. &amp;nbsp;It looks to me like a bunch of dirty hippies whining about the fact that they bought houses they can't afford and created an economic meltdown. &amp;nbsp;How the hell is that Wall Street's fault?&lt;br /&gt;&lt;br /&gt;Occupiers: You jackasses committed fraud and got away with it. &amp;nbsp;Or, at the very least, your mortgage brokers did. &amp;nbsp;Sure. &amp;nbsp;There was a little bit of economic fallout from your decisions and the Wall Street people definitely didn't do anything to arrest the downturn you created. &amp;nbsp;That hardly entitles you guys to bitch about them. &amp;nbsp;It's not their job to look out for you.&lt;br /&gt;&lt;br /&gt;Here's what I think we should do. &amp;nbsp;We have a long history of liberating pansies who can't seem to take it upon themselves to fight back when occupied; most notably the French. &amp;nbsp;Why don't we get together as Americans and start liberating Occupied spaces? &amp;nbsp;We can start where it all began: Wall Street.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Liberate Wall Street!&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-8377238473591749897?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/8377238473591749897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/11/liberate-wall-street.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8377238473591749897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8377238473591749897'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/11/liberate-wall-street.html' title='Liberate Wall Street'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/07378097426969863070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/-2JR_N_vVnwk/TdlOjwe1LDI/AAAAAAAAAAM/9ibVMZO9yW4/s220/Max%2BGuernsey%2B-%2BPublicity%2BPhoto%2B-%2BWeb.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-133529263868116345</id><published>2011-11-13T08:45:00.001-08:00</published><updated>2011-11-13T08:50:59.419-08:00</updated><title type='text'>The Gift that Keeps on Giving</title><content type='html'>Christmas is approaching as rapidly as ever. &amp;nbsp;In fact, it's approaching at exactly the same pace it always have and probably always will. &amp;nbsp;I don't know what everyone wants but I do know what most people&amp;nbsp;desperately&amp;nbsp;need. &amp;nbsp;They need the thing that helps them get through life, cold and twisted a thing as it is.&lt;br /&gt;&lt;br /&gt;Unfortunately, if you're in the ninety-nine percent who don't seem to have this, nobody can give it to you. &amp;nbsp;That is, nobody can give it to you but you.&lt;br /&gt;&lt;br /&gt;This year, give yourself the gift that keeps on giving: a&amp;nbsp;fucking&amp;nbsp;sense of humor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-133529263868116345?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/133529263868116345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/11/gift-that-keeps-on-giving.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/133529263868116345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/133529263868116345'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/11/gift-that-keeps-on-giving.html' title='The Gift that Keeps on Giving'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/07378097426969863070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/-2JR_N_vVnwk/TdlOjwe1LDI/AAAAAAAAAAM/9ibVMZO9yW4/s220/Max%2BGuernsey%2B-%2BPublicity%2BPhoto%2B-%2BWeb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-3877926026779000047</id><published>2011-11-12T16:52:00.001-08:00</published><updated>2011-11-12T17:07:26.549-08:00</updated><title type='text'>The Reason for the Season</title><content type='html'>Hey everybody! &amp;nbsp;Thanksgiving is coming up and I'm very excited. &amp;nbsp;Of course, there's the feast but it's also a special day on which we all get together and celebrate the circumstances that afford us this free and comfortable lifestyle to which we have all grown so accustomed.&lt;br /&gt;&lt;br /&gt;So this year, invite everyone you love to come over to your place. &amp;nbsp;Gather around the table. &amp;nbsp;Join hands. &amp;nbsp;Pray, if you're the religious sorts. &amp;nbsp;However you do it give thanks for the thing that allowed us to be us. &amp;nbsp;Was it Columbus? &amp;nbsp;No. &amp;nbsp;Was it the corn and beans thing? &amp;nbsp;I think not.&lt;br /&gt;&lt;br /&gt;I wouldn't waste any precious thanks on those things. &amp;nbsp;Instead, let's remember how it really happened and let that remind us of who we really are. &amp;nbsp;We're the people who figured out how to make blankets into a weapon of mass destruction because winning a war with bullets, cannons, superior infrastructure, and trick beads wasn't going fast enough.&lt;br /&gt;&lt;br /&gt;This Thanksgiving, instead of saying "Happy Thanksgiving," why not something that rings a little more true:&lt;br /&gt;&lt;br /&gt;"They never knew what hit them."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-3877926026779000047?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/3877926026779000047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/11/reason-for-season.html#comment-form' title='27 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3877926026779000047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3877926026779000047'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/11/reason-for-season.html' title='The Reason for the Season'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/07378097426969863070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/-2JR_N_vVnwk/TdlOjwe1LDI/AAAAAAAAAAM/9ibVMZO9yW4/s220/Max%2BGuernsey%2B-%2BPublicity%2BPhoto%2B-%2BWeb.jpg'/></author><thr:total>27</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-5873517047752037290</id><published>2011-11-07T21:18:00.001-08:00</published><updated>2011-11-07T21:18:41.809-08:00</updated><title type='text'>"5 Whys" on the Economic Meltdown</title><content type='html'>&lt;span class="Apple-style-span" style="background-color: white; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 11px; line-height: 14px; text-align: left;"&gt;The economy crashed.&lt;/span&gt;&lt;br style="background-color: white; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 11px; line-height: 14px; text-align: left;" /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 11px; line-height: 14px; text-align: left;"&gt;Why? Because banks were profiteering off of loans the borrowers couldn't afford.&lt;/span&gt;&lt;br style="background-color: white; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 11px; line-height: 14px; text-align: left;" /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 11px; line-height: 14px; text-align: left;"&gt;Why? Because people were borrowing more than they could afford.&lt;/span&gt;&lt;br style="background-color: white; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 11px; line-height: 14px; text-align: left;" /&gt;&lt;span class="text_exposed_show" style="background-color: white; display: inline; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 11px; line-height: 14px; text-align: left;"&gt;Why? Because prices were sky-rocketing.&lt;br /&gt;Why? Because government created artificially low interest rates.&lt;br /&gt;Why? Because the economy crashed.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-5873517047752037290?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/5873517047752037290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/11/5-whys-on-economic-meltdown.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5873517047752037290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5873517047752037290'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/11/5-whys-on-economic-meltdown.html' title='&quot;5 Whys&quot; on the Economic Meltdown'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/07378097426969863070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/-2JR_N_vVnwk/TdlOjwe1LDI/AAAAAAAAAAM/9ibVMZO9yW4/s220/Max%2BGuernsey%2B-%2BPublicity%2BPhoto%2B-%2BWeb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-5068998451498620764</id><published>2011-10-16T09:53:00.000-07:00</published><updated>2011-10-16T09:53:37.248-07:00</updated><title type='text'>Occupy the Slippery Slope</title><content type='html'>"You know what? &amp;nbsp;Maybe it's not just the top 1% who's the problem. &amp;nbsp;That second percent is pretty rich and therefore responsible for my lot in life, too." &amp;nbsp;It's not unlikely that the #Occupy movement will take that turn and this is what it looks like...&lt;br /&gt;&lt;br /&gt;1% becomes 2%.&lt;br /&gt;2% becomes 4%.&lt;br /&gt;4% becomes 10%.&lt;br /&gt;10% becomes 25%.&lt;br /&gt;25% becomes 49%.&lt;br /&gt;&lt;br /&gt;Nearly half of all Americans would be screwed by them trying to "make things fair."&lt;br /&gt;&lt;br /&gt;Then, if they get what they want (read their literature), we'll have full scale communism which screws almost everyone all the time.&lt;br /&gt;&lt;br /&gt;So here is my modest call to action. &amp;nbsp;Go to the places where they are organizing and counter organize. &amp;nbsp;Help them see that they are their own problem and nobody else is responsible for the choices they make but them. &amp;nbsp;Be relentless with your reason and maybe we can avert the storm they are gathering.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-5068998451498620764?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/5068998451498620764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/10/occupy-slippery-slope.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5068998451498620764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5068998451498620764'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/10/occupy-slippery-slope.html' title='Occupy the Slippery Slope'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-4645798872038082769</id><published>2011-08-10T11:46:00.000-07:00</published><updated>2011-08-10T11:46:39.510-07:00</updated><title type='text'>I think it's time to invade China</title><content type='html'>Check this out:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.hbr.org/cs/2011/08/apple_stores_in_china_the_one.html"&gt;http://blogs.hbr.org/cs/2011/08/apple_stores_in_china_the_one.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I know how we could enforce trademarks over there. &amp;nbsp;We could threaten to default on our loans to them. &amp;nbsp;We could place an embargo on them. &amp;nbsp;We could start a good ol'fashion war with them. &amp;nbsp;It's about time a World War didn't start in&amp;nbsp;Europe, anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-4645798872038082769?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/4645798872038082769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/08/i-think-its-time-to-invade-china.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4645798872038082769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4645798872038082769'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/08/i-think-its-time-to-invade-china.html' title='I think it&apos;s time to invade China'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-4241956272160918694</id><published>2011-07-28T08:16:00.001-07:00</published><updated>2011-07-28T08:16:20.930-07:00</updated><title type='text'>Term Coined</title><content type='html'>A very short while ago, a friend of mind posed this question: "What do you call a handjob from a chick with no hands?"&lt;br /&gt;&lt;br /&gt;After numerous trials and errors, we came up with this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.urbandictionary.com/define.php?term=chernobyl+stump+stroke"&gt;http://www.urbandictionary.com/define.php?term=chernobyl+stump+stroke&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-4241956272160918694?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/4241956272160918694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/07/term-coined.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4241956272160918694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4241956272160918694'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/07/term-coined.html' title='Term Coined'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-615319832207603747</id><published>2011-07-09T18:11:00.000-07:00</published><updated>2011-07-09T18:11:33.567-07:00</updated><title type='text'>My Work is Now Cut out for Me</title><content type='html'>Okay. &amp;nbsp;So I let myself get sidetracked on the development of my book as a result of having a lot to do at my current job. &amp;nbsp;That's the bad news. &amp;nbsp;The good news is that everything has been "percolating" during this time and I've come up with &amp;nbsp;a really good mental map of how I'm going to guide the reader through all the problems involved in agile database development.&lt;br /&gt;&lt;br /&gt;Here it is...&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-7ilHnD_b-vU/Thj2gfeuCJI/AAAAAAAAABY/1dhs7ZJDx20/s1600/ThoughtMap2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-7ilHnD_b-vU/Thj2gfeuCJI/AAAAAAAAABY/1dhs7ZJDx20/s320/ThoughtMap2.png" width="277" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Basically, the idea is as follows.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Goals:&lt;/b&gt;&lt;br /&gt;We have the goal of increasing the speed with which value can be delivered by reducing the "bottleneck effect" that generally surrounds database changes. &amp;nbsp;However, we cannot do that at the expense of things we've already gotten good at; namely preserving the knowledge stored in a database and maintaining the availability of its service as experienced by a user via an intermediary application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Obstacles:&lt;/b&gt;&lt;br /&gt;There are risks posed to the things we are already good at by increasing the speed of change. &amp;nbsp;Changing structure, the way we do it now, implies risk to existing knowledge stored in a database. &amp;nbsp;It also introduces the chance that an application coupled to a database might not have had time to adapt to a change in structure by the time a change is rolled out.&lt;br /&gt;&lt;br /&gt;There is also an obstacle to agile database development in that whatever infrastructure is required to mitigate the previously mentioned risks will probably not be available for legacy databases.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;(From the Other Angle) Axioms:&lt;/b&gt;&lt;br /&gt;Databases store knowledge - that is their primary role. &amp;nbsp;To acquire knowledge and make use of it, databases absorb and emit information. &amp;nbsp;Another thing to assume is that people &lt;i&gt;will&lt;/i&gt;&amp;nbsp;make mistakes.&lt;br /&gt;&lt;br /&gt;Here's the big one: databases are objects. &amp;nbsp;They are objects that store knowledge on behalf of other entities, like applications.&lt;br /&gt;&lt;br /&gt;In any environment, where there is risk or instability, test-driven development mitigates those dangers to the point of rendering them almost non-existent. &amp;nbsp;This is especially true in a good object-oriented environment where behaviors can be easily isolated and tested.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution:&lt;/b&gt;&lt;br /&gt;Good object oriented platforms, and really even mediocre ones, provide the notion of a class. &amp;nbsp;That is: an encapsulated, refactorable unit of design that provides a reliable way to instantiate objects with predictable behavior and easy-to-couple-to interfaces.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Implementation:&lt;/b&gt;&lt;br /&gt;We cannot simply take existing mechanisms for defining classes and apply them to databases because the forces around a database are different - they have "inertia" in the form of knowledge that cannot be lost in the course of a design change.&lt;br /&gt;&lt;br /&gt;The core of the implementation is to introduce a predictable, highly structured create-or-upgrade path that minimizes errors, protects existing knowledge, and regulates how change is introduced to any given database instance.&lt;br /&gt;&lt;br /&gt;The next step is to specify exactly how changes are introduced to a database by test-driving them. &amp;nbsp;This all-but-eliminates the chance that a database will lose knowledge in the course of changing its design.&lt;br /&gt;&lt;br /&gt;Once that is accomplished, provide a strong interface for your database to ensure that application developers are warned of breaking changes as soon as they possibly can be. &amp;nbsp;You, yourself, can be warned of these changes by using test-driven development to specify the behavior of the current database.&lt;br /&gt;&lt;br /&gt;Finally, there must be a way to handle errors. &amp;nbsp;This is a function of good database development practices - like taking regular backups - and providing a mechanism for rapidly introducing corrections to errors that have already been committed to production. &amp;nbsp;Once you have that system in place, by definition, you will have a process that can be used to enroll legacy databases into your agile database development process.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-615319832207603747?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/615319832207603747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/07/my-work-is-now-cut-out-for-me.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/615319832207603747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/615319832207603747'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/07/my-work-is-now-cut-out-for-me.html' title='My Work is Now Cut out for Me'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-7ilHnD_b-vU/Thj2gfeuCJI/AAAAAAAAABY/1dhs7ZJDx20/s72-c/ThoughtMap2.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-29391025082561406</id><published>2011-07-08T23:18:00.000-07:00</published><updated>2011-07-08T23:18:20.763-07:00</updated><title type='text'>Where Does the Buck Stop?</title><content type='html'>So I just watched another Michael Moore propaganda film and the theme of individual non-accountability continues.&lt;br /&gt;&lt;br /&gt;I have a question for anyone who is swayed to believe that homeowners are not responsible for the consequences of their actions or that workers aren't responsible for choosing to work a job where they are underpaid.&lt;br /&gt;&lt;br /&gt;If individuals should not be accountable for the consequences of their actions, who should?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-29391025082561406?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/29391025082561406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/07/where-does-buck-stop.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/29391025082561406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/29391025082561406'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/07/where-does-buck-stop.html' title='Where Does the Buck Stop?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-8814167533197638736</id><published>2011-07-05T23:31:00.000-07:00</published><updated>2011-07-05T23:31:28.867-07:00</updated><title type='text'>The Law of Damocles</title><content type='html'>People keep talking about the Law of Demeter. &amp;nbsp;It's a pretty good law - although it seems like a hard one to break in a modern programming environment.&lt;br /&gt;&lt;br /&gt;Anyway, I'd like to propose another law based on a classical mythical character: The Law of Damocles:&amp;nbsp;All code exists with a sword poised above its head.&lt;br /&gt;&lt;br /&gt;Shit code is better deleted than mutated. &amp;nbsp;Ensure the behaviors are properly specified with tests, delete it, and start writing good code until the tests are all green again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-8814167533197638736?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/8814167533197638736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/07/law-of-damocles.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8814167533197638736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8814167533197638736'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/07/law-of-damocles.html' title='The Law of Damocles'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2636725882933413751</id><published>2011-06-19T21:46:00.001-07:00</published><updated>2011-06-19T22:01:45.438-07:00</updated><title type='text'>The Golden Hammer</title><content type='html'>I think I've finally turned up something in my search for a compelling reason to use Ruby rather than something else.  Here is the first argument in favor of it that includes an actual snippet of code that I have found:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://wowkhmer.com/2009/01/20/dotnet-coders-should-give-ruby-a-try/"&gt;http://wowkhmer.com/2009/01/20/dotnet-coders-should-give-ruby-a-try/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think people's insistence on Ruby being a worthwhile thing is based on its expressiveness &lt;i&gt;when defining the behavior of an algorithm&lt;/i&gt;.  Personally, I don't see how the Ruby code in that example is any more expressive than the C# code but that's not the point.  For the sake of argument, I will grant that it somehow might be for some people.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It still doesn't matter.  People are already able to write and understand very complex algorithms.  Making them easier to implement is not a good thing.  For one thing, it optimizes the easiest part of what we do.  For another, it enables programmers with outdated skills sets by allowing them to do what they are comfortable doing: writing "programs" and wrapping them up in objects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Defining algorithms is not what good programmers do.  What good programmers to is encapsulate variation to such an extent that there is no need to define a complex algorithm.  This is very difficult as it requires us to think about things in terms of entities with responsibilities rather than in terms of sequences of steps, some of which are conditionally executed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I think that Ruby is a bit of a golden hammer: It's optimized for how it looks rather than how it functions - it focuses on letting people indulge their bad habits rather than providing an incentive to correct their behaviors.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That is... unless there is some way it enables people to define abstractions and encapsulate variation better than other languages.  If there is, please send me a link to an example demonstrating.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2636725882933413751?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2636725882933413751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/06/golden-hammer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2636725882933413751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2636725882933413751'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/06/golden-hammer.html' title='The Golden Hammer'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/07378097426969863070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/-2JR_N_vVnwk/TdlOjwe1LDI/AAAAAAAAAAM/9ibVMZO9yW4/s220/Max%2BGuernsey%2B-%2BPublicity%2BPhoto%2B-%2BWeb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1946614469108778704</id><published>2011-06-19T21:37:00.000-07:00</published><updated>2011-06-19T21:38:39.503-07:00</updated><title type='text'>A compelling reason to learn Ruby, anyone?</title><content type='html'>I am presently in search of a clear, concise explanation of what advantage Ruby might provide over, say, C# or Java and rock-hard evidence to back up that(those) claim(s).  Any suggestions?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1946614469108778704?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1946614469108778704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/06/compelling-reason-to-learn-ruby-anyone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1946614469108778704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1946614469108778704'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/06/compelling-reason-to-learn-ruby-anyone.html' title='A compelling reason to learn Ruby, anyone?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/07378097426969863070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/-2JR_N_vVnwk/TdlOjwe1LDI/AAAAAAAAAAM/9ibVMZO9yW4/s220/Max%2BGuernsey%2B-%2BPublicity%2BPhoto%2B-%2BWeb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-7564924326391681913</id><published>2011-05-30T16:36:00.000-07:00</published><updated>2011-05-30T16:36:53.631-07:00</updated><title type='text'>I'm tired of hearing how teachers are underpaid</title><content type='html'>Look at &lt;a href="http://www.payscale.com/research/US/All_K-12_Teachers/Salary"&gt;this&lt;/a&gt;. &amp;nbsp;They get full benefits and are paid around $40k/y to work about a thousand hours a year. &amp;nbsp;That means that, in terms of effort that goes in versus money that goes out, they are paid about like a decent programmer on average. &amp;nbsp;If my experience was at all typical, most of them do a terrible job and don't even try to do a good one. &amp;nbsp;Throw into that that there is a mechanism specifically designed to ensure they don't have to do a good job (tenure), and it's a pretty sweet deal.&lt;br /&gt;&lt;br /&gt;I would say being paid comparably to one of the most highly paid professions in our country while not being held to any real standard of quality and, in fact, being explicitly shielded from any such standards puts teachers in the category of "overpaid" rather than "underpaid." &amp;nbsp;If a government wants to cut costs by bringing their pay into alignment with the value they deliver (or at least improving the alignment), then so be it. &amp;nbsp;Don't like it? &amp;nbsp;Find a different job.&lt;br /&gt;&lt;br /&gt;Most of the people who should be teaching children probably aren't in it for the money anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-7564924326391681913?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/7564924326391681913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/05/im-tired-of-hearing-how-teachers-are.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7564924326391681913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7564924326391681913'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/05/im-tired-of-hearing-how-teachers-are.html' title='I&apos;m tired of hearing how teachers are underpaid'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-4907267246994460933</id><published>2011-05-30T16:30:00.001-07:00</published><updated>2011-05-30T16:30:15.265-07:00</updated><title type='text'>Walk away, walk away / I'll be a parade</title><content type='html'>&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-6yKUHadWw6s/TeQoJZg2jLI/AAAAAAAAABU/mBdBL228VxE/s1600/AnotherBridge.bmp" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="147" src="http://4.bp.blogspot.com/-6yKUHadWw6s/TeQoJZg2jLI/AAAAAAAAABU/mBdBL228VxE/s400/AnotherBridge.bmp" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;"Modus Operandi"&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-4907267246994460933?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/4907267246994460933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/05/walk-away-walk-away-ill-be-parade_30.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4907267246994460933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4907267246994460933'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/05/walk-away-walk-away-ill-be-parade_30.html' title='Walk away, walk away / I&apos;ll be a parade'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-6yKUHadWw6s/TeQoJZg2jLI/AAAAAAAAABU/mBdBL228VxE/s72-c/AnotherBridge.bmp' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-4457203423522971251</id><published>2011-05-30T16:29:00.000-07:00</published><updated>2011-05-30T16:29:47.525-07:00</updated><title type='text'>Walk away, walk away / I'll be a parade</title><content type='html'>&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-6yKUHadWw6s/TeQoJZg2jLI/AAAAAAAAABU/mBdBL228VxE/s1600/AnotherBridge.bmp" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-6yKUHadWw6s/TeQoJZg2jLI/AAAAAAAAABU/mBdBL228VxE/s1600/AnotherBridge.bmp" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;"Modus Operandi"&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-4457203423522971251?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/4457203423522971251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/05/walk-away-walk-away-ill-be-parade.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4457203423522971251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4457203423522971251'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/05/walk-away-walk-away-ill-be-parade.html' title='Walk away, walk away / I&apos;ll be a parade'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-6yKUHadWw6s/TeQoJZg2jLI/AAAAAAAAABU/mBdBL228VxE/s72-c/AnotherBridge.bmp' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-4003746809360377024</id><published>2011-05-21T21:04:00.000-07:00</published><updated>2011-05-21T22:04:33.227-07:00</updated><title type='text'>Why TDD Does Not Replace Compilers</title><content type='html'>There is a commonly held belief that the presence of good tests obviates the need for a compiler. &amp;nbsp;It is a myth. &amp;nbsp;It can easily be shown to be false and I will do so in a few paragraphs.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Conceptually&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Before demonstrating in concrete terms why a compiler is still necessary. &amp;nbsp;Now, perhaps it is true that the single task of adding a class to a system of classes might not greatly benefit from the presence of a compiler. &amp;nbsp;It also might not be true. &amp;nbsp;Either way, I'm not going to address it because it's not the hard part of what we do.&lt;br /&gt;&lt;br /&gt;Where a compiler comes in handy in a way that the simple presence of tests cannot help us is in the process of &lt;i&gt;changing&lt;/i&gt;&amp;nbsp;design, not creating it. &amp;nbsp;TDD does not replace design, it augments it by attaching executable specifications to elements thereof.&lt;br /&gt;&lt;br /&gt;Compilers tell you when elements of your design are inconsistent. &amp;nbsp;In ways that tests cannot. &amp;nbsp;At least, in ways that tests cannot do without replicating the purpose and behavior of compilers. &amp;nbsp;They do this by allowing you to create positive coupling that can be validated at compile time.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Duplication&lt;/b&gt;&lt;br /&gt;To really understand the value of a compiler, you have to understand the nature of duplication. &amp;nbsp;Duplication exists whenever you have to make a single change in multiple places.&lt;br /&gt;&lt;br /&gt;Unfortunately, duplication is not actually something we can eliminate altogether. &amp;nbsp;In fact, all the techniques we have been taught for eliminating duplication do not, in fact, eliminate duplication but actually replace uncheckable duplication with coupling - a form of duplication that can be mathematically checked for consistency.&lt;br /&gt;&lt;br /&gt;For instance, the signature of a method and the calls to that method are duplication. &amp;nbsp;There are cases when changing the signature also requires the calls to be changed or requires some other change like creating an overload. &amp;nbsp;However, with a strong-typing system such as you often find with a compiler, you have a mechanism to ensure that all calls are at least basically in sync with the methods they are invoking.&lt;br /&gt;&lt;br /&gt;Duplication doesn't stop you and rarely even slows you down when you are creating something new. &amp;nbsp;It's when you are changing things that duplication becomes a killer. &amp;nbsp;The reason it is a killer because people seldom find all instances of duplication on their own. &amp;nbsp;I refer you to &lt;a href="http://www.netobjectives.com/blogs/shalloways-law-and-shalloways-principle"&gt;Shalloway's Law&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Change&lt;/b&gt;&lt;br /&gt;Healthy products change a great deal. &amp;nbsp;The more useful and important your software is, the more you are going to need to change its design. &amp;nbsp;There's a small irony there, isn't there? &amp;nbsp;The more your software is used, the more it will change. &amp;nbsp;The more it changes, the more the design will change. &amp;nbsp;The more the design changes, the more you will want to keep instances of necessary duplication in sync with one another.&lt;br /&gt;&lt;br /&gt;The key to surviving change in any system of a reasonable size is not to eliminate duplication; that is impossible to do one-hundred percent. &amp;nbsp;Instead, it is to eliminate unnecessary duplication and to comply with &lt;a href="http://www.netobjectives.com/blogs/shalloways-law-and-shalloways-principle"&gt;Shalloway's Principle&lt;/a&gt;&amp;nbsp;(same link as before) in the case of necessary duplication.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dependencies and Strong Typing&lt;/b&gt;&lt;br /&gt;Strong typing, which is typically found in compiled languages, is the only tool we have invented at the time of this writing that combats necessary duplication by linking together all instances of a particular duplication. &amp;nbsp;It's really the strong typing, not the compilation, but at this time the correlation is so strong that you can practically treat them as the same thing, setting aside bastardizations like VB.Net.&lt;br /&gt;&lt;br /&gt;Strongly typed languages tend to do this by allowing programmers to create dependencies&amp;nbsp;that are implied by one entity in a piece of software using another. &amp;nbsp;For instance, all calls to a method depend on the definition of that method. &amp;nbsp;You cannot compile things that call a method without basically correct parameters. &amp;nbsp;Likewise, all references to an instance of a type grant the dependent access to its public methods and allow it to pass the referred-to object around as a parameter to suitable methods.&lt;br /&gt;&lt;br /&gt;These dependencies can then be checked for an entire compilation unit in a single pass, guaranteeing a basic of potential correctness before even bothering to produce a program that can be tested. &amp;nbsp;Note that, if there were a strongly typed, statically checked, non-compiled language, then the programmer would get the same benefits except that it would happen when the script is loaded rather than when the program is compiled. &amp;nbsp;The difference between those two things would be&amp;nbsp;imperceptible&amp;nbsp;to most, if not all, programmers.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Strong, Weak, Explicit,&amp;nbsp;&lt;/b&gt;&lt;b&gt;Implicit,&amp;nbsp;&lt;/b&gt;&lt;b&gt;Static, and Dynamic Typing&lt;/b&gt;&lt;br /&gt;It is also important to note that I am not arguing for or against most of the traits listed in the title of this subsection. &amp;nbsp;I am arguing in favor of strong typing and against weak typing. &amp;nbsp;I don't really care about implicit typing or explicit typing, nor do I care about static or dynamic typing, except to the extent that they may influence a language's ability to be strongly or weakly typed. &amp;nbsp;Let's go over what these various things mean, in case it is not obvious.&lt;br /&gt;&lt;br /&gt;A strongly typed system is one in which types and method calls can be validated prior to the execution of any part of the type system being evaluated. &amp;nbsp;Dependencies are defined in some way (probably by use) that allows the basic compatibility of design elements to be automatically verified with no work required from a programmer beyond defining said design.&lt;br /&gt;&lt;br /&gt;A weakly typed system is one that is not strongly typed. &amp;nbsp;That is, one in which a developer has to do extra work to validate the consistency of relationships between entities in a system or one in which it is not automatically done before a design element can be used.&lt;br /&gt;&lt;br /&gt;An explicitly typed system would be one in which all types, including abstractions, must be explicitly defined. Java and C# are examples of such a system. &amp;nbsp;If you want to create a polymorphic relationship, you have to create some kind of interface that is implemented by variants of the abstraction.&lt;br /&gt;&lt;br /&gt;An implicitly typed system is one in which types, including abstractions, can be inferred by some part of the programming language or environment. &amp;nbsp;A lot of scripting languages do this: you define the interface for an abstraction by how the caller uses implementations. &amp;nbsp;What you may or may not have considered is that C++ also had elements of implicit typing: templates created a &lt;i&gt;de facto&lt;/i&gt;&amp;nbsp;interface between the template-ized thing and its dependencies. &amp;nbsp;Note that the dependencies of a C++ template are still checked at compile-time so implicit typing is, by no means, inextricably linked to strong, weak, static, or dynamic typing.&lt;br /&gt;&lt;br /&gt;A statically typed system is one in which types cannot be redefined at runtime. &amp;nbsp;C#, C++, and Java are all examples of such a language. &amp;nbsp;You define a type and that's that.&lt;br /&gt;&lt;br /&gt;Finally, there are dynamically typed languages. &amp;nbsp;JavaScript would be an example of such a language, where a type could be changed after it has been loaded and even after it has produced an object to be used.&lt;br /&gt;&lt;br /&gt;I don't care whether a language has implicit or explicit types. &amp;nbsp;Nor do I care whether it has static or dynamic typing. &amp;nbsp;I may have a slight bias toward the former in each category but I don't consider it a big problem if a language or platform decides to go the other way. &amp;nbsp;It is specifically the strength or weakness of a language's typing system that matters in the context of this blog entry.&lt;br /&gt;&lt;br /&gt;Strongly typed systems are preferable to weakly typed ones because they aid in refactoring and extension in ways that cannot easily be done using other tools available to date. &amp;nbsp;They do this by forcing us to reconcile instances of necessary duplication before we even bother testing a code change.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Practically&lt;/span&gt;&lt;br /&gt;Hopefully, you are at least intrigued by the theoretical information provided above. &amp;nbsp;However, I recognize that abstract arguments aren't always enough to make one's case so here's a real world example. &amp;nbsp;This is a simple case and, the more complex the case, the more dangerous weakly-typed systems are.&lt;br /&gt;&lt;br /&gt;In this example, we have a template method pattern. &amp;nbsp;The pattern is implemented the classical way (through inheritance) even though I seldom do that in real life. &amp;nbsp;No point getting embroiled in another debate before this one is settled. &amp;nbsp;:)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Setup&lt;/b&gt;&lt;br /&gt;In the weakly-typed language we are using (which I'm making up on the spot to avoid getting into a religious war), we have no way to define an abstract method that ensures all inheritors of our base class implement it.&lt;br /&gt;&lt;br /&gt;Let's look at the base class now:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;class BaseClass&lt;br /&gt;  method DoesSomething(x, y)&lt;br /&gt;    factor = 1&lt;br /&gt;    factor *= ComputeFactorForX(x)&lt;br /&gt;    factor *= ComputeFactorForY(y)&lt;br /&gt;&lt;br /&gt;    return factor&lt;br /&gt;  end method&lt;br /&gt;end class&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now, let's consider one inheritor of this class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;class RarelyUsed extends BaseClass&lt;br /&gt;  method ComputeFactorForX(x)&lt;br /&gt;    return 1 + x * x&lt;br /&gt;  end method&lt;br /&gt;&lt;br /&gt;  method ComputeFactorForY(y)&lt;br /&gt;    return -1 - (y * y)&lt;br /&gt;  end method&lt;br /&gt;end class&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In addition, there are twelve other extensions of &lt;code&gt;BaseClass&lt;/code&gt; which are used very frequently. &amp;nbsp;Let's even go as far as to say that we have a strong suite of acceptance tests that validate the value delivered by the software being developed. &amp;nbsp;Even with such a thing, however, it is impossible to test every combination of every object.&lt;br /&gt;&lt;br /&gt;Now, as I've stated before.  TDD is handy for helping us define the behavior of each of these classes.  It may even allow us to prescribe the relationship between them. &amp;nbsp;What it doesn't do automatically is &lt;i&gt;enforce&lt;/i&gt;&amp;nbsp;the relationship.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Twist&lt;/b&gt;&lt;br /&gt;Let's imagine that we want to test-drive an extension to the behavior of the base class. &amp;nbsp;That is, we want to change the relationship between &lt;code&gt;BaseClass&lt;/code&gt; and its inheritors. &amp;nbsp;TDD allows us to define the behavior as we want and ensure it is done right:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;class BaseClass&lt;br /&gt;  method DoesSomething(x, y, z)&lt;br /&gt;    factor = 1&lt;br /&gt;    factor *= ComputeFactorForX(x)&lt;br /&gt;    factor *= ComputeFactorForY(y)&lt;br /&gt;    factor *= ComputeFactorForZ(z)&lt;br /&gt;    return factor&lt;br /&gt;  end method end class&lt;br /&gt;end class&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;What it doesn't do is make sure that all inheritors of&amp;nbsp;&lt;code&gt;BaseClass&lt;/code&gt; conform to the contract it demands. &amp;nbsp;We have to wait until the real application is put together in order to see if we did everything we need to do. &amp;nbsp;Let's say we just plain forgot the type &lt;code&gt;RarelyUsed&lt;/code&gt;. &amp;nbsp;Why wouldn't we? &amp;nbsp;It is, after all, rarely used and a member of a family of types that is thirteen-large.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Punchline&lt;/b&gt;&lt;br /&gt;How long do we have to wait for that feedback? &amp;nbsp;Ironically, the best-case scenario is: "Forever." &amp;nbsp;In that scenario, the bogus class is never used and will be deleted the next time someone looks at it. &amp;nbsp;The next-best case scenario would be when your automated acceptance tests run. &amp;nbsp;Even that creates an irritatingly-long delay.&lt;br /&gt;&lt;br /&gt;What if it happens during manual testing? &amp;nbsp;The cost of finding and fixing the problem is going to be dozens of times what it would have been if the problem were apparent when making the change originally.&lt;br /&gt;&lt;br /&gt;What if it happens in production? &amp;nbsp;The loss of goodwill is possibly irreparable but probably could be smoothed over. &amp;nbsp;However, the cost of finding and fixing a problem with that kind of delay between introduction and discovery would be astronomical, when compared to the cost of finding and fixing it immediately. &amp;nbsp;We're talking hours or days when compared to seconds or minutes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Rebuttal&lt;/b&gt;&lt;br /&gt;One might argue that one's tests are deficient. &amp;nbsp;For instance, one could have a method that checks for the existence of the required methods on an inheritor of &lt;code&gt;BaseClass&lt;/code&gt;. &amp;nbsp;That method could then be called from a test in the test suite for each inheritor.&lt;br /&gt;&lt;br /&gt;I'll not try and claim that isn't true. &amp;nbsp;It obviously is. &amp;nbsp;My counter-rebuttal is this:&lt;br /&gt;&lt;br /&gt;Yes, you can do that. &amp;nbsp;You can also write your code in assembly and write tests for each method which ensure it is properly formed - that all code paths lead to an exit or to an infinite loop, that it properly puts things in the right registers, etc.&lt;br /&gt;&lt;br /&gt;In fact, you can re-write as many parts of a strong-type-system-checker or a compiler. &amp;nbsp;However, doing so either requires you to write a compiler and then use it from a whole bunch of tests or to duplicate your design in the form of tests.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I think I've made some strong arguments in favor of using a strongly-typed programming language over a weak one. &amp;nbsp;You cannot avoid creating duplication so, in addition to keeping to to the minimum amount necessary, you should use automation to enforce as much consistency between duplicates as possible.&lt;br /&gt;&lt;br /&gt;I've failed, however, to mention the biggest and simplest argument. &amp;nbsp;I've done this partially because I'm saving it for last. &amp;nbsp;Here it is: there's no cost. &amp;nbsp;It's one-hundred percent free to use a strongly typed language instead of a weakly typed one.&lt;br /&gt;&lt;br /&gt;At least, that's how all the proponents of weakly-typed languages seem to make things look. &amp;nbsp;You see. &amp;nbsp;I've spent days trying to get people who don't like type-safety to explain one advantage of not having it. &amp;nbsp;Nobody - not one person I've talked to - has been able to identify a single reason why it even &lt;i&gt;might&lt;/i&gt;&amp;nbsp;be better to have a language be weakly typed than it is to have it be strongly-typed.&lt;br /&gt;&lt;br /&gt;The closest anyone has come has been something along the lines of "it's more challenging, so I work harder and with more focus." &amp;nbsp;Languages should not provide the challenge. &amp;nbsp;There are plenty of real challenges: getting your tests right, creating a good design, and aligning implementation with business value, to name a few. &amp;nbsp;We don't need made-up challenges coming from languages that represent a big step backward.&lt;br /&gt;&lt;br /&gt;So here is my final argument: I've shown that there is an advantage to having a strongly typed system. &amp;nbsp;I submit that until a single, real advantage of weak typing can be identified, that tips the scales in favor of strong typing. &amp;nbsp;If someone can come up with a strongly typed language that is also implicitly typed and/or dynamically typed, then that should be considered to be a competitor to real languages like Java, C#, and Go.&lt;br /&gt;&lt;br /&gt;TDD allows you to use a language more effectively than you could without it but cannot make up for fundamental deficiencies in that language. &amp;nbsp;One such deficiency that is presently en vogue is the absence of a strong typing system. &amp;nbsp;You can mitigate that deficiency by writing numerous additional tests but at a number of great costs.&lt;br /&gt;&lt;br /&gt;Just because you write good tests doesn't mean you cannot benefit from a compiler or something that fills a similar role and nobody has been able to show me how you could possibly benefit from not having one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-4003746809360377024?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/4003746809360377024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/05/why-tdd-does-not-replace-compilers.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4003746809360377024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4003746809360377024'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/05/why-tdd-does-not-replace-compilers.html' title='Why TDD Does Not Replace Compilers'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-804654945796236805</id><published>2011-03-12T10:55:00.000-08:00</published><updated>2011-03-12T10:58:41.224-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DataClass'/><title type='text'>A mile stone in the long road</title><content type='html'>&lt;a href="http://dataclass.hexsw.com/"&gt;DataC&lt;span id="goog_2145537791"&gt;&lt;/span&gt;&lt;span id="goog_2145537792"&gt;&lt;/span&gt;lass&lt;/a&gt; now supports Java. &amp;nbsp;It took a lot longer than I expected but it's done now.&lt;br /&gt;&lt;br /&gt;You might be thinking "that's neat but what does it mean that it 'supports Java'?"&lt;br /&gt;&lt;br /&gt;Before I answer that, I'll briefly remind you what DataClass does - just in case you stumbled on this entry by accident and don't already know. &amp;nbsp;DataClass is a compiler that takes documents that describe a&amp;nbsp;&lt;a href="http://dataclass.hexsw.com/Documentation/Concept/dbclass"&gt;class of database&lt;/a&gt; and produces binaries that know how to build and interact with instances of that class. &amp;nbsp;The point is to give you the same ease of development you would have for any other class of objects; for instance, allowing you to quickly spin up test instances with identical behavior to production instances.&lt;br /&gt;&lt;br /&gt;Following is an example of a DataClass source document:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: lightgray; font-size: 90%; font: courier; margin-bottom: 0; margin-top: 0; padding-bottom: 0; padding-top: 0;"&gt;database SomeDB {&lt;br /&gt;  types int as integer;&lt;br /&gt;&lt;br /&gt;  version 1.0 : initialized {&lt;br /&gt;    design {&lt;br /&gt;      public table T {&lt;br /&gt;        public column X with DataType = type(int);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    construction { &lt;br /&gt;      step sql { $[T.Declaration] }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  current version 1.1 : 1.0 {&lt;br /&gt;    design {&lt;br /&gt;      public table T : base.T {&lt;br /&gt;        public column Y with DataType = type(int);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    construction { &lt;br /&gt;      step sql { ALTER TABLE $[T] ADD $[T.Y.Declaration] }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That would create a class called SomeDB that knew about two versions of a database design, knew how to build and/or upgrade databases to either of those versions, and had a body of symbols allowing clients to couple to public aspects of each of SomeDB's various designs (1.0 and 1.1). &amp;nbsp;If stored procedures were involved, there would be a proxy for each version that allowed clients to call these stored procedures as if they were normal methods on a normal object.&lt;br /&gt;&lt;br /&gt;Up until build 20.11.1733, DataClass would only produce .NET assemblies that connected to a database through ADO.NET. &amp;nbsp;This most recent build, however, added the ability to produce database proxies and constructors in a java JAR file.&lt;br /&gt;&lt;br /&gt;This involved a significant amount of refactoring before it could readily be supported. &amp;nbsp;I had to encapsulate all the variation between Java and C# (not too hard), between the JRE and the CLR (there's a fair amount), and between JDBC and ADO.NET (they work in fundamentally different ways).&lt;br /&gt;&lt;br /&gt;The really disappointing thing about this was that I discovered how fundamentally different JDBC and ADO.NET were very late in the game. &amp;nbsp;In ADO.NET, access to schema information and binding by name are both easy and reliable. &amp;nbsp;In JDBC it appears to be expected that you will bind by position - something I thought we left behind two decades ago - because binding by name is possible for certain providers but not guaranteed.&lt;br /&gt;&lt;br /&gt;Anyway, that was a problem I could work around pretty easily. &amp;nbsp;DataClass uses the logical position of a parameter or column to infer its physical position. &amp;nbsp;There are, I'm sure, times that this will not suffice. &amp;nbsp;In such cases, developers can use the PhysicalPosition attribute to dictate the binding position of a parameter or a column. &amp;nbsp;That might look something like the following:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: lightgray;"&gt;public procedure MyProcedure {&lt;br /&gt;  // Inferred: PhysicalPosition = 1&lt;br /&gt;  public parameter F;&lt;br /&gt;  // Inferred: PhysicalPosition = 2&lt;br /&gt;  public parameter G;&lt;br /&gt;  // Explicitly: PhysicalPosition = 0&lt;br /&gt;  public parameter H with PhysicalPosition = 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Another "gotcha" for Java programmers is the fact that DataClass expects physical positions to be zero-based and adjusts accordingly for the platform. &amp;nbsp;So, even though the first parameter is parameter 1 when binding via JDBC, you must specify it as parameter 0. &amp;nbsp;I guess the point is this: don't take JDBC's implementation details into account as DataClass hides them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-804654945796236805?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/804654945796236805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/03/mile-stone-in-long-road.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/804654945796236805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/804654945796236805'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/03/mile-stone-in-long-road.html' title='A mile stone in the long road'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-3387386245290125760</id><published>2011-03-04T21:02:00.000-08:00</published><updated>2011-03-04T21:02:01.482-08:00</updated><title type='text'>Do not trust CodeMaid</title><content type='html'>She steals CodeSilverware.&lt;br /&gt;&lt;br /&gt;Seriously, though: CodeMaid appears to randomly delete using statements. &amp;nbsp;I've done a little work to uncover the root cause and identify a fix: it is not ready for production use; uninstall it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-3387386245290125760?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/3387386245290125760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/03/do-not-trust-codemaid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3387386245290125760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3387386245290125760'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/03/do-not-trust-codemaid.html' title='Do not trust CodeMaid'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-7767939219745528307</id><published>2011-02-01T17:05:00.000-08:00</published><updated>2011-02-01T17:05:59.574-08:00</updated><title type='text'>DataClass now available</title><content type='html'>It's been a long haul but I think it was well worth it. &amp;nbsp;&lt;a href="http://dataclass.hexsw.com/"&gt;DataClass&lt;/a&gt; is now available for&amp;nbsp;&lt;a href="http://www.hexsw.com/Products/Compilers/DataClass/Download.aspx"&gt;download&lt;/a&gt;,&amp;nbsp;&lt;a href="http://www.hexsw.com/Products/Compilers/DataClass/Try.aspx"&gt;trial&lt;/a&gt;, or &lt;a href="http://www.hexsw.com/Products/Compilers/DataClass/BuyNow.aspx"&gt;purchase&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-7767939219745528307?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/7767939219745528307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/02/dataclass-now-available.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7767939219745528307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7767939219745528307'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/02/dataclass-now-available.html' title='DataClass now available'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-7656389004037490706</id><published>2011-01-17T07:08:00.000-08:00</published><updated>2011-01-17T07:08:39.925-08:00</updated><title type='text'>Conference Submissions: What to Do with the Rest?</title><content type='html'>I was looking through the &lt;a href="http://submit2011.agilealliance.org/proposals"&gt;Agile 2011 submissions&lt;/a&gt;&amp;nbsp;and I noticed something. &amp;nbsp;A lot of them are pretty interesting, well thought out ideas. &amp;nbsp;I do not envy the chairs of the various stages their task. &amp;nbsp;They are going to have to make tough decisions about which good talks to include in the conference and who they tell "great idea but there's just no time."&lt;br /&gt;&lt;br /&gt;It occurred to me that one mitigation for this might be if conferences like this started soliciting papers from the talks that &lt;i&gt;didn't&lt;/i&gt;&amp;nbsp;make it and collected them into a book (or collection of booklets). &amp;nbsp;That way, all the neat ideas that didn't make the cut could still find their way out into the world. &amp;nbsp;If done right, the conference could make a little profit off of coordinating their release.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-7656389004037490706?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/7656389004037490706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/01/conference-submissions-what-to-do-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7656389004037490706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7656389004037490706'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/01/conference-submissions-what-to-do-with.html' title='Conference Submissions: What to Do with the Rest?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-4183557473314586883</id><published>2011-01-08T21:14:00.000-08:00</published><updated>2011-01-08T21:14:06.695-08:00</updated><title type='text'>Agile Database Development: From Requirements to Delivery</title><content type='html'>I've received, signed, and returned a contract for my upcoming book, &lt;i&gt;Agile Database Development: From Requirements to Delivery&lt;/i&gt;, scheduled for release in 2012. We'll see whether the "From Requirements to Delivery" part of the title survives the book development process. Regardless, the scope of the book will run that gamut.&lt;br /&gt;&lt;br /&gt;Something I've noticed - and I really noticed this when I got my first publication contract for &lt;a href="http://www.informit.com/store/product.aspx?isbn=032163604X"&gt;Transition Testing: Cornerstone of Database Agility&lt;/a&gt; - is that there is nothing like a contract to focus your attention on a project.  It's not even the deadline, which I feel was extremely generous on the part of my publisher.  It's those words that rattle around in the back of your mind...&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;&lt;br /&gt;This is really happening.  The ball is in your court, now.&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;There is nothing like it to motivate someone.  At least, there is nothing like it to motivate me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-4183557473314586883?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/4183557473314586883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/01/agile-database-development-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4183557473314586883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4183557473314586883'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/01/agile-database-development-from.html' title='Agile Database Development: From Requirements to Delivery'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-5730766131243044748</id><published>2011-01-01T22:06:00.000-08:00</published><updated>2011-01-01T22:06:17.465-08:00</updated><title type='text'>Submissions for Agile 2011 Entered</title><content type='html'>Hi Everyone,&lt;br /&gt;&lt;br /&gt;I've made three entries into the Agile 2011 submission system:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://submit2011.agilealliance.org/node/8746"&gt;Fundamentals of Agile Database Development&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://submit2011.agilealliance.org/node/8752"&gt;Goad Testing: Guaranteeing that Tests Make Distinctions&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://submit2011.agilealliance.org/node/8753"&gt;A New Perspective on Automated Tests: Tests as Increments of Process Improvement&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;I'd love any review and feedback that anyone may offer.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-5730766131243044748?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/5730766131243044748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2011/01/submissions-for-agile-2011-entered.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5730766131243044748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5730766131243044748'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2011/01/submissions-for-agile-2011-entered.html' title='Submissions for Agile 2011 Entered'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-9070759432780695762</id><published>2010-12-29T16:17:00.000-08:00</published><updated>2010-12-29T16:17:22.929-08:00</updated><title type='text'>A Pretty Functional Dynamic Proxy for jni4net</title><content type='html'>Wish you could use the dynamic keyword to access java objects created using jni4net? &amp;nbsp;I use this class to do that. &amp;nbsp;Feel free to reproduce it, modify it, or incorporate it into your own products so long as you don't claim that it is "yours" and start suing other people who use it.&lt;br /&gt;&lt;br /&gt;It's cut-and-pasted out of my code so there's no guarantee that you won't need to tweak it a little.  One might say it's pretty much guaranteed that you will.  :)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;using net.sf.jni4net;&lt;br /&gt;using System.Dynamic;&lt;br /&gt;&lt;br /&gt;public class JavaObjectProxyFactory&lt;br /&gt;{&lt;br /&gt;  public class JavaObjectProxy : DynamicObject&lt;br /&gt;  {&lt;br /&gt;    private readonly java.lang.Object o;&lt;br /&gt;    private readonly java.lang.Class c;&lt;br /&gt;&lt;br /&gt;    private JavaObjectProxy(&lt;br /&gt;      java.lang.Object o,&lt;br /&gt;      java.lang.Class c)&lt;br /&gt;    {&lt;br /&gt;      this.o = o;&lt;br /&gt;      this.c = c;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static dynamic GetInstance(&lt;br /&gt;      java.lang.Object o,&lt;br /&gt;      java.lang.Class c)&lt;br /&gt;    {&lt;br /&gt;      return new JavaObjectProxy(o, c);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override bool TryGetMember(&lt;br /&gt;      GetMemberBinder binder,&lt;br /&gt;      out object result)&lt;br /&gt;    {&lt;br /&gt;      var field = c.getField(binder.Name);&lt;br /&gt;&lt;br /&gt;      if (field == null)&lt;br /&gt;      {&lt;br /&gt;        result = null;&lt;br /&gt;        return false;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      result = ConvertToDotNetObject(field.get(o));&lt;br /&gt;&lt;br /&gt;      return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override bool TrySetMember(&lt;br /&gt;      SetMemberBinder binder,&lt;br /&gt;      object value)&lt;br /&gt;    {&lt;br /&gt;      var field = c.getField(binder.Name);&lt;br /&gt;&lt;br /&gt;      if (field == null)&lt;br /&gt;      {&lt;br /&gt;        return false;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      field.set(o, ConvertToJavaObject(value));&lt;br /&gt;      return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override bool TryInvokeMember(&lt;br /&gt;      InvokeMemberBinder binder,&lt;br /&gt;      object[] args,&lt;br /&gt;      out object result)&lt;br /&gt;    {&lt;br /&gt;      var signature = new java.lang.Class[&lt;br /&gt;        binder.CallInfo.ArgumentCount];&lt;br /&gt;      var arguments = new java.lang.Object[&lt;br /&gt;        binder.CallInfo.ArgumentCount];&lt;br /&gt;&lt;br /&gt;      for (var i = 0; i &lt; args.Length; ++i)&lt;br /&gt;      {&lt;br /&gt;        java.lang.Object arg = &lt;br /&gt;          ConvertToJavaObject(args[i]);&lt;br /&gt;        if (arg != null)&lt;br /&gt;        {&lt;br /&gt;          signature[i] = arg.getClass();&lt;br /&gt;          arguments[i] = arg;&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      var method = c.getMethod(binder.Name, signature);&lt;br /&gt;      if (method == null)&lt;br /&gt;      {&lt;br /&gt;        result = null;&lt;br /&gt;        return false;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      result = ConvertToDotNetObject(&lt;br /&gt;        method.invoke(o, arguments));&lt;br /&gt;&lt;br /&gt;      return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private object ConvertToDotNetObject(&lt;br /&gt;      java.lang.Object o)&lt;br /&gt;    {&lt;br /&gt;      if (o == null)&lt;br /&gt;      {&lt;br /&gt;        return null;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      if (o is java.lang.String)&lt;br /&gt;      {&lt;br /&gt;        var s = (java.lang.String)o;&lt;br /&gt;        return new string(s.toCharArray());&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      return GetDynamicProxy(o);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private java.lang.Object ConvertToJavaObject(&lt;br /&gt;      object p)&lt;br /&gt;    {&lt;br /&gt;      if (p == null)&lt;br /&gt;      {&lt;br /&gt;        return null;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      if (p is string)&lt;br /&gt;      {&lt;br /&gt;        return new java.lang.String((string)p);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      return (java.lang.Object)p;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static dynamic GetDynamicProxy(&lt;br /&gt;    java.lang.Object o)&lt;br /&gt;  {&lt;br /&gt;    if (o == null)&lt;br /&gt;    {&lt;br /&gt;      return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return JavaObjectProxy.GetInstance(o, o.getClass());&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-9070759432780695762?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/9070759432780695762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/12/pretty-functional-dynamic-proxy-for.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/9070759432780695762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/9070759432780695762'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/12/pretty-functional-dynamic-proxy-for.html' title='A Pretty Functional Dynamic Proxy for jni4net'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2081120030090573839</id><published>2010-12-17T09:02:00.001-08:00</published><updated>2010-12-17T09:02:10.947-08:00</updated><title type='text'>"Happy Holidays" is what terrorists say.  Merry Christmas!</title><content type='html'>Even though I'm not a Christian, merry Christmas everyone.&lt;br /&gt;&lt;br /&gt;As a gift to the public at large, I've lowered the price of the&amp;nbsp;&lt;a href="http://www.lulu.com/product/file-download/goad-testing-deepening-our-understanding-of-automated-tests/6396355"&gt;Goad Testing&lt;/a&gt;&amp;nbsp;PDF to&amp;nbsp;free. &amp;nbsp;So get your copy now.&lt;br /&gt;&lt;br /&gt;-- Max&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2081120030090573839?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2081120030090573839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/12/happy-holidays-is-what-terrorists-say.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2081120030090573839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2081120030090573839'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/12/happy-holidays-is-what-terrorists-say.html' title='&quot;Happy Holidays&quot; is what terrorists say.  Merry Christmas!'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1932194767412936049</id><published>2010-08-12T00:44:00.000-07:00</published><updated>2010-08-12T00:44:52.340-07:00</updated><title type='text'>United Airlines: An Example of Why Airlines must be Allowed to Fail</title><content type='html'>United Airlines just fucked away an entire day of travel for me and managed to not get me anywhere.&lt;br /&gt;&lt;br /&gt;I guess it's my fault, really. &amp;nbsp;How silly was it of me to think that eighteen hours was enough time to transport me three hundred miles.&lt;br /&gt;&lt;br /&gt;On the other hand, you do have to cut me a little slack because I could have driven to San Francisco from Bend and checked in to my hotel in the time it took United to decide they weren't going to send us where we paid to go.&lt;br /&gt;&lt;br /&gt;So here's what happened. &amp;nbsp;I showed up a good two hours early. &amp;nbsp;You know... like you're supposed to. &amp;nbsp;I was told there was going to be a "slight delay" of two hours. &amp;nbsp;"Okay," I said. &amp;nbsp;"That's okay. &amp;nbsp;That's why I am giving myself so much time to get where I need to go."&lt;br /&gt;&lt;br /&gt;The idea was to give myself enough time to ensure that the airlines couldn't possibly screw up my very important trip. &amp;nbsp;Long story short: I'm pissing and moaning about the flight being canceled nine hours later (right after I got home).&lt;br /&gt;&lt;br /&gt;There was not one person on that plane who would have been less satisfied with a trip to Oakland and a train-ride to SFO than they were with what they got (nothing). &amp;nbsp;Airlines are, by and large, idiocratic entities. &amp;nbsp;Stupid people are allowed to set up elaborate systems that are simultaneously incapable of meeting the fictitious needs initially envisioned&amp;nbsp;and incapable of dealing with the actual needs of real customers.&lt;br /&gt;&lt;br /&gt;When a limb is that rotten, the only thing left to do is chew it off. &amp;nbsp;We must allow the airlines to fail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1932194767412936049?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1932194767412936049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/08/united-airlines-example-of-why-airlines.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1932194767412936049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1932194767412936049'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/08/united-airlines-example-of-why-airlines.html' title='United Airlines: An Example of Why Airlines must be Allowed to Fail'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1407091838227855182</id><published>2010-07-28T21:38:00.001-07:00</published><updated>2010-07-28T21:38:24.277-07:00</updated><title type='text'>Quickie Orange Sauce</title><content type='html'>&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;Quickie orange sauce:&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;1 orange&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;1 "new mexico pepper" (whatever the hell that is)&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;1/3 cup (ish?) marsala&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;1 slice butter&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;1 tsp (ish?) cooking oil&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;&amp;nbsp;1 tsp (ish?) sugar&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;Crush orange into a glass&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;Add the other ingredients&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;Put in a pan on lowish heat&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;Stir until it reaches desired thickness (20 - 30 minutes?)&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;Turn to low heat&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px;"&gt;Continue to stir occasionally&amp;nbsp;until time to serve&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1407091838227855182?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1407091838227855182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/quickie-orange-sauce.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1407091838227855182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1407091838227855182'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/quickie-orange-sauce.html' title='Quickie Orange Sauce'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1801151964904853365</id><published>2010-07-26T18:21:00.000-07:00</published><updated>2010-07-26T18:21:57.462-07:00</updated><title type='text'>Lowering Cost of Goad Testing</title><content type='html'>I've lowered the cost of my long paper: &lt;a href="http://www.lulu.com/product/paperback/goad-testing-deepening-our-understanding-of-automated-tests/6396354"&gt;Goad Testing&lt;/a&gt;. &amp;nbsp;This booklet shows a weakness in the way we usually do test-driven development along with a discipline we can apply to mitigate it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1801151964904853365?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1801151964904853365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/lowering-cost-of-goad-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1801151964904853365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1801151964904853365'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/lowering-cost-of-goad-testing.html' title='Lowering Cost of Goad Testing'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-729035450141241117</id><published>2010-07-18T21:05:00.000-07:00</published><updated>2010-07-18T21:05:08.968-07:00</updated><title type='text'>I Write Like</title><content type='html'>&lt;a href="http://iwl.me/"&gt;I write like&lt;/a&gt;&amp;nbsp;is a pretty neat little tool and surprisingly precise. &amp;nbsp;I haven't read either of the authors it says I write like so I cannot say how accurate it is but I can definitely say it is precise.&lt;br /&gt;&lt;br /&gt;Most of the time I paste in a blog entry, it says I'm like this Canadian blogger, eh. &amp;nbsp;The rest of the time, it says I'm like some science-fiction writer/essayist. &amp;nbsp;Even if the comparisons are totally, horribly wrong. &amp;nbsp;Just having metrics capable of consistently mapping one person's writing to one or two other people's writing is worth a golf clap.&lt;br /&gt;&lt;br /&gt;Rock on, guys. &amp;nbsp;Rock on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-729035450141241117?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/729035450141241117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/i-write-like.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/729035450141241117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/729035450141241117'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/i-write-like.html' title='I Write Like'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2933046775989221053</id><published>2010-07-18T12:45:00.000-07:00</published><updated>2010-07-18T12:46:00.179-07:00</updated><title type='text'>Software Development and Flow</title><content type='html'>In response to Marco Dorantes's post on &lt;a href="http://blogs.msdn.com/b/marcod/archive/2010/07/18/processandflow.aspx"&gt;flow in software development&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Flow is part of it. &amp;nbsp;There are five Lean principles, all of equal importance:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Start with a clear concept of value as a customer would define it&lt;/li&gt;&lt;li&gt;Lay out the series of steps required to create value to define the value stream&lt;/li&gt;&lt;li&gt;Create flow across the value stream&lt;/li&gt;&lt;li&gt;Let the customer pull value&lt;/li&gt;&lt;li&gt;Compete against perfection rather than other organizations&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;There are tools that allow us to do all five of these. &amp;nbsp;In fact, the tool that Al is promoting quite heavily right now - kanban - enables every single one of those things. &amp;nbsp;So, while I agree that flow is a critical part of the software development process - I don't understand why we are all so focused on the middle part.&lt;br /&gt;&lt;br /&gt;It's like saying a ham sandwich with cheese and lettuce is all about cheese. &amp;nbsp;The cheese is necessary and not sufficient.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2933046775989221053?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2933046775989221053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/in-response-to-marco-dorantess-post-on.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2933046775989221053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2933046775989221053'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/in-response-to-marco-dorantess-post-on.html' title='Software Development and Flow'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-6474639375012546297</id><published>2010-07-17T14:53:00.000-07:00</published><updated>2010-07-17T14:53:28.423-07:00</updated><title type='text'>Moq Sequencing</title><content type='html'>Declan Whelan recently &lt;a href="http://dpwhelan.com/blog/software-development/moq-sequences/"&gt;responded&lt;/a&gt; to my &lt;a href="http://maxg3prog.blogspot.com/2010/04/very-simple-sequencer-for-moq.html"&gt;Moq Sequencer&lt;/a&gt; post.&lt;br /&gt;&lt;br /&gt;Looks pretty good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-6474639375012546297?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/6474639375012546297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/moq-sequencing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6474639375012546297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6474639375012546297'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/moq-sequencing.html' title='Moq Sequencing'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1002671964261150800</id><published>2010-07-17T14:32:00.000-07:00</published><updated>2010-07-17T14:32:33.531-07:00</updated><title type='text'>Switching web hosts</title><content type='html'>My current webhost - ServerIntellect.com - appears to be completely incompetent. &amp;nbsp;I'd put my uptime in the vicinity of seventy-five to eighty percent. &amp;nbsp;Generously. &amp;nbsp;I highly recommend that you do &lt;b&gt;not&lt;/b&gt;&amp;nbsp;use them, if you have the ability to avoid it.&lt;br /&gt;&lt;br /&gt;I'm going to be switching away in a bit, here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1002671964261150800?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1002671964261150800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/switching-web-hosts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1002671964261150800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1002671964261150800'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/switching-web-hosts.html' title='Switching web hosts'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-5493809836132584647</id><published>2010-07-06T19:57:00.000-07:00</published><updated>2010-07-06T19:57:55.524-07:00</updated><title type='text'>Support Matrix and Short Term Planning for DataClass</title><content type='html'>The next three months are going to be all about expanding DataClass's platform support. &amp;nbsp;I've &lt;a href="http://dataclass.hexsw.com/Home/SupportMatrix"&gt;published the current support matrix&lt;/a&gt;.&amp;nbsp;&amp;nbsp;That same page also includes estimates as to when currently-unsupported platforms will become supported.&lt;br /&gt;&lt;br /&gt;Anywho... check it out. &amp;nbsp;Also, if you haven't already, check out the way I documented the &lt;a href="http://dataclass.hexsw.com/Help/Syntax"&gt;DataClass syntax&lt;/a&gt; and let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-5493809836132584647?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/5493809836132584647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/support-matrix-and-short-term-planning.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5493809836132584647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5493809836132584647'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/support-matrix-and-short-term-planning.html' title='Support Matrix and Short Term Planning for DataClass'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-669523555853886003</id><published>2010-07-06T12:06:00.000-07:00</published><updated>2010-07-06T12:06:40.869-07:00</updated><title type='text'>RE: Uncle Bob's "Software Calculus"</title><content type='html'>...which can be found here:&lt;div&gt;&lt;a href="http://blog.objectmentor.com/articles/2010/07/05/software-calculus-the-missing-abstraction"&gt;http://blog.objectmentor.com/articles/2010/07/05/software-calculus-the-missing-abstraction&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.objectmentor.com/articles/2010/07/05/software-calculus-the-missing-abstraction"&gt;&lt;/a&gt;It don't think the problem is a lack of thought-tools at all. &amp;nbsp;The problem is people won't use the tools we have. &amp;nbsp;Sure, we can keep refining our tool set. &amp;nbsp;We should always do that. &amp;nbsp;I just don't think we should hold our breath for a revolution...&lt;br /&gt;&lt;br /&gt;Software development &lt;i&gt;is&lt;/i&gt;&amp;nbsp;the revolution.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-669523555853886003?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/669523555853886003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/re-uncle-bobs-software-calculus.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/669523555853886003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/669523555853886003'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/re-uncle-bobs-software-calculus.html' title='RE: Uncle Bob&apos;s &quot;Software Calculus&quot;'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1377630513281622639</id><published>2010-07-05T14:04:00.000-07:00</published><updated>2010-07-05T14:04:41.688-07:00</updated><title type='text'>DataClass Syntax Documentation now Available Online</title><content type='html'>I've posted documentation for the syntax of a DataClass source file online (&lt;a href="http://dataclass.hexsw.com/Help/Syntax/"&gt;here&lt;/a&gt;). &amp;nbsp;It was really not that hard to build the engine that provides documentation in that format and I think it really helps you learn the language. &amp;nbsp;It leads one to the question "Why aren't all languages documented this way?" &amp;nbsp;Surely a human language would be a lot harder but at least programming languages.&lt;br /&gt;&lt;br /&gt;Anyway, let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1377630513281622639?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1377630513281622639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/dataclass-syntax-documentation-now.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1377630513281622639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1377630513281622639'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/dataclass-syntax-documentation-now.html' title='DataClass Syntax Documentation now Available Online'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-3628989073727855534</id><published>2010-07-03T09:14:00.000-07:00</published><updated>2010-07-03T09:14:01.640-07:00</updated><title type='text'>We Reap What We Sew</title><content type='html'>...and I have sewn the seeds of a marriage to a tool that no longer provides adequate functionality. &amp;nbsp;All throughout &lt;a href="http://dataclass.hexsw.com/"&gt;DataClass&lt;/a&gt;, I coupled directly to Microsoft's CodeDom framework.&lt;br /&gt;&lt;br /&gt;The following were my excuses for not encapsulating this stuff:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;What a convenient way to model the code I want to generate.&lt;/li&gt;&lt;li&gt;It's just data.&lt;/li&gt;&lt;li&gt;It's part of the framework, I can trust it.&lt;/li&gt;&lt;li&gt;It will be easy to add support for Java because this is a language-independent format.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Bull...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;...shit.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All of it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Microsoft screwed us all over by getting rid of the J# code provider. &amp;nbsp;The C# code provider ought to work just fine with some small extensions but it is almost impossible to extend. &amp;nbsp;Bottom line, I'm having to write a working code modeling library; albeit one that only meets my needs.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;They also gave .net eventing - a bastardized, incomplete, attempt at generically implementing the Observer pattern - a "little overhaul." &amp;nbsp;Translation: the way that you depended on these things working (crappy though it was) is no more. &amp;nbsp;Fortunately, I avoid those like the goddamn plague.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The bottom line, here, is this: If you didn't write it, don't trust it. &amp;nbsp;I'm not saying that Microsoft is likely to deprecate System.Int32 any time soon but you cannot count on them not changing something about how it works. &amp;nbsp;Encapsulate, encapsulate, encapsulate.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;...or you &lt;i&gt;will&lt;/i&gt;&amp;nbsp;be sorry.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-3628989073727855534?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/3628989073727855534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/we-reap-what-we-sew.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3628989073727855534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3628989073727855534'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/we-reap-what-we-sew.html' title='We Reap What We Sew'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-3822203217811737959</id><published>2010-07-01T18:52:00.000-07:00</published><updated>2010-07-01T18:52:59.187-07:00</updated><title type='text'>Why Me?</title><content type='html'>Has anyone else noticed that the universe or, at the very least, our social and economic system, is set up to reward the stupid, the weak, and the wicked while punishing those who are smart, strong, and virtuous?&lt;br /&gt;&lt;br /&gt;Idiots get bailed out from their bad decision making with their credit cards and I labor under the weight of those bailouts. &amp;nbsp;Weaklings choose to live off the government and I struggle under their considerable mass as well. &amp;nbsp;Jackasses intentionally screw over the economy and it's my job to give them a handout too.&lt;br /&gt;&lt;br /&gt;Yet, while doing all of that and trying to contribute to society, I can't get a goddamn computer to run right. &amp;nbsp;First, it's hard-drive dies. &amp;nbsp;Then it's power intake. &amp;nbsp;Where is the support system for the people who are generally making this a better place to exist but just happen to actually, literally be down on their luck?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-3822203217811737959?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/3822203217811737959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/why-me.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3822203217811737959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3822203217811737959'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/07/why-me.html' title='Why Me?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-8598854445040788511</id><published>2010-06-30T20:43:00.000-07:00</published><updated>2010-06-30T20:43:37.065-07:00</updated><title type='text'>Flattery will Get you All Kinds of Places</title><content type='html'>Someone "liked" the &lt;a href="http://dataclass.hexsw.com/"&gt;DataClass homepage&lt;/a&gt; on Facebook. &amp;nbsp;I wish I could figure out who it was. &amp;nbsp;It's very flattering as it was not particularly solicited.&lt;br /&gt;&lt;br /&gt;Anywho. &amp;nbsp;Today is the last day before tomorrow and tomorrow is the first day of the DataClass beta. &amp;nbsp;I'm leaving &lt;a href="http://dataclass.hexsw.com/Beta/SignUp"&gt;registration&lt;/a&gt; open until the 10th. &amp;nbsp;If you don't get a chance to get involved in this beta, there will be another chance in August if you are a Java programmer or work with Java programmers who use a database you maintain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-8598854445040788511?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/8598854445040788511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/flattery-will-get-you-all-kinds-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8598854445040788511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8598854445040788511'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/flattery-will-get-you-all-kinds-of.html' title='Flattery will Get you All Kinds of Places'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-6833731246836201474</id><published>2010-06-28T23:33:00.000-07:00</published><updated>2010-06-28T23:33:01.356-07:00</updated><title type='text'>What Can We Learn about Agility from the Pyramids?</title><content type='html'>In response to&amp;nbsp;&lt;a href="http://whitewaterprojects.com/2010/06/28/were-pyramids-the-first-iterative-development/"&gt;http://whitewaterprojects.com/2010/06/28/were-pyramids-the-first-iterative-development/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The author makes a good point. &amp;nbsp;In all likelihood the pyramids were built that way and, again in all likelihood, it did have the effect of a pyramid being ready whenever a pharaoh died. &amp;nbsp;The way these facts are presented tells us something about a lot of things. &amp;nbsp;Not the least interesting of which is the ever-present and ever-intriguing issue of perspective.&lt;br /&gt;&lt;br /&gt;On the surface, this story tells us how Agility helped the people building tombs for pharaohs in ancient Egypt. &amp;nbsp;Another layer down, it tells us about how large groups of people organize to become agile. &amp;nbsp;Deeper still is a story of motivations and perspective. &amp;nbsp;Think of this as a practicality sandwich on philosophy bread. &amp;nbsp;The outer layers are important but I'm going to focus on the meat.&lt;br /&gt;&lt;br /&gt;How did the ancient Egyptians learn to become Agile when it took us so many decades of lean thinking? &amp;nbsp;It's amazing, really.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_-GTjGvlJ3bE/TCmQPRfViNI/AAAAAAAAAAw/fY2mgql---k/s1600/Blades_070614041138432_wideweb_300x375.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_-GTjGvlJ3bE/TCmQPRfViNI/AAAAAAAAAAw/fY2mgql---k/s320/Blades_070614041138432_wideweb_300x375.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;In the words of Chazz Michael Michaels, it's mind-bottling. &amp;nbsp;You know, when things are so crazy it gets your thoughts all trapped, like in a bottle?&lt;br /&gt;&lt;br /&gt;So while you are sitting there being all astounded by the wisdom of the ancients, let me just add this one little piece of info to the puzzle:&lt;br /&gt;&lt;br /&gt;There were no massive cranes back then. &amp;nbsp;There were no steel girders. &amp;nbsp;There was no such thing as temporary scaffolding that could suspend one of those stones for a substantial period of time.&lt;br /&gt;&lt;br /&gt;Knowing that, the question has to be asked. &amp;nbsp;How &lt;i&gt;else&lt;/i&gt;&amp;nbsp;would they have built a pyramid? &amp;nbsp;What structural, architectural, or engineering tools could they have used to do anything else but build it in shells?&lt;br /&gt;&lt;br /&gt;Once you answer those questions, it becomes apparent that they &lt;i&gt;had&lt;/i&gt;&amp;nbsp;to be agile. &amp;nbsp;They had no alternative. &amp;nbsp;There were no tools available that would accommodate a big-batch approach in the first place. &amp;nbsp;Being ready to bury a pharaoh who died before his time probably was not even on anybody's mind.&lt;br /&gt;&lt;br /&gt;...at least until the first time one died young. &amp;nbsp;Then, maybe, someone said "Hey! &amp;nbsp;It's really handy we've been building these tombs this way, now we can just drop him off in the center and start working on the next guy's pyramid!"&lt;br /&gt;&lt;br /&gt;There is no evidence that the ancient Egyptians' agility was a consequence of their wisdom or foresight. &amp;nbsp;Quite the opposite, agility was mandated by the context in which the supposedly agile people did their work. There is a nugget of wisdom in that fact.&lt;br /&gt;&lt;br /&gt;I think it is this: People are not naturally agile. &amp;nbsp;Don't try to control the person, instead control the context in which they work. &amp;nbsp;Make agility easier than the alternative and the people will do the hard part of the transition for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-6833731246836201474?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/6833731246836201474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/what-can-we-learn-about-agility-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6833731246836201474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6833731246836201474'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/what-can-we-learn-about-agility-from.html' title='What Can We Learn about Agility from the Pyramids?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_-GTjGvlJ3bE/TCmQPRfViNI/AAAAAAAAAAw/fY2mgql---k/s72-c/Blades_070614041138432_wideweb_300x375.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-4598229870512192641</id><published>2010-06-26T12:14:00.000-07:00</published><updated>2010-06-26T12:14:49.922-07:00</updated><title type='text'>Frustrated by SlideShare</title><content type='html'>&lt;a href="http://www.slideshare.net/MaxGuernseyIII"&gt;SlideShare&lt;/a&gt;&amp;nbsp;has some cool features and I really like the idea. &amp;nbsp;However, I do find its user experience maddening. &amp;nbsp;Not that I am the king of user experience or anything... the &lt;a href="http://www.hexsw.com/"&gt;Hexagon Software&lt;/a&gt; website is evidence enough of that.&lt;br /&gt;&lt;br /&gt;Still. &amp;nbsp;I'm one guy with a day job. &amp;nbsp;SlideShare appears to be a company that does this as a reason to exist. &amp;nbsp;Mostly the problems I have come from two things:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Delays&lt;/li&gt;&lt;li&gt;Unclear directives&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;b&gt;Delays&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I get that it takes time to do something like process a document into a SlideCast. &amp;nbsp;What I don't get is why there is no indication to me that I should be waiting. &amp;nbsp;Frequently, SlideShare will tell me something is "done" but it does not appear to actually be done, yet. &amp;nbsp;There is no way for me to determine whether something went wrong or everything is fine except to wait.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Unclear Directives&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Generally speaking, buttons don't do what I think they should do. &amp;nbsp;This is especially true of file uploads. &amp;nbsp;Am I uploading a video? &amp;nbsp;A slide deck? &amp;nbsp;A document? &amp;nbsp;Why, when I try to upload a video, does the Open dialog not show videos but, when I try to upload a slide deck, I have to sift through a bunch of videos?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;What Can We Learn?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;In reality, these are all just examples of poor feedback. &amp;nbsp;A simple note saying "Your new document is in the final stages of processing. &amp;nbsp;Please be patient." &amp;nbsp;Would save a lot of pain and suffering. &amp;nbsp;A few extra developer hours on their upload technology would save decades in user time over the course of the next year.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-4598229870512192641?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/4598229870512192641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/frustrated-by-slideshare.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4598229870512192641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/4598229870512192641'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/frustrated-by-slideshare.html' title='Frustrated by SlideShare'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-7434835028951317658</id><published>2010-06-25T21:43:00.000-07:00</published><updated>2010-06-25T21:43:39.436-07:00</updated><title type='text'>Why &amp; how DataClass can facilitate Agile database development</title><content type='html'>I've released another video on the topic of &lt;a href="http://dataclass.hexsw.com/"&gt;DataClass&lt;/a&gt;. &amp;nbsp;This time I go over what the problems related to database development are and how DataClass helps you resolve them.&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ERDiA-v_d1Q&amp;hl=en_US&amp;fs=1&amp;hd=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/ERDiA-v_d1Q&amp;hl=en_US&amp;fs=1&amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-7434835028951317658?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/7434835028951317658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/why-how-dataclass-can-facilitate-agile.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7434835028951317658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7434835028951317658'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/why-how-dataclass-can-facilitate-agile.html' title='Why &amp; how DataClass can facilitate Agile database development'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-8478128566982230307</id><published>2010-06-23T23:04:00.000-07:00</published><updated>2010-06-23T23:04:25.388-07:00</updated><title type='text'>DataClass 1.0 Beta Program Impending</title><content type='html'>Well, I'm excited to say that the beta program has reached critical mass in terms of registrants so we are &lt;i&gt;definitely on&lt;/i&gt;&amp;nbsp;for July.&lt;br /&gt;&lt;br /&gt;Make sure you &lt;a href="http://dataclass.hexsw.com/Beta/SignUp"&gt;sign up here&lt;/a&gt; if you are interested.&lt;br /&gt;&lt;br /&gt;I'm really excited about the opportunity to build a new product using what I know about business, product, and software development today. &amp;nbsp;DataClass is something that is a big deal for me because it is the result of nearly half a decade of accumulated knowledge. &amp;nbsp;Everything I learnt we shouldn't do with DataConstructor, I made sure isn't done by DataClass. &amp;nbsp;All the most important things I wished I could have are in DataClass.&lt;br /&gt;&lt;br /&gt;Moreover, it represents a whole new way of thinking and of working with databases. &amp;nbsp;The vision I've been pushing in my courses and in my writings is now facilitated by a single logical document compiled by a single tool.&lt;br /&gt;&lt;br /&gt;I look forward to getting real feedback and releasing the initial version of DataClass and I hope you do, too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-8478128566982230307?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/8478128566982230307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/dataclass-10-beta-program-impending.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8478128566982230307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8478128566982230307'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/dataclass-10-beta-program-impending.html' title='DataClass 1.0 Beta Program Impending'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2177411306087085508</id><published>2010-06-19T17:23:00.000-07:00</published><updated>2010-06-19T17:23:03.605-07:00</updated><title type='text'>DataClass Case Study #1: Solving the Duplication Problem</title><content type='html'>I've posted a short (12 minute) video on SlideShare that shows how you can use DataClass to eliminate duplication between the documents you used to define your database and your .net database client.  I intend to hit Java in the near future.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.slideshare.net/MaxGuernseyIII/dataclass-case-study-1-solving-the-duplication-problem-with-narration"&gt;Here is a link to the video.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Stay tuned and be sure to sign up for the beta if you want to be a part of it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2177411306087085508?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2177411306087085508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/dataclass-case-study-1-solving.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2177411306087085508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2177411306087085508'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/dataclass-case-study-1-solving.html' title='DataClass Case Study #1: Solving the Duplication Problem'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2036002658291930895</id><published>2010-06-19T11:15:00.000-07:00</published><updated>2010-06-20T09:06:37.947-07:00</updated><title type='text'>DataClass 1.0 Beta Program Open</title><content type='html'>&lt;p&gt;The DataClass 1.0 Beta program is now open.  DataClass is the next generation of DataConstructor technology.  It is smaller, faster, and does a heck of a lot more.&lt;/p&gt;&lt;p&gt;If you are interested, the sign-up form can be found below.  You will get a beta license to the product to be used over the course of the month of July.  You will then get a survey to fill out in August.  When you fill out the survey, you will get a complementary 1-seat license to DataClass as a thank you.&lt;/p&gt;&lt;br /&gt;&lt;a href="http://dataclass.hexsw.com/Beta/SignUp"&gt;Click here to go to the beta sign-up page.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2036002658291930895?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2036002658291930895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/dataclass-10-beta-program-open.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2036002658291930895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2036002658291930895'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/dataclass-10-beta-program-open.html' title='DataClass 1.0 Beta Program Open'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2108472247173708949</id><published>2010-06-07T08:06:00.000-07:00</published><updated>2010-06-07T08:06:54.839-07:00</updated><title type='text'>Two Customers</title><content type='html'>In response to&amp;nbsp;&lt;a href="http://whitewaterprojects.com/2010/06/04/who-is-your-cutomer/"&gt;http://whitewaterprojects.com/2010/06/04/who-is-your-cutomer/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I respectfully disagree with the concept of a "technical customer" in addition to a "business customer." &amp;nbsp;It may just be a semantics thing but I think it's important to keep the customer's place special.&lt;br /&gt;&lt;br /&gt;The customer is the customer. &amp;nbsp;For the team closest to the customer, that is not difficult to see. &amp;nbsp;For teams "behind" the teams on the "surface" of an organization, it gets a little cloudier. &amp;nbsp;I think it makes more sense to think of the intervening teams between yours and the customer as downstream work-cells. &amp;nbsp;As such, they have the power to specify what an upstream work-cell builds in the moment.&lt;br /&gt;&lt;br /&gt;The mental difference, however, is that they are not considered customers when your organization is working to optimize the whole.&lt;br /&gt;&lt;br /&gt;Now, if there are two kinds of customer, I would say that there is a business customer and a &lt;i&gt;process&amp;nbsp;customer&lt;/i&gt;. &amp;nbsp;That is, you can spend time delivering value to your actual customers, or you can spend time increasing your organizations capacity or lowering its cost.&lt;br /&gt;&lt;br /&gt;The process customer is going to be interested in any project that eliminates waste. &amp;nbsp;This might be traditional process projects like training in the latest methodology. &amp;nbsp;This might be the acquisition of a tool. &amp;nbsp;This might be something we don't think of as process but that plays heavily into it, like refactoring or covering legacy code it tests.&lt;br /&gt;&lt;br /&gt;The business customer just wants what it wants.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2108472247173708949?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2108472247173708949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/two-customers.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2108472247173708949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2108472247173708949'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/06/two-customers.html' title='Two Customers'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-6653489932157687018</id><published>2010-05-28T16:29:00.000-07:00</published><updated>2010-05-28T16:29:16.668-07:00</updated><title type='text'></title><content type='html'>Oblivion for One&lt;br /&gt;By Max Guernsey, III&lt;br /&gt;&lt;br /&gt;Stop all the clocks?&lt;br /&gt;Why bother?&lt;br /&gt;&lt;br /&gt;This is the end...&lt;br /&gt;&lt;br /&gt;...of life.&lt;br /&gt;...of love.&lt;br /&gt;...of joy.&lt;br /&gt;...of pain.&lt;br /&gt;...of experience.&lt;br /&gt;&lt;br /&gt;At least, for one. &amp;nbsp;At 2:30 pm, today, one of our cats, Seelie, died.&lt;br /&gt;&lt;br /&gt;For those of us left here, we go on; some more affected than others. &amp;nbsp;Yet, that's not really the point... is it? &amp;nbsp;Mourning is an inherently selfish thing. &amp;nbsp;We lament our loss; our pain; our experience; but those things all pale in comparison to what Seelie has lost: existence itself.&lt;br /&gt;&lt;br /&gt;She is no more. &amp;nbsp;To her, there is no more "to be." &amp;nbsp;There is no more her for there to be no "to be" to. &amp;nbsp;Nothing. &amp;nbsp;No experience. &amp;nbsp;No love. &amp;nbsp;No joy or hate. &amp;nbsp;The world does not exist.&lt;br /&gt;&lt;br /&gt;So I say "Stop all the clocks? &amp;nbsp;No need. &amp;nbsp;Prevent the dog from barking with a juicy bone? &amp;nbsp;No call."&lt;br /&gt;&lt;br /&gt;For Seelie, the clocks have stopped and the dogs have stopped barking. &amp;nbsp;From her perspective, those things all happened and more: The entire universe, including herself, ceased to exist the moment she died.&lt;br /&gt;&lt;br /&gt;Who will be next?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-6653489932157687018?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/6653489932157687018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/05/oblivion-for-one-by-max-guernsey-iii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6653489932157687018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6653489932157687018'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/05/oblivion-for-one-by-max-guernsey-iii.html' title=''/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-237447778857255753</id><published>2010-05-21T21:36:00.000-07:00</published><updated>2010-05-22T11:53:15.734-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DataConstructor'/><category scheme='http://www.blogger.com/atom/ns#' term='DataClass'/><title type='text'>DataClass is almost here!</title><content type='html'>The new version of &lt;i&gt;&lt;a href="http://www.dataconstructor.com/"&gt;DataConstructor&lt;/a&gt;&lt;/i&gt;, &lt;i&gt;DataClass&lt;/i&gt;, is almost ready for prime-time. &amp;nbsp;I've got all of the critical v1.0 features ready for release and all I have left is the packaging and tutorials. &amp;nbsp;I'm looking for beta testers so, if you are interested, let me know.&lt;br /&gt;&lt;br /&gt;Each beta tester earns one Agile team a license to use v1.x of &lt;i&gt;DataClass&lt;/i&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-237447778857255753?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/237447778857255753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/05/dataclass-is-almost-here.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/237447778857255753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/237447778857255753'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/05/dataclass-is-almost-here.html' title='DataClass is almost here!'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2720374656398539797</id><published>2010-05-21T17:27:00.000-07:00</published><updated>2010-05-21T17:27:38.029-07:00</updated><title type='text'>Quitting stack overflow</title><content type='html'>I tried being a member of the stackoverflow community. &amp;nbsp;At the end of the day, it appears to be no different from facebook... just another waste of time mindlessly drifting wherever the winds of mob mentality take it that day. &amp;nbsp;All investment, no return.&lt;br /&gt;&lt;br /&gt;I'm done and you should seriously consider the following question, if you are a user: do you really get any value from it or is it just another addiction to a meaningless point system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2720374656398539797?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2720374656398539797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/05/quitting-stack-overflow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2720374656398539797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2720374656398539797'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/05/quitting-stack-overflow.html' title='Quitting stack overflow'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-3681610797702464909</id><published>2010-05-11T08:37:00.000-07:00</published><updated>2010-05-22T11:52:46.855-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DataConstructor'/><category scheme='http://www.blogger.com/atom/ns#' term='DataClass'/><title type='text'>DataClass nearing completion</title><content type='html'>As many of you know, I'm working on the next generation of &lt;a href="http://www.dataconstructor.com/"&gt;DataConstructor&lt;/a&gt; technology, DataClass. &amp;nbsp;I am personally very excited about this new product - it takes database building, design, and testing to the next level. &amp;nbsp;Here are some of the benefits that DataClass has (with &lt;span class="Apple-style-span" style="color: red;"&gt;red&lt;/span&gt; asterisks next to the benefits DataConstructor gave you):&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It is a &lt;b&gt;compiled language&lt;/b&gt;.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The only things not compiled are the SQL and DDL scripts themselves.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;It enables designs with&amp;nbsp;&lt;b&gt;zero duplication&lt;/b&gt;.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;No duplicated strings &lt;b&gt;even between database scripts and .NET code&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;It facilitates &lt;b&gt;transition testing knowledge&lt;/b&gt;.&lt;span class="Apple-style-span" style="color: red;"&gt;*&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;DataClass still&amp;nbsp;enables you to build a database from&amp;nbsp;&lt;b&gt;any historical version to any future version&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;.&lt;span class="Apple-style-span" style="color: red;"&gt;*&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;It alleviates the need for most&amp;nbsp;&lt;/span&gt;transition testing design&lt;/b&gt;.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;For certain database platforms, basic design structures will be validated implicitly.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;It &lt;b&gt;does not require a license&lt;/b&gt; at runtime.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The compiler is the licensed component, not its output.&lt;/li&gt;&lt;li&gt;The developer is licensed rather than the application.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;It allows you to define a &lt;b&gt;complete class&lt;/b&gt;&amp;nbsp;of database.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Transition logic.&lt;/li&gt;&lt;li&gt;Public, private, and protected design elements are all defined in one document.&lt;/li&gt;&lt;li&gt;Version info.&lt;/li&gt;&lt;li&gt;All are compiled into a single .NET class.&lt;/li&gt;&lt;li&gt;Public aspects are made public.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-3681610797702464909?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/3681610797702464909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/05/dataclass-nearing-completion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3681610797702464909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3681610797702464909'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/05/dataclass-nearing-completion.html' title='DataClass nearing completion'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1802900725650879808</id><published>2010-04-13T22:19:00.000-07:00</published><updated>2010-04-13T22:19:49.160-07:00</updated><title type='text'>Mr. Graffin: My Uneaten Greens Are a Feast for Some, I Say</title><content type='html'>I just went two days without a&amp;nbsp;substantive&amp;nbsp;meal. &amp;nbsp;That's right: Fatty go hungry. &amp;nbsp;After &lt;i&gt;two freaking days&lt;/i&gt;, I prepared for myself a meal I would never have previously considered eating and, guess what: It tasted great.&lt;br /&gt;&lt;br /&gt;It takes me back to when I was a boy scout. &amp;nbsp;We went on this one hike that felt like forever. &amp;nbsp;At the end of the day, we made ourselves "hobo dinners." &amp;nbsp;Right up until now, that dining experience is still my fondest. &amp;nbsp;When I try to recreate it, I never succeed because I am not famished.&lt;br /&gt;&lt;br /&gt;Here we are, the fattest, most abundantly fed nation in the known history of the world, and we can't get a decent meal. &amp;nbsp;The constant availability of relatively cheap, delicious food has driven our expectations to the point where we are difficult to satisfy and impossible to wow.&lt;br /&gt;&lt;br /&gt;So, when I listen to the &lt;a href="http://www.amazon.com/Generator-Bad-Religion/dp/B0001JXP98?ie=UTF8&amp;amp;tag=guid06-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Bad Religion&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=guid06-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=B0001JXP98" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt; song "&lt;a href="http://www.amazon.com/Quality-or-Quantity-Album-Version/dp/B001XNGXTU?ie=UTF8&amp;amp;tag=guid06-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Quality or Quantity&lt;/a&gt;" - which I often do - and I hear Mr. Graffin lament the woes of the poor folk who live on "just seventy cents a day," I am forced to wonder "Do they really have it so bad?"&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=guid06-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=B001XNGXTU" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;&lt;br /&gt;&lt;br /&gt;My point is this:&lt;br /&gt;Have no sympathy for people who are living off of "less than the cost of a cup of coffee" a day; they are eating better than we do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1802900725650879808?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1802900725650879808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/04/mr-graffin-my-uneaten-greens-are-feast.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1802900725650879808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1802900725650879808'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/04/mr-graffin-my-uneaten-greens-are-feast.html' title='Mr. Graffin: My Uneaten Greens Are a Feast for Some, I Say'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2109046809623316212</id><published>2010-04-12T21:49:00.000-07:00</published><updated>2010-04-12T21:49:27.343-07:00</updated><title type='text'>Book Titles</title><content type='html'>As some of you know, I am in the process of writing a book having to do with Agile database development.  This book contains a lot of the ideas I cover in my course (&lt;a href="http://www.netobjectives.com/courses/database-agility-online"&gt;shameless plug&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Since a lot of Agility ports straight across to database development, I'm largely not dealing with those issues.  I'm trying to come up with a name that conveys "this book helps you overcome the technical impediments to Agile database design."  Following are my ideas. &amp;nbsp;Any votes or suggestions would be welcome:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Agile Database Design:&amp;nbsp;Just-Right,&amp;nbsp;Just-in-Time&lt;/li&gt;&lt;li&gt;Agile Database Development: A Technical Perspective&lt;/li&gt;&lt;li&gt;Just-in-Time Database Design: And All It Entails&lt;/li&gt;&lt;li&gt;The Test-Driven Database: Building Solid, Flexible Data Stores&lt;/li&gt;&lt;li&gt;The JIT Database: How To&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Basically, I'd love to hear any suggestions you have.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2109046809623316212?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2109046809623316212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/04/book-titles.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2109046809623316212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2109046809623316212'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/04/book-titles.html' title='Book Titles'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-7779534941034930060</id><published>2010-04-04T16:43:00.000-07:00</published><updated>2010-04-04T16:53:04.795-07:00</updated><title type='text'>Very Simple Sequencer for Moq...</title><content type='html'>Following is a very simple tool for testing Moq...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;public class MoqSequence&lt;br /&gt;{&lt;br /&gt;  private int expectedSteps;&lt;br /&gt;  private int actualSteps;&lt;br /&gt;&lt;br /&gt;  private MoqSequence() { }&lt;br /&gt;&lt;br /&gt;  internal static MoqSequence GetInstance()&lt;br /&gt;  {&lt;br /&gt;    return new MoqSequence();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private class SequenceException : Exception&lt;br /&gt;  {&lt;br /&gt;    private SequenceException(string message)&lt;br /&gt;      : base(message)&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    internal static SequenceException GetInstance(&lt;br /&gt;      int expectedStep, int actualStep)&lt;br /&gt;    {&lt;br /&gt;      return GetInstance(&lt;br /&gt;        "Step " + expectedStep + " executed when step "&lt;br /&gt;        + actualStep + " should have been.");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    internal static SequenceException GetInstance(&lt;br /&gt;      string message)&lt;br /&gt;    {&lt;br /&gt;      return new SequenceException(message);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void InSequence&amp;lt;T&amp;gt;(ISetup&amp;lt;T&amp;gt; iSetup)&lt;br /&gt;    where T : class&lt;br /&gt;  {&lt;br /&gt;    var expectedStep = expectedSteps++;&lt;br /&gt;&lt;br /&gt;    iSetup.Callback(&lt;br /&gt;      () =&amp;gt;&lt;br /&gt;      {&lt;br /&gt;        if (actualSteps != expectedStep)&lt;br /&gt;        {&lt;br /&gt;          throw SequenceException.GetInstance(&lt;br /&gt;            expectedStep, actualSteps);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        actualSteps++;&lt;br /&gt;      });&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void Verify()&lt;br /&gt;  {&lt;br /&gt;    if (expectedSteps != actualSteps)&lt;br /&gt;    {&lt;br /&gt;      throw SequenceException.GetInstance(&lt;br /&gt;        "Expected " + expectedSteps + &lt;br /&gt;        " steps but only got " + actualSteps +&lt;br /&gt;        " steps");&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;Here is an example of how to use it:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void ExecutesStepsInCorrectOrder()&lt;br /&gt;{&lt;br /&gt;  var sequence = MoqSequence.GetInstance();&lt;br /&gt;&lt;br /&gt;  sequence.InSequence(transactionMock.Setup(&lt;br /&gt;    t =&amp;gt; t.Lock()));&lt;br /&gt;  sequence.InSequence(transactionMock.Setup(&lt;br /&gt;    t =&amp;gt; t.TransferAssetsIntoEscrow(escrowMock.Object)));&lt;br /&gt;  sequence.InSequence(transactionMock.Setup(&lt;br /&gt;    t =&amp;gt; t.SchedulePayouts(escrowMock.Object)));&lt;br /&gt;  sequence.InSequence(escrowMock.Setup(&lt;br /&gt;    e =&amp;gt; e.ReconcilePayoutsWithHoldings()));&lt;br /&gt;  sequence.InSequence(escrowMock.Setup(&lt;br /&gt;    e =&amp;gt; e.ExecutePayouts()));&lt;br /&gt;  sequence.InSequence(transactionMock.Setup(&lt;br /&gt;    t =&amp;gt; t.Complete()));&lt;br /&gt;&lt;br /&gt;  transactionCoordinator&lt;br /&gt;    .RunTransaction(transactionMock.Object);&lt;br /&gt;&lt;br /&gt;  sequence.Verify();&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-7779534941034930060?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/7779534941034930060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/04/very-simple-sequencer-for-moq.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7779534941034930060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/7779534941034930060'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/04/very-simple-sequencer-for-moq.html' title='Very Simple Sequencer for Moq...'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-6985358394723385769</id><published>2010-03-27T16:00:00.000-07:00</published><updated>2010-03-27T16:00:48.246-07:00</updated><title type='text'>Do You Have a Jesus Problem?  Alcohol is the answer.</title><content type='html'>Do you frequently get high on Jesus or Moses when you are alone? &amp;nbsp;Are you afraid to talk to your friends about where you went last Sunday? &amp;nbsp;Do you hide bibles around the house so your spouse can't find them?&lt;br /&gt;&lt;br /&gt;These are all signs of religion abuse. &amp;nbsp;Religion abuse is a very serious condition that affects nearly two out of every three Americans. &amp;nbsp;If you don't suffer from religion abuse, look to your left, then to your right. &amp;nbsp;Both of those people probably do.&lt;br /&gt;&lt;br /&gt;The affects of religious abuse last a lifetime. &amp;nbsp;Long term religion abuse can affect your personality, making your presence less pleasant or even unbearable to others. &amp;nbsp;People who are high on religion are often extremely suggestible and will do practically anything to "score" a shot at "heaven." &amp;nbsp;Worse still:&amp;nbsp;people who abuse religion often pass their condition on to their children.&lt;br /&gt;&lt;br /&gt;Even though it's completely ridiculous, these facts show that religion is no laughing matter.&lt;br /&gt;&lt;br /&gt;But... if you suffer from this condition, I have some good news: &lt;b&gt;there is a way out&lt;/b&gt;. &amp;nbsp;By giving yourself over to &lt;b&gt;Alcohol&lt;/b&gt;, you can blind yourself to the evils of the world. &amp;nbsp;Through Its powers, you will become blissfully unaware of your suffering and will no longer feel the need to justify it by contriving fictitious entities who watch over you and have a "good reason" for putting you through a living hell.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;And the wages of delusion is death of joy, but in Alcohol there is joy everlasting.&lt;/i&gt;&lt;/blockquote&gt;&amp;nbsp;Remember: &lt;b&gt;you don't have to live like this&lt;/b&gt;. &amp;nbsp;You can think for yourself and you can find a way to cope with the cold, barren, empty void that is our existence &lt;b&gt;without depending on imaginary figures from ancient fairy tales&lt;/b&gt;. &amp;nbsp;In Alcohol, there is redemption. &amp;nbsp;Turn yourself over to Alcohol and start living your life.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-6985358394723385769?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/6985358394723385769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/do-you-have-jesus-problem-alcohol-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6985358394723385769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6985358394723385769'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/do-you-have-jesus-problem-alcohol-is.html' title='Do You Have a Jesus Problem?  Alcohol is the answer.'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-5168886878672719064</id><published>2010-03-20T15:04:00.000-07:00</published><updated>2010-03-20T15:04:04.099-07:00</updated><title type='text'>The New Threat: Global Sideways-ing</title><content type='html'>People just don't get it. &amp;nbsp;Ever since several groups started trying to warn us about man-made global warming, there's been a small cadre of crackpots who've said crazy things like&amp;nbsp;"Wait a minute! &amp;nbsp;Isn't the Earth just going through its normal cycle of warming and cooling?" or "Hey! &amp;nbsp;It seems like we shouldn't be worried about global warming when the Earth is near the bottom of it's ordinary temperature range."&lt;br /&gt;&lt;br /&gt;Oh sure, the scientific and media community has been able to throw together some numbers and change their language against statements like the latter by changing "global warming" to "climate change." &amp;nbsp;...but the threat those people pose still remains. &amp;nbsp;How exactly do you deal with it when someone has a modicum of knowledge about the Earth's climate history in a larger context, one that generally does not include man? &amp;nbsp;How do you handle pesky lunatics who want to point out that tens of thousands of years ago could not have been the &lt;i&gt;last&lt;/i&gt;&amp;nbsp;ice age because it was part of &lt;i&gt;this&lt;/i&gt;&amp;nbsp;ice age and, in fact, we are in what is known as an "interglacial period?"&lt;br /&gt;&lt;br /&gt;You can try and show how insane they are for pointing at things like "evidence" and "historical data." &amp;nbsp;I'm sure that's what &lt;a href="http://seattletimes.nwsource.com/html/editorialsopinion/2011132171_pitts21.html"&gt;these fine, upstanding people&lt;/a&gt; would say is the right course of action.&lt;br /&gt;&lt;br /&gt;However, I would like to point out that those of us who do believe in global warming; those of us who keep the faith in spite of the evidence - because that's what it's about, after all: keeping the faith - have been focusing on the wrong thing...&lt;br /&gt;&lt;br /&gt;You see, this is a complex problem full of complex numbers and, as everybody knows, complex numbers have two components: the &lt;i&gt;real&lt;/i&gt;&amp;nbsp;part and the &lt;i&gt;imaginary&lt;/i&gt;&amp;nbsp;part. &amp;nbsp;Our problem is that we've been trying to convince people that man-made global climate change exists using real numbers and the real numbers have been very uncooperative.&lt;br /&gt;&lt;br /&gt;What we need to start doing is helping people comprehend the threat posed by the &lt;b&gt;imaginary numbers&lt;/b&gt;. &amp;nbsp;After all, the true threat lies in the imaginary component of the evidence we have collected, rather than the real part. &amp;nbsp;Let's look at a concrete example.&lt;br /&gt;&lt;br /&gt;Let's say that last year, the global average temperature went up by 0.1°F - don't bother to fact-check, I made that up as a hypothetical. &amp;nbsp;Someone could argue we have absolutely no evidence whatsoever that,&amp;nbsp;when exiting an ice age,&amp;nbsp;the temperature &lt;i&gt;should not&lt;/i&gt;&amp;nbsp;go up as fast as it did.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What these people don't understand is the imaginary impact of that change and the very real threat it poses. &lt;/b&gt;&amp;nbsp;Let's take a closer look:&lt;br /&gt;&lt;br /&gt;While, in our hypothetical example, the &lt;i&gt;real&lt;/i&gt;&amp;nbsp;component of climate change was only&amp;nbsp;0.1°F, the &lt;i&gt;imaginary&lt;/i&gt;&amp;nbsp;component could be 10&lt;i&gt;i&lt;span class="Apple-style-span" style="font-style: normal;"&gt;√(°F). &amp;nbsp;The good news is that we have no way of measuring this number so there is no way for those "that's not what the evidence suggests" fruitcakes to show that they are completely fabricated. &amp;nbsp;The bad news is that same attribute makes it so that those same nut jobs can say "because we cannot measure it, it won't have any measurable impact on our lives."&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;This can be resolved with the simple remedy of applying "what if;" the tool we used to generate a buzz and get people worried about &lt;s&gt;global warming&lt;/s&gt; climate change in the first place. &amp;nbsp;All we have to say is "What if some event were to occur that caused the imaginary portion of our climate change to be squared? &amp;nbsp;Where would be be then?"&lt;br /&gt;&lt;br /&gt;If our actual global average temperature were, say 67&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;°F +&amp;nbsp;10&lt;i&gt;i&lt;span class="Apple-style-span" style="font-style: normal;"&gt;√(°F), and the imaginary portion were to be squared, the real part of our global average temperature would &lt;/span&gt;drop&lt;/i&gt;&amp;nbsp;100&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;°F - a global&amp;nbsp;catastrophe. &amp;nbsp;Likewise, if the temperature started out as&amp;nbsp;67&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;°F -&amp;nbsp;10&lt;i&gt;i&lt;span class="Apple-style-span" style="font-style: normal;"&gt;√(°F), the temperature would jump&amp;nbsp;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;100&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;°F - killing pretty much everything everywhere.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;This proves, I think, that the real threat is not global warming, weirding, or climate change but Global Sidways-ing, man-made changes to the imaginary portion of our global average temperature that could lead to very disastrous consequences if mathematics were to&amp;nbsp;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;fundamentally&amp;nbsp;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;change in a way that caused those imaginary numbers to become real.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-5168886878672719064?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/5168886878672719064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/new-threat-global-sideways-ing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5168886878672719064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/5168886878672719064'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/new-threat-global-sideways-ing.html' title='The New Threat: Global Sideways-ing'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-711548505101669149</id><published>2010-03-20T10:51:00.000-07:00</published><updated>2010-03-20T10:51:20.029-07:00</updated><title type='text'>Living without Dryer Sheets</title><content type='html'>Now that I live in Bend, one of my biggest problems is static electricity. &amp;nbsp;&lt;b&gt;Every&lt;/b&gt;&amp;nbsp;time that I reach for my computer at work, I get shocked; sometimes hard enough that the affected finger goes a little numb for a few minutes.&lt;br /&gt;&lt;br /&gt;Another problem I have is that I am lazy. &amp;nbsp;Horribly, horribly lazy... at least when it comes to mundane things. &amp;nbsp;Ask my wife, she'll confirm: I'm the laziest person there is. &amp;nbsp;Think you're the laziest? &amp;nbsp;Wrong. &amp;nbsp;It's me.&lt;br /&gt;&lt;br /&gt;So, long story short: I don't have dryer sheets because I am too lazy to walk across the street and buy them. &amp;nbsp;So my static electricity problem is worse than ever before.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Problem:&lt;/b&gt;&amp;nbsp;My pants carry too high a static charge.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution:&lt;/b&gt; Wrap them around the faucet while I'm brushing my teeth.&lt;br /&gt;&lt;br /&gt;Faucets are pretty well grounded things. &amp;nbsp;Wrapping your clothes around them for a few minutes will drain them of most of their static charge.&lt;br /&gt;&lt;br /&gt;So, if you are lazy and don't want to go get dryer sheets - or maybe your one of those new-age enviro-douches who lives in constant fear of the dryer-sheet-ocolypse... whatever the case, if you don't want to use dryer sheets use the faucet to de-staticify your clothes before you wear them. &amp;nbsp;You have my personal guarantee that it will work.&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;sup&gt;*&lt;/sup&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;*&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt; Personal guarantees made by Max Guernsey, III are backed by nothing. &amp;nbsp;Void where prohibited. &amp;nbsp;Void where permitted.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-711548505101669149?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/711548505101669149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/living-without-dryer-sheets.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/711548505101669149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/711548505101669149'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/living-without-dryer-sheets.html' title='Living without Dryer Sheets'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-610944282632499491</id><published>2010-03-15T20:04:00.000-07:00</published><updated>2010-03-15T20:04:57.813-07:00</updated><title type='text'>Your Last Chance to Sign up for My Database Agility Course is Approaching!</title><content type='html'>Tomorrow, the Early Bird Special prices for the &lt;a href="http://www.netobjectives.com/course-schedule/database-agility-online-mar-2010"&gt;March-April Database Agility Online Training&lt;/a&gt; will expire. &amp;nbsp;Although I will probably start another one no later than July,&amp;nbsp;my schedule is pretty hectic so don't assume that I'll be starting one in May or June. &amp;nbsp;I might but I cannot make any promises.&lt;br /&gt;&lt;br /&gt;For those of you who don't know what this course is about: it tackles the critical problems that make Agile software development difficult in the database domain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-610944282632499491?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/610944282632499491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/your-last-chance-to-sign-up-for-my.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/610944282632499491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/610944282632499491'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/your-last-chance-to-sign-up-for-my.html' title='Your Last Chance to Sign up for My Database Agility Course is Approaching!'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2811116311100754906</id><published>2010-03-14T19:13:00.000-07:00</published><updated>2010-03-14T19:13:34.748-07:00</updated><title type='text'>Automation and Value Streams</title><content type='html'>Recently, I release a book called "&lt;a href="http://www.lulu.com/product/paperback/goad-testing-deepening-our-understanding-of-automated-tests/6396354"&gt;Goad Testing: Deepening our Understanding of Automated Tests&lt;/a&gt;." &amp;nbsp;While the general purpose of that particular writing is to help people find ways to keep their bed of tests as healthy as the tests help them keep their production code, it also hits on something that I believe and I talk about implicitly but never call out as a topic of its own...&lt;br /&gt;&lt;br /&gt;Automation of any kind - programs written for customers, machines that build cars, video games, and, yes, tests too - are really instruments of &lt;i&gt;process improvement&lt;/i&gt;. &amp;nbsp;In every single case they have no less than one of the following effects on some value stream:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;They provide access to&lt;i&gt;&amp;nbsp;&lt;/i&gt;information which enables the completion of a step&lt;/li&gt;&lt;li&gt;They reduce the amount of time a step takes&lt;/li&gt;&lt;li&gt;They improve the quality of the outcome produced by a step&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;...and really, these all resolve down to a single impact:&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Every piece of useful software reduces the amount of time required to complete some step in a value stream.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Whether or not the amount of time required without software made the step in question infeasible or caused the quality of its output to suffer is irrelevant, it's all a function of not being about to make a decision, come to a realization, trigger an action, store your findings, etc. &lt;i&gt;quickly&lt;/i&gt;. &amp;nbsp;There is nothing that software can do but we people cannot, given enough time. &amp;nbsp;Even the fact that software runs the same way every time it is executed in the same context translates into an impact on the time it takes to get something done by minimizing the potential for rework.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It all comes down to &lt;i&gt;time &lt;/i&gt;and &lt;i&gt;process&lt;/i&gt;, which is what Lean told us in the first place. &amp;nbsp;The customer for a test just happens to be the development team that will use the test to avoid releasing crappy software to their customers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Why does this matter? &amp;nbsp;...because people bandy about all these different explanations of what tests "really are..."&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;A test isn't really a test... it's a specification&lt;/li&gt;&lt;li&gt;A test isn't really a test... it's process control&lt;/li&gt;&lt;li&gt;A test isn't really a test... it's a performance metric&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Tests have the side effect of eliminating the need for a lot of those things but, at the end of the day, a test is a piece of software that reduces the cycle time of a development team by eliminating delays between the introduction of a defect and its discovery.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;A.K.A.&lt;/b&gt;: a "test."&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2811116311100754906?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2811116311100754906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/automation-and-value-streams.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2811116311100754906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2811116311100754906'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/automation-and-value-streams.html' title='Automation and Value Streams'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-3876216812012652851</id><published>2010-03-04T19:00:00.000-08:00</published><updated>2010-03-04T19:00:46.670-08:00</updated><title type='text'>Some Guy's Crazy, Cheesy Dream</title><content type='html'>This guy's trying to take $250k from Dorritos so that he can fight cancer and stuff.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.doritosviralocity.ca/Gallery/VideoDetails.aspx?v=6435"&gt;Check out his video here&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-3876216812012652851?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/3876216812012652851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/some-guys-crazy-cheesy-dream.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3876216812012652851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/3876216812012652851'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/some-guys-crazy-cheesy-dream.html' title='Some Guy&apos;s Crazy, Cheesy Dream'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-6506692768813287380</id><published>2010-03-01T22:18:00.000-08:00</published><updated>2010-03-01T22:18:52.213-08:00</updated><title type='text'>Branching with Design</title><content type='html'>&lt;blockquote&gt;&lt;i&gt;Code. &amp;nbsp;Code never changes.&amp;nbsp;&lt;/i&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;The end of the world occurred pretty much as we predicted. &amp;nbsp;Too much duplication. &amp;nbsp;Not enough manpower to go around.&amp;nbsp;&amp;nbsp;The details are trivial and pointless. &amp;nbsp;The reasons, as always, purely human ones.&amp;nbsp;&lt;/i&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;(adapted from the &lt;/i&gt;&lt;a href="http://www.youtube.com/watch?v=_mcJAI6oRYY"&gt;&lt;i&gt;beginning of the last real Fallout game&lt;/i&gt;&lt;/a&gt;&lt;i&gt;)&lt;/i&gt;&lt;/blockquote&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;I hate branches. &amp;nbsp;I hate them... and why shouldn't I? &amp;nbsp;Here is the promise of a branch...&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;We're going to defer integration for a long time so that it will cost more when we do it but don't worry, until the branch is merged, we're going to essentially maintain two copies of the same code base. &amp;nbsp;Make that three. &amp;nbsp;Make that four. &amp;nbsp;Make that... ah fuck it.&lt;/blockquote&gt;Recently, a pretty decent argument was made in favor of branching...&lt;br /&gt;&lt;blockquote&gt;We have to change &lt;i&gt;&lt;b&gt;X&lt;/b&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;. &amp;nbsp;Whenever we change &lt;/span&gt;&lt;b&gt;X&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;, everyone on the team is broken for months.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/blockquote&gt;Naturally, the first response is "Well, it shouldn't be that way." &amp;nbsp;To which the person with whom I was having the debate replied...&lt;br /&gt;&lt;blockquote&gt;I know but it is.&lt;/blockquote&gt;Check...&lt;br /&gt;&lt;blockquote&gt;We're trying to fix it but that's the way things are right now.&lt;/blockquote&gt;&amp;nbsp;...aaaaaaand mate.&lt;br /&gt;&lt;br /&gt;The team understood that it was a huge problem and wanted desperately to fix it but didn't have the resources to do all of the necessary refactoring before they had to change &lt;b&gt;&lt;i&gt;X&lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;. &amp;nbsp;Because of the size of the system, its complexity, and the level of encapsulation around &lt;i&gt;&lt;b&gt;X&lt;/b&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;, there were&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt; &lt;u&gt;going&lt;/u&gt;&amp;nbsp;&lt;/span&gt;&lt;/i&gt;to be breaks; no "if"s, "and"s, or "but"s about it.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;So what to do, then? &amp;nbsp;The answer is, as I'm sure you've guessed now, to branch with design. &amp;nbsp;What, precisely, does that mean? &amp;nbsp;The steps can be summarized pretty simply as follows:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Find the places where &lt;i&gt;&lt;b&gt;X&lt;/b&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;, is used and its behavior needs to change.&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Create a Facade that exposes just the functionality needed by those touch-points.&lt;/li&gt;&lt;li&gt;Promote the Facade to an abstraction with its only variation being the classic usages of &lt;b&gt;&lt;i&gt;X&lt;/i&gt;&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;Make the old behavior the default variation of your Facade abstraction.&lt;/li&gt;&lt;li&gt;Create another variation into which the new behavior is placed; provide QA with a place to "turn on" the new behavior.&lt;/li&gt;&lt;/ol&gt;The alternate behavior can be a Proxy to&amp;nbsp;&lt;i&gt;&lt;b&gt;X&lt;/b&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;, an alternate implementation... it can even be incomplete or not work - it's not being used in the normal "production" code path. &amp;nbsp;Yet, your "branch" is continuously integrated.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;Without even touching your continuous integration configuration code, your "branch" will be built with the rest of the code. &amp;nbsp;If a test fails against it, your build goes red. &amp;nbsp;If you forget a semicolon, your build goes red. &amp;nbsp;You will receive continuous feedback as though you didn't branch... because you didn't. &amp;nbsp;Yet you will be able to insulate people working on other things from pain caused by your changes as if you did.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;Now, I'm not claiming this as my own. &amp;nbsp;It would have to be crazy to do so as it is basically nothing more than a narration of how the Facade pattern plays out when you pursue it aggressively. &amp;nbsp;My point is not "Hey! &amp;nbsp;Look at this neat thing I invented," because I didn't invent it.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;Instead, my point is that you can always do this and it always works. &amp;nbsp;I'm sure that, somewhere out in the world, someone has a good reason why they absolutely &lt;u&gt;have to&lt;/u&gt; branch. &amp;nbsp;Disregarding such one-in-a-million scenarios, you should always branch with design rather than with source control. &amp;nbsp;It's safer, cleaner, and lower cost.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-6506692768813287380?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/6506692768813287380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/branching-with-design.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6506692768813287380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/6506692768813287380'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/03/branching-with-design.html' title='Branching with Design'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2900080184921879616</id><published>2010-02-28T08:59:00.000-08:00</published><updated>2010-02-28T08:59:08.301-08:00</updated><title type='text'>Upcoming Database Agility Online Training</title><content type='html'>I will be running another course on database agility over the internet starting on March 16th. &amp;nbsp;This course is designed to give you an understanding of what the impediments to Agility in database development are and, of course, to show you how to overcome those impediments.&lt;br /&gt;&lt;br /&gt;For more information click on the following link:&lt;br /&gt;&lt;a href="http://www.netobjectives.com/course-schedule/database-agility-online-mar-2010"&gt;http://www.netobjectives.com/course-schedule/database-agility-online-mar-2010&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2900080184921879616?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2900080184921879616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/upcoming-database-agility-online.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2900080184921879616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2900080184921879616'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/upcoming-database-agility-online.html' title='Upcoming Database Agility Online Training'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1102208530405835763</id><published>2010-02-27T16:24:00.000-08:00</published><updated>2010-02-27T16:24:57.833-08:00</updated><title type='text'>Facts and Certitude (A Retardation Celebration!)</title><content type='html'>Remember &lt;a href="http://seattletimes.nwsource.com/html/editorialsopinion/2011132171_pitts21.html"&gt;this dumb article&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;Well, I've heard back from the team involved - at least from the assistant.&lt;br /&gt;&lt;br /&gt;I'll paraphrase:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Them:&amp;nbsp;&lt;/b&gt;You don't understand, this guy didn't agree with us.&lt;br /&gt;&lt;b&gt;Me: &lt;/b&gt;Oh I get that, how come that's wrong and you not agreeing with him is okay?&lt;br /&gt;&lt;b&gt;Them: &lt;/b&gt;His argument was "Nuh-uh."&lt;br /&gt;&lt;b&gt;Me:&lt;/b&gt;&lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;Are you sure that wasn't &lt;i&gt;your&lt;/i&gt;&amp;nbsp;argument?&lt;br /&gt;&lt;b&gt;Them: &lt;/b&gt;But he didn't accept a fact.&lt;br /&gt;&lt;b&gt;Me: &lt;/b&gt;Where does the fact come from? &amp;nbsp;How come your source is more valid than his?&lt;br /&gt;&lt;b&gt;Them: &lt;/b&gt;No... no... you just don't get it. &amp;nbsp;This is a &lt;i&gt;proven&lt;/i&gt;&amp;nbsp;fact.&lt;br /&gt;&lt;b&gt;Me: &lt;/b&gt;Proofs are only ironclad in how it leads from assumptions to conclusions. &amp;nbsp;The postulates (and, therefore the conclusions) themselves are still open for debate.&lt;br /&gt;&lt;b&gt;Them:&lt;/b&gt;&amp;nbsp;You're trying to claim I don't understand. &amp;nbsp;Thanks for your input.&lt;br /&gt;&lt;b&gt;Me:&lt;/b&gt;&amp;nbsp;(thinking&lt;i&gt;&amp;nbsp;duh!&lt;/i&gt;) I hope you see how funny that is. &amp;nbsp;I sure do, so thanks for enriching my day.&lt;br /&gt;&lt;br /&gt;I'll go out on a limb here and say that there are some far worse arguments against the freedom of the press than these people - Glen Beck, for example - but, still, the fact that they are contributing to the media and inundating the weak minded with false certainty makes them part of the problem not part of the solution.&lt;br /&gt;&lt;br /&gt;We need to come up with a system that routes people like this to jobs for which they are better suited. &amp;nbsp;For instance, I would suggest that the person I talked to should be taking &lt;i&gt;out&lt;/i&gt;&amp;nbsp;the trash rather than filling people's heads with it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1102208530405835763?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1102208530405835763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/facts-and-certitude-retardation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1102208530405835763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1102208530405835763'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/facts-and-certitude-retardation.html' title='Facts and Certitude (A Retardation Celebration!)'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-2318159250960759765</id><published>2010-02-25T20:25:00.000-08:00</published><updated>2010-02-25T20:25:55.567-08:00</updated><title type='text'>Original Sin</title><content type='html'>&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: #001320; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 500; line-height: 21px;"&gt;&lt;i&gt;Either make the abstraction good and its variations good, or make the abstraction bad and its variations bad; for the abstraction is known by its variations.&lt;/i&gt;&lt;/span&gt;&lt;/blockquote&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="color: #001320; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 500; line-height: 21px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-weight: normal; line-height: normal;"&gt;We do not inherit to specialize, we inherit to add variation behind abstraction. &amp;nbsp;Yet both of the major platforms today - Java and .NET - force every object to specialize a base class. &amp;nbsp;For Java, you have to inherit &lt;/span&gt;&lt;span class="Apple-style-span" style="color: black; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;java.Object&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-weight: normal; line-height: normal;"&gt;, and for .NET it is &lt;/span&gt;&lt;span class="Apple-style-span" style="color: black; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;System.Object&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #001320; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 500; line-height: 21px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: black; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #001320; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 500; line-height: 21px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: black; font-size: medium; font-style: normal; line-height: normal;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;...but it really doesn't matter; the damage is done either way.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is the "original sin" of software development. &amp;nbsp;Every object must be able to determine if it is equivalent to another. &amp;nbsp;Every object must be able to bucket itself with equivalent and similar objects. &amp;nbsp;Every object must be able to convert itself to a string.&lt;br /&gt;&lt;br /&gt;Whether you need these features or not, you must, at the very least, inherit them. &amp;nbsp;The true nature of abstraction is, therefore, tarnished. &amp;nbsp;You can never have a&lt;i&gt;&amp;nbsp;pure&lt;/i&gt;&amp;nbsp;interface for every object is tarnished by the sins of its base class's designers. &amp;nbsp;Consequently, programmers will, forever, be weighed down by the mental model of objects as "data with behavior" that is so apparent in their platform's design.&lt;br /&gt;&lt;br /&gt;I hope that, when he next real platform (ruby and python don't count, guys... I hope you all figure that out, soon), its architects will be more enlightened. &amp;nbsp;In the mean time, I hope you can bring yourself to flat-out ignore those garbage behaviors that every object inherits.&lt;br /&gt;&lt;br /&gt;P.S.: Isn't it interesting that we, the gods of software, are the ones truly responsible for a sin of design committed by a single ancestor and that said sin burdens its every inheritor?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-2318159250960759765?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/2318159250960759765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/original-sin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2318159250960759765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/2318159250960759765'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/original-sin.html' title='Original Sin'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1980502524332495180</id><published>2010-02-24T21:50:00.000-08:00</published><updated>2010-02-25T20:00:04.509-08:00</updated><title type='text'>Remember when Facts Ended Arguments?</title><content type='html'>I sure don't.&lt;br /&gt;&lt;br /&gt;Thanks to fark, I recently stumbled upon &lt;a href="http://seattletimes.nwsource.com/html/editorialsopinion/2011132171_pitts21.html"&gt;this article&lt;/a&gt;. &amp;nbsp;Go ahead and read it for yourself, if you like. &amp;nbsp;If you'd prefer to spend a few minutes of your life doing something more productive - like setting an orphanage on fire or smoking crack - I'll save you the trouble with by summarizing:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;"I miss the days when people who didn't agree to me would simply cow tow to an appeal to authority."&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;Yep. &amp;nbsp;Those were the days. &amp;nbsp;I sure miss the days when people refused to think for themselves or ask "why." &amp;nbsp;Remember all the good things that came out of mindless obedience to those who claim knowledge with sufficient emphasis? &amp;nbsp;It's hard to count them all but I'll take a shot:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Witch-hunts&lt;/li&gt;&lt;li&gt;The Inquisition&lt;/li&gt;&lt;li&gt;The Crusades&lt;/li&gt;&lt;li&gt;The "War" on Terror&lt;/li&gt;&lt;li&gt;The "War" on Drugs&lt;/li&gt;&lt;li&gt;The Holocaust&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I knew I would never make it through to the end of the list... after all, I'll probably only live another thirty to sixty years... but it was worth a try. &amp;nbsp;That guy's article is like a handmade Christmas card: heartfelt an the product of careful attention but ultimately worthless.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you don't agree, indulge me by considering the following questions:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Do you understand the difference between "hypothesis," "truth," and "theory?"&lt;/li&gt;&lt;li&gt;What do you think the difference between our collective model of the universe and the universe itself is?&lt;/li&gt;&lt;li&gt;Do &lt;i&gt;you&lt;/i&gt; remember when facts settled arguments?&lt;/li&gt;&lt;ul&gt;&lt;li&gt;When, specifically, was that?&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;What are “facts?”&lt;/li&gt;&lt;ul&gt;&lt;li&gt;What makes a “fact” good enough to “settle” an argument?&lt;/li&gt;&lt;li&gt;Who chooses these which assertions are “facts” and which are “opinions?”&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Was&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Phlogiston_theory"&gt;phlogiston theory&lt;/a&gt;&amp;nbsp;a fact when it was ?&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Is it now?&lt;/li&gt;&lt;li&gt;Was it one before it was believed?&lt;/li&gt;&lt;li&gt;If it wasn't a fact, was it bad?&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Do you have the power to tell me which facts are true and which will be contraindicated in the future?&lt;/li&gt;&lt;ul&gt;&lt;li&gt;If so, can you tell when?&lt;/li&gt;&lt;li&gt;(I would pay you handsomely for the use of that talent, by the way)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;How, in your mind, do facts and beliefs differ?&lt;/li&gt;&lt;li&gt;What is the difference between proof and evidence?&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1980502524332495180?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1980502524332495180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/remember-when-facts-ended-arguments.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1980502524332495180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1980502524332495180'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/remember-when-facts-ended-arguments.html' title='Remember when Facts Ended Arguments?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-8928802959256653327</id><published>2010-02-21T13:46:00.000-08:00</published><updated>2010-02-21T13:49:33.228-08:00</updated><title type='text'>Is Encapsulation Creating Duplication?</title><content type='html'>The answer is a definite "no." &amp;nbsp;Each is the other's anathema. &amp;nbsp;Yet sometimes it looks like concision and encapsulation are at odds.&lt;br /&gt;&lt;br /&gt;Let's take the simple example of encapsulating construction. &amp;nbsp;When you encapsulate a constructor, you might do something very simple as follows:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;public class MyService {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;private MyService() { }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;public static MyService GetInstance() {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return new MyService();&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.netobjectives.com/resources/webinars/encapsulate-construction-software-design"&gt;argument&lt;/a&gt; for encapsulating construction are pretty ironclad. &amp;nbsp;It's essentially free, and it lets you promote a class from a concrete class to an abstract one. &amp;nbsp;At least, theoretically speaking...&lt;br /&gt;&lt;br /&gt;When you get into it, you find that something very annoying occurs. &amp;nbsp;Let's say that we need a new parameter when producing instances of MyService. &amp;nbsp;We have to make that change in two places.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;public class MyService {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;private MyService(string parameter1) { }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;public static MyService GetInstance(string parameter1) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return new MyService(parameter1);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;This is arguably unavoidable: the system was &lt;i&gt;closed&lt;/i&gt;&amp;nbsp;to variation in whatever &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;parameter1&lt;/span&gt;&lt;/span&gt; represents. &amp;nbsp;We had to refactor the system to be &lt;i&gt;open&lt;/i&gt;&amp;nbsp;to that kind of variation and &lt;i&gt;closed&lt;/i&gt; to future change pertaining to the same concept. &amp;nbsp;Yes we had to make a change in two places to be complete but we did it to improve design so its okay.&lt;br /&gt;&lt;br /&gt;What about when we add another parameter? &amp;nbsp;Is that just another refactor? &amp;nbsp;What about when we want to delegate some of the work off to another method? &amp;nbsp;Do we now have to maintain two parameters in three signatures and some number of method calls? &amp;nbsp;In areas where change is the most common, the problem becomes clear quickly.&lt;br /&gt;&lt;br /&gt;"Keep it simple!" someone might cry, "That's what you did wrong, you made things &lt;i&gt;complex&lt;/i&gt;&amp;nbsp;by adding a whole bunch of unnecessary methods."&lt;br /&gt;&lt;br /&gt;&lt;a href="http://maxguernsey.spaces.live.com/blog/cns!23373E9A68E6B14B!140.entry"&gt;Nonsense&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The problem isn't that I improved design. &amp;nbsp;The problem is that I &lt;i&gt;missed an opportunity&lt;/i&gt;&amp;nbsp;to improve design again when I added the parameter. &amp;nbsp;I made the called methods open-closed to the arguments with which they could be called (which is the whole point of a parameter) but I didn't encapsulate them from changes to the arguments, themselves.&lt;br /&gt;&lt;br /&gt;What if I had done something like the following, instead?&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;public class MyService {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;public class InstantiationArguments {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public string Parameter1 { get; set; }&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;private MyService(InstantiationArguments arguments) { }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;public static MyService GetInstance(InstantiationArguments arguments) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return new MyService(parameter1);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;That would have been a much better refactor. &amp;nbsp;For one thing, I would have been applying the open-closed principle correctly - rendering the thing I am refactoring open-closed to the kind of change I am introducing (changes to method signature). &amp;nbsp;For another, I could have done my work in smaller steps: first making the instantiation behavior open-closed to its parameters, then adding the parameter and handling its value.&lt;br /&gt;&lt;br /&gt;The point here is this: the principles of design seem unassailable; at least, with our current knowledge. &amp;nbsp;When it look like a principle isn't working, it is most likely that you (or I) just cannot &lt;i&gt;see&lt;/i&gt;&amp;nbsp;how it applies and less likely that the principle is wrong or requires refinement.&lt;br /&gt;&lt;br /&gt;There is no room for "moderation" when adhering to principles. &amp;nbsp;If there were, they wouldn't be principles. &amp;nbsp;You either refine them, figure out how to follow them, or perish at the hands of someone more competitive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-8928802959256653327?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/8928802959256653327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/is-encapsulation-creating-duplication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8928802959256653327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/8928802959256653327'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/is-encapsulation-creating-duplication.html' title='Is Encapsulation Creating Duplication?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-1220138805338762164</id><published>2010-02-19T23:48:00.000-08:00</published><updated>2010-02-19T23:48:05.300-08:00</updated><title type='text'>Goad Testing</title><content type='html'>Well. &amp;nbsp;I've spent long enough with this particular writing sitting on the shelf collecting dust. &amp;nbsp;I decided to finally get off my ass and publish it. &amp;nbsp;It is entitled &lt;i&gt;Goad Testing: Deepening our Understanding of Automated Tests&lt;/i&gt;. &amp;nbsp;In addition to (hopefully) doing as the subtitle promises, the booklet teaches a technique that expands test driven development by ensuring that each test makes a &lt;i&gt;distinction&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;As was the case with &lt;i&gt;&lt;a href="http://www.informit.com/store/product.aspx?isbn=032163604X"&gt;Transition Testing: Cornerstone of Database Agility&lt;/a&gt;&lt;/i&gt;, I intend to have this writing be a short introduction to a broader concept. &amp;nbsp;Later, when I have more time on my hands, a book will follow about the larger concept.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.lulu.com/content/paperback-book/goad-testing-deepening-our-understanding-of-automated-tests/8372524"&gt;Click here&lt;/a&gt; to check out&amp;nbsp;&lt;i&gt;Goad Testing&lt;/i&gt; now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-1220138805338762164?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/1220138805338762164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/goad-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1220138805338762164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/1220138805338762164'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2010/02/goad-testing.html' title='Goad Testing'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-114058411202913512</id><published>2006-02-21T20:53:00.000-08:00</published><updated>2006-02-21T20:55:12.030-08:00</updated><title type='text'>Why does my code get screwed up?</title><content type='html'>&lt;p&gt;Why does blogger.com screw up my code? Does anyone out there know a good way to post code? &lt;/p&gt;&lt;p&gt;I've yet to find a good way to post an attachment.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-114058411202913512?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/114058411202913512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/why-does-my-code-get-screwed-up.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/114058411202913512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/114058411202913512'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/why-does-my-code-get-screwed-up.html' title='Why does my code get screwed up?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-114042746792615886</id><published>2006-02-20T00:58:00.000-08:00</published><updated>2006-02-24T00:48:10.170-08:00</updated><title type='text'>The Barrier Method</title><content type='html'>&lt;p&gt;They say it's the only safe way... use a barrier method every time.&lt;/p&gt;&lt;p&gt;Seriously, though. I was pleased to see that .Net 2.0 contained an implementation of &lt;a href="http://msdn2.microsoft.com/en-us/library/system.threading.semaphore(VS.80).aspx"&gt;Semaphore&lt;/a&gt;. It contains a lot of cool stuff. Something it doesn't have, though, is a barrier. Barriers are a synchronization tool that can be used to ensure no thread starts working until the desired number of threads are ready.&lt;/p&gt;&lt;p&gt;A good real life analogy for a barrier is the starter in a race. The starter makes sure that all of the runners (threads) are at their marks. When all of the contestants are ready, the starter fires his fake pistol and they're off. That's what the barrier does. It's not the most commonly used synchronization tool - I use it mostly in tests - but it can come in handy.&lt;/p&gt;&lt;p&gt;Below, I've implemented a barrier as a wait handle. I commented it a little but, frankly, I'm tired. It should be pretty clear how it works.&lt;/p&gt;&lt;p&gt;Google blogging screws up one's code, so I've moved the example to a &lt;a href="http://www.harbingersoftware.com/FreeCode/Barrier/BarrierCode.cs.txt"&gt;seperate text file&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-114042746792615886?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/114042746792615886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/barrier-method.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/114042746792615886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/114042746792615886'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/barrier-method.html' title='The Barrier Method'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-114038608752898279</id><published>2006-02-19T12:41:00.000-08:00</published><updated>2006-02-24T00:54:16.110-08:00</updated><title type='text'>WebPart Skins &amp; User Controls</title><content type='html'>&lt;p&gt;Today, we're developing a &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.webpart.aspx"&gt;web part&lt;/a&gt;. This web part has the requirement that administrators be able to edit the user interface through the web UI. Since more than instance may be deployed to a single web site and one web site can span more than one host, we cannot simply provide an editor for a file.&lt;/p&gt;&lt;p&gt;What we really need is the ability to treat one of our web part's properties as a &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.usercontrol.aspx"&gt;user control&lt;/a&gt;. Of course, user controls are useless if they can't have scripts or databinding in them, so we cannot simply use &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.templatecontrol.parsecontrol.aspx"&gt;TemplateControl.ParseControl&lt;/a&gt;; we have to use &lt;a href="http://msdn2.microsoft.com/en-us/library/t9ecy7tf.aspx"&gt;LoadControl&lt;/a&gt;. Now we see our problem: LoadControl requires a file but we want to persist our control as a property.&lt;/p&gt;&lt;p&gt;The solution ends up being pretty simple: We store the body of our skin as a property of our web part with freshness data. In the solution provided here, our freshness data is a &lt;a href="http://msdn2.microsoft.com/en-us/library/system.guid(VS.80).aspx"&gt;Guid&lt;/a&gt; and the body of our skin is the text portion of a user control (we are foregoing code-behind, for now). Every time an instance of our web part is rendered, it tries to load its skin from a cache directory (which is also specified via property) using the Guid as its name. If the file does not exist, we create it.&lt;/p&gt;&lt;p&gt;The result is, effectively, every time an administrator saves a change to a web part, a new use control will be created on every host. Since the user control is loaded from a file, it will get the advantage of ASP.NET's caching &amp; compilation infrastructure; meaning it can have custom code and data-bindings in it.&lt;/p&gt;&lt;p&gt;Unfortunately, Google Blogs screws up source code.  You can download an example &lt;a href="http://www.harbingersoftware.com/FreeCode/WebPartSkins/WebPartSkinsCode.cs.txt"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;A nightly job can clean up old items by simply deleting all the files in the cache folder: the ones worth saving will get regenerated the next time they are needed anyway.&lt;/p&gt;&lt;p&gt;"Why?" you ask, or maybe, "Why not just use files?" I cannot answer that. I mean: I &lt;em&gt;know&lt;/em&gt; the answer; I just can't give it to you right now. There are some out there who know why already. To anyone who asks "why" the only legal answer I can give you is "you'll see."&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-114038608752898279?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/114038608752898279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/webpart-skins-user-controls.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/114038608752898279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/114038608752898279'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/webpart-skins-user-controls.html' title='WebPart Skins &amp; User Controls'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-114007695980333370</id><published>2006-02-15T21:09:00.000-08:00</published><updated>2006-02-24T01:06:46.330-08:00</updated><title type='text'>Skin me.  Skin me, my friend.</title><content type='html'>Skin me again!&lt;br /&gt;&lt;br /&gt;Okay, today I'm going to give you a little example of skinning. This is a super-simple case. Here, we have a controller class called "SquareIt." SquareIt lives in an assembly named "SkinExample.UI" and inherits from System.Web.UI.Control. There is also an interface ("ISquareItSkin") that serves as the contract between the SquareIt class and its skins.&lt;br /&gt;&lt;br /&gt;For simplicity's sake we are just dealing with skinning. We are not separating any business logic into separate classes.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.harbingersoftware.com/FreeCode/AspNetSkins/AspNetSkinsCode.zip"&gt;Let the code speak for itself&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-114007695980333370?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/114007695980333370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/skin-me-skin-me-my-friend.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/114007695980333370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/114007695980333370'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/skin-me-skin-me-my-friend.html' title='Skin me.  Skin me, my friend.'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-113999532207809948</id><published>2006-02-15T01:11:00.000-08:00</published><updated>2006-02-16T22:58:13.423-08:00</updated><title type='text'>Let's talk about skinning</title><content type='html'>No, not the "it puts the lotion in the basket" kind: the "my UI and business are loosely coupled" kind. In this post we are going to discuss a good way to break the user interface out of your system: Skinning. When you make your application "skinnable," you allow users to load new looks-and-feels at run-time. There is a Skin Pattern out there. Unfortunately, there is no definitive authority on what, exactly, the Skin Pattern is. There don't really seem to be any good authorities on what any pattern is, for that matter. I am going to talk about &lt;em&gt;a&lt;/em&gt; way of implementing Skinning, not &lt;em&gt;the&lt;/em&gt; way.&lt;br /&gt;&lt;br /&gt;Skinning is little more than a fancy name wrapped around the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpatterns/html/DesMVC.asp"&gt;Model-View-Controller&lt;/a&gt; pattern. Why that's not called the "Model-Controller-View" pattern is lost on me. Really quickly: Let's not get true skinning confused with &lt;a href="http://msdn2.microsoft.com/en-us/library/ykzx33wh.aspx"&gt;ASP.NET Themse or Skins&lt;/a&gt;, which solve the problems that &lt;a href="http://www.w3.org/Style/CSS/"&gt;css&lt;/a&gt; should have. If you are one of those people who is in to service-oriented architecture, think of the skin as just another service: the "interface with foreign actor" service. If you are into MVC, think of a skin as a loadable view with a few extra restrictions. If you are someone who doesn't need fancy-pants terminology wrappped around everything you do then, well, good for you... we could probably be friends.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/1379/2230/1600/SkinPatternExample.0.jpg"&gt;&lt;/a&gt;&lt;a href="http://photos1.blogger.com/blogger/1379/2230/1600/SkinPatternExample.1.jpg"&gt;&lt;/a&gt;&lt;a href="http://photos1.blogger.com/blogger/1379/2230/1600/SkinPatternExample.2.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/1379/2230/200/SkinPatternExample.1.jpg" border="0" /&gt;&lt;/a&gt;Consider the leftward class system. There are a number of business objects which represent the "Model." If you are an SOA guy, then they are your various data and business intelligence services. There is a controller that coordinates between the business objects and the skin. Finally, there are skins which compose the "View." For SOA people, the skin is just another service that allows foreign actors to communicate with a system.&lt;br /&gt;&lt;br /&gt;There are slight differences between making an application "skinnable" and using the MVC pattern. For one, in the MVC pattern, the view is allowed to access the model. In the implementation of skinning proposed here (and in any instantiation of the Skin Pattern worth its salt, really), the Skin (the View) is not allowed to talk with the business objects (the Model). Also, while skins cannot provide new functionality, they are able to hide existing functionality. Additionally, there is a difference of intent. Most often, I have seen MVC used to create modularity between the presentation, the business intelligence, and the data; the ultimate goal being maintainability. Skinning, on the other hand, generally &lt;em&gt;takes advantage&lt;/em&gt; of modularity to allow run-time selection and/or customization of the UI; the ultimate goal being flexibility.&lt;br /&gt;&lt;br /&gt;In the diagram above, you should see an ISkin interface. This interface should serve as a contract between the controller and the skin. The contract defines three means of interaction:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Messages from the Controller to the Skin&lt;/li&gt;&lt;li&gt;Messages from the Skin to the Controller&lt;/li&gt;&lt;li&gt;Shared data&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Messages from the Controller should be passed to the skin via method calls. Messages from the skin should be posted via an event. Shared data should be referenced by properties. Once you have defined the contract between your controller and its skin, you may then implement the skin and controller in whatever order and manner you choose. The end result is that you have a modular system in which new user interfaces can be deployed independantly of the application itself.&lt;/p&gt;&lt;p&gt;A code example of how this might be implemented will be posted in the near future.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-113999532207809948?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/113999532207809948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/lets-talk-about-skinning.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113999532207809948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113999532207809948'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/lets-talk-about-skinning.html' title='Let&apos;s talk about skinning'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-113920796415148910</id><published>2006-02-05T22:16:00.000-08:00</published><updated>2006-02-24T01:11:35.506-08:00</updated><title type='text'>PolyLoginView</title><content type='html'>This is another variant of LoginView. This one is for building a role-based dashboard. It instantiates the template for each applicable &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.rolegroup.aspx"&gt;RoleGroup&lt;/a&gt;. A &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.rolegroup.aspx"&gt;RoleGroup&lt;/a&gt; is considered applicable when all a user is in all of its roles.&lt;br /&gt;Of course, since Google Blogs screws up my code, I have to put it &lt;a href="http://www.harbingersoftware.com/FreeCode/PolyLoginView/PolyLoginViewCode.zip"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-113920796415148910?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/113920796415148910/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/polyloginview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113920796415148910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113920796415148910'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/polyloginview.html' title='PolyLoginView'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-113919204411246053</id><published>2006-02-05T18:09:00.000-08:00</published><updated>2006-02-24T01:14:24.626-08:00</updated><title type='text'>ScopedLoginView</title><content type='html'>Okay, here is a LoginView that is not bound to the default provider.  Of course, I would like to be able to just post it to the web, bug Google Blogs does not support that, so I have to put it &lt;a href="http://www.harbingersoftware.com/FreeCode/ScopedLoginView/ScopedLoginViewCode.zip"&gt;here&lt;/a&gt;, instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-113919204411246053?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/113919204411246053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/scopedloginview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113919204411246053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113919204411246053'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/scopedloginview.html' title='ScopedLoginView'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-113912889013146923</id><published>2006-02-05T00:01:00.000-08:00</published><updated>2006-02-05T01:19:31.680-08:00</updated><title type='text'>Is Java on its way out?</title><content type='html'>Of course not. I hate stupid questions like that. "Is .Net dying?" is just as idiotic.&lt;br /&gt;&lt;br /&gt;People who ask questions like that are good arguments for eugenics. There. I said it. If you call into question the short-term survivability of a platform as vibrant as either .Net or Java, you should be sterilized. As should all of your offspring.&lt;br /&gt;&lt;br /&gt;...possibly anyone who didn't slap you when you initially asked the question.&lt;br /&gt;&lt;br /&gt;Okay. That's out of my system. Pending a disclaimer, let's ask some real questions.&lt;br /&gt;&lt;br /&gt;DISCLAIMER: I am not an authority on Microsoft's motives. I am not an authority on anything, for that matter.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Question #1:&lt;/strong&gt; A common pattern, in today's world, is to program to an interface and use an abstract factory, service locator, etc. to obtain instances thereof. How come most of the .Net framework does not use this pattern?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Answer #1:&lt;/strong&gt; You won't like the answer.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Question #2:&lt;/strong&gt; No, seriously, tell me!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Answer #2:&lt;/strong&gt; Because you make them cry. People, generally, don't understand things. For instance: beyond the basics, I don't know how a car or a lung works. The world is big and scary. It is filled with monsters, wars, tragic deaths, and scary spiders. These and a myriad other things all drive the average person - including the average programmer - to simply "tune out." Having to explicitly use an abstract factory or other "servicey-locatory-type-thingy" is an extra step that half the people just won't comprehend and the other half will question the validity of. Using &lt;strong&gt;new&lt;/strong&gt;, on the other hand is comfortable; It's easy to read and understand.&lt;br /&gt;&lt;br /&gt;Fortunately for everyone, those tricksy hobbitses at Microsoft figured out a way to build a "servicey-locatory-type-thingy" directly into the .Net platform: &lt;a href="http://msdn2.microsoft.com/2fc472t2.aspx"&gt;binding redirection&lt;/a&gt;. Through this artifice Microsoft can update a .Net framework assembly without disrupting dependent assemblies. That's right: Because of &lt;a href="http://msdn2.microsoft.com/2fc472t2.aspx"&gt;binding redirection&lt;/a&gt;, you can sit on your couch, drink your pepsi cola all evening, leave the reality TV shows running while you sleep, then drive your SUV to work and keep using &lt;strong&gt;new&lt;/strong&gt; without having to worry if Microsoft is going to update an assembly on you.&lt;br /&gt;&lt;br /&gt;The bottom line is this: They did implement a dependency inversion mechanism it's just too transparent for most people to see and they did it that way because they don't trust you. I don't trust you either but that's probably not your fault: I know the coffee machine lies but it's words are like honey... I just get all mixed up.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Question #3:&lt;/strong&gt; Should I just use &lt;a href="http://msdn2.microsoft.com/2fc472t2.aspx"&gt;binding redirection&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Answer #3:&lt;/strong&gt; If you have to ask, the answer is probably "no." There are reasons to use it and reasons not to use it. Let's go over them together as two friends holding hands:&lt;br /&gt;&lt;br /&gt;Good points:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You can apply it to applications you have already deployed&lt;/li&gt;&lt;li&gt;It allows for intuitive construction of objects using new&lt;/li&gt;&lt;li&gt;It requires no maintenance&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Bad point:&lt;br /&gt;&lt;br /&gt;There is really only one bad point. Reliance on &lt;a href="http://msdn2.microsoft.com/2fc472t2.aspx"&gt;binding redirection&lt;/a&gt; as one's primary mechanism for dependency inversion hides certain design problems until after the fact. If you have to conform to a service location mechanism, you are more likely to think about where boundaries between services and consumers might be. Likewise: you are more likely to use interfaces to address a class hierarchy than actual implementations.&lt;br /&gt;&lt;br /&gt;The System.IO namespace is a good example of the downfall of reliance on &lt;a href="http://msdn2.microsoft.com/2fc472t2.aspx"&gt;binding redirection&lt;/a&gt;. All streams must derive from &lt;a href="http://msdn2.microsoft.com/en-us/library/system.io.stream.aspx"&gt;System.IO.Stream&lt;/a&gt;, which is monolithic and does not capture the essence of "streamness." Instead, because .Net's linear inheritence is so limiting, it attempts to provide hooks for all features that a stream &lt;em&gt;might&lt;/em&gt; offer. If you need a concrete example, take &lt;a onclick="javascript:TrackThisClick('ctl00_LibFrame_MainContent_ctl06','ctl00_LibFrame_MainContent_ctl06::ctl00_LibFrame_MainContent_ctl09',this.href);" href="http://msdn2.microsoft.com/en-us/library/system.io.stream.cantimeout.aspx"&gt;CanTimeout&lt;/a&gt;, &lt;a onclick="javascript:TrackThisClick('ctl00_LibFrame_MainContent_ctl06','ctl00_LibFrame_MainContent_ctl06::ctl00_LibFrame_MainContent_ctl13',this.href);" href="http://msdn2.microsoft.com/en-us/library/system.io.stream.readtimeout.aspx"&gt;ReadTimeout&lt;/a&gt;, and &lt;a onclick="javascript:TrackThisClick('ctl00_LibFrame_MainContent_ctl06','ctl00_LibFrame_MainContent_ctl06::ctl00_LibFrame_MainContent_ctl14',this.href);" href="http://msdn2.microsoft.com/en-us/library/system.io.stream.writetimeout.aspx"&gt;WriteTimeout&lt;/a&gt;. In a proper, interface-driven, class system, one might break these out into a seperate interface (one that implemented IStream); it is likely that &lt;a onclick="javascript:TrackThisClick('ctl00_LibFrame_MainContent_ctl06','ctl00_LibFrame_MainContent_ctl06::ctl00_LibFrame_MainContent_ctl09',this.href);" href="http://msdn2.microsoft.com/en-us/library/system.io.stream.cantimeout.aspx"&gt;CanTimeout&lt;/a&gt; would retire altogether.&lt;br /&gt;&lt;br /&gt;Again, this is not a failing of &lt;a href="http://msdn2.microsoft.com/2fc472t2.aspx"&gt;binding redirection&lt;/a&gt;, it is a failing of the class-system designer. &lt;a href="http://msdn2.microsoft.com/2fc472t2.aspx"&gt;Binding redirection&lt;/a&gt; is just an accessory.&lt;br /&gt;&lt;br /&gt;I tend not to use &lt;a href="http://msdn2.microsoft.com/2fc472t2.aspx"&gt;binding redirection&lt;/a&gt; and, when I'm helping an organization set its infrastructure up, I recommend against it.  A custom solution is easy to implement (more on that later... I'm tired), easy to maintain, and begs certain questions that historically people do not ask.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-113912889013146923?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/113912889013146923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/is-java-on-its-way-out.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113912889013146923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113912889013146923'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/is-java-on-its-way-out.html' title='Is Java on its way out?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21981243.post-113911851674404219</id><published>2006-02-04T21:42:00.000-08:00</published><updated>2006-02-04T21:57:14.890-08:00</updated><title type='text'>Why, god?  Why?</title><content type='html'>All I ever wanted from you was... ten... million... dollors!&lt;br /&gt;&lt;br /&gt;Seriously.  I'm smacking my head up against a wall looking for a way to tell my &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.loginview.aspx"&gt;LoginView&lt;/a&gt; which &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.security.roleprovider.aspx"&gt;RoleProvider&lt;/a&gt; to use.&lt;br /&gt;&lt;br /&gt;Well, not really.  It is annoying, though.  I guess we'll just have to write one that is complete.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21981243-113911851674404219?l=maxg3prog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://maxg3prog.blogspot.com/feeds/113911851674404219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/why-god-why.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113911851674404219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21981243/posts/default/113911851674404219'/><link rel='alternate' type='text/html' href='http://maxg3prog.blogspot.com/2006/02/why-god-why.html' title='Why, god?  Why?'/><author><name>Max Guernsey, III</name><uri>http://www.blogger.com/profile/09455092244023527348</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_-GTjGvlJ3bE/S3m3ND6J98I/AAAAAAAAAAM/0MLaUKDQmYw/S220/Max+Guernsey+-+Publicity+Photo+-+Web.jpg'/></author><thr:total>0</thr:total></entry></feed>
