<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-6928325842095718321</atom:id><lastBuildDate>Wed, 11 Nov 2009 00:35:37 +0000</lastBuildDate><title>IFormattable</title><description>Saving you time by making my hard-won .NET knowledge available through a free-text search.</description><link>http://iformattable.blogspot.com/</link><managingEditor>noreply@blogger.com (Christopher)</managingEditor><generator>Blogger</generator><openSearch:totalResults>106</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Iformattable" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">Iformattable</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-1603908937942063713</guid><pubDate>Tue, 10 Nov 2009 18:44:00 +0000</pubDate><atom:updated>2009-11-10T13:47:03.378-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">powershell</category><category domain="http://www.blogger.com/atom/ns#">xml</category><category domain="http://www.blogger.com/atom/ns#">localization</category><title>Create an XML Schema Enumeration of Supported .NET CultureInfo with Powershell</title><description>&lt;p&gt;Here’s a Powershell script to generate the enumeration elements of an XML Schema simpleType restriction.&amp;#160; The first command loads the .NET Assembly you’ll need, sysglobl.dll.&lt;/p&gt;  &lt;code&gt;PS&amp;gt;  [System.Reflection.Assembly]::Load("sysglobl, Version=2.0.0.0, Culture=neutral, PublicKeyToken= b03f5f7f11d50a3a, processorArchitecture=MSIL")&lt;/code&gt; &lt;br /&gt; &lt;code&gt;PS&amp;gt; [System.Globalization.CultureInfo]::GetCultures([System.Globalization.CultureTypes]::FrameworkCultures)    &lt;br /&gt;| ? {$_.Name.Trim().Length -eq 5} | % { &amp;quot;&amp;lt;xs:enumeration value=`&amp;quot;$_`&amp;quot;/&amp;gt;&amp;quot;} | Out-File cultures.txt&lt;/code&gt;  &lt;p&gt;See my earlier post on locale identifiers for more background. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-1603908937942063713?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/11/create-xml-schema-enumeration-of.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-6556379108377014761</guid><pubDate>Sat, 31 Oct 2009 00:17:00 +0000</pubDate><atom:updated>2009-10-30T20:17:52.770-04:00</atom:updated><title>Whoa!!! HP Software Sucks!</title><description>&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_FQ1igFTZD04/SuuCLkS3DJI/AAAAAAAAAFU/6zeC_dwICao/s1600-h/image%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_FQ1igFTZD04/SuuCMApAFqI/AAAAAAAAAFY/lzGMxXy9sBw/image_thumb%5B3%5D.png?imgmax=800" width="491" height="233" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is the error that was reported after the HP installer forced me to restart my computer to continue installation…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-6556379108377014761?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/10/whoa-hp-software-sucks.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-4527204857540689070</guid><pubDate>Thu, 15 Oct 2009 14:12:00 +0000</pubDate><atom:updated>2009-10-15T10:12:07.253-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">TFS</category><title>TFS: Locked for Check-out</title><description>&lt;p&gt;Today a co-worker was attempting to edit a file, and TFS reported that it was “locked for check-out by [me] in workspace …”.&lt;/p&gt;  &lt;p&gt;I didn’t have it checked out.&amp;#160; I tried to use “tf lock /lock:none” on the file in question, but it would simply report:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;TF10152: The item … must remain locked because its file type prevents multiple check-outs.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We don’t allow multiple checkouts for this Team Project.&amp;#160; Unfortunately, this meant that not only didn’t I intend to lock the file, I couldn’t unlock it.&lt;/p&gt;  &lt;p&gt;My solution was to just check-in some dummy changes, comments full of expletives if you must know, since TFS will not perform a check-in unless there are actually changes to the files.&lt;/p&gt;  &lt;p&gt;So yeah, not TFS’ most shining moment.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-4527204857540689070?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/10/tfs-locked-for-check-out.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-4766525039184089136</guid><pubDate>Thu, 06 Aug 2009 04:01:00 +0000</pubDate><atom:updated>2009-08-06T00:01:49.300-04:00</atom:updated><title>Cloud Morphology</title><description>&lt;p&gt;Spent some time this evening tracking down the various component technologies of the myriad cloud offerings out there.&amp;#160; Here’s the result.&amp;#160; This will be updated over time.&lt;/p&gt; &lt;!-- Google Spreadsheets Element Code --&gt; &lt;iframe frameborder="0" marginwidth="0" marginheight="0" border="0" style="border:0;margin:0;width:720px;height:360px;" src="http://spreadsheets.google.com/pub?output=html&amp;amp;widget=true&amp;amp;single=true&amp;amp;element=true&amp;amp;gid=0&amp;amp;key=tLRUKXB-k-n0ON92stPlMIA" scrolling="no" allowtransparency="true"&gt;&lt;/iframe&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-4766525039184089136?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/08/cloud-morphology.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-9172548469184328298</guid><pubDate>Tue, 04 Aug 2009 21:45:00 +0000</pubDate><atom:updated>2009-08-04T17:50:13.133-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">architecture</category><title>NASA’s Cloud Platform: NEBULA, and Amorphous Morphology</title><description>&lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://nebula.nasa.gov/services" target="_blank"&gt;NEBULA&lt;/a&gt; is a Cloud Computing environment developed at NASA Ames Research Center, integrating a set of open-source components into a seamless, self-service platform. It provides high-capacity computing, storage and network connectivity, and uses a virtualized, scalable approach to achieve cost and energy efficiencies.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;They always write it in all caps, though it doesn’t appear to be an acronym. My guess is that it’s easier to search for “NEBULA” and find what you want at NASA. And, what better name for a cloud computing platform?&lt;/p&gt;  &lt;p&gt;To be frank, I didn’t recognize any of the technologies other than RabbitMQ and Apache. So I set out to find out what each piece does, and it’s these times that really make me envious of the LAMP folks. There is so much going on in the OSS world!&lt;/p&gt;  &lt;p&gt;In fact, it’s that sheer volume of innovation that makes it such a nightmare. Here’s where having NASA or Amazon or Elastra or EngineYard or Rackspace or Google AppEngine discuss their respective cloud infrastructures is so beneficial. If you look at their technology choices as a Venn diagram, you might find an optimal set of technologies in the overlap. Beyond that, you can begin to form a generalized blueprint of a cloud platform, identifying the core components.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_FQ1igFTZD04/Snir7-NT8pI/AAAAAAAAAE0/KYVeGPFTGlg/s1600-h/image%5B16%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="cloud provider Venn diagram" border="0" alt="cloud provider Venn diagram" src="http://lh6.ggpht.com/_FQ1igFTZD04/Snir8nV_TfI/AAAAAAAAAE4/5_qQ1KY0RHg/image_thumb%5B12%5D.png?imgmax=800" width="244" height="145" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In this way the cloud begins to take shape. Were we to sit all the big industry players down and say, define the cloud al a the OSI model, no one would have gotten around to building one. If we find the clouds in the wild, we can dissect them and find out what makes them tick. We can reverse engineer our blueprint.&lt;/p&gt;  &lt;p&gt;There’s a few major players missing here, of course, most notably Salesforce.com (SFDC) and Microsoft’s Azure platform.&amp;#160; SFDC doesn’t have an infrastructure that you can replicate, per se, because it is inseparable from their proprietary technologies.&amp;#160; In fact, Stu Charlton and others have noted that this is their biggest failing.&amp;#160; Similarly, Microsoft’s Azure is also a monolithic platform play, with the major difference that the platform can be deployed on premises, a so-called private cloud.&lt;/p&gt;  &lt;p&gt;Still though, we can include SFDC and Azure in our analysis.&amp;#160; We can develop our morphology of the cloud platforms that have published their constituent technologies.&amp;#160; With the language of this morphology in hand, we can classify the facilities of other cloud platforms.&amp;#160; Perhaps a taxonomy will evolve that allows us to identify Platform-as-a-Service, Infrastructure-as-a-Service, Software-as-a-Service, hybrids, and perhaps some novel species.&lt;/p&gt;  &lt;p&gt;Despite the amorphous character implied by the term cloud computing, these platforms have well-defined structure.&amp;#160; Moreover, unlike the traditional use of clouds in architecture diagrams, the details of this structure are important.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-9172548469184328298?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/08/nasas-cloud-platform-nebula-and.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-7380910121744605614</guid><pubDate>Mon, 03 Aug 2009 03:33:00 +0000</pubDate><atom:updated>2009-08-02T23:33:24.509-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">powershell</category><title>Powershell: Get Size of Child Directories</title><description>&lt;p&gt;gci -recurse -force |   &lt;br /&gt; ? { $_.GetType() -like 'System.IO.DirectoryInfo'} |    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select-object Name,@{Name=&amp;quot;size&amp;quot;; Expression = {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ($_.GetFiles()&amp;#160; |    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Measure-Object -Property Length -Sum |    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Measure-Object -Property Sum -Sum).Sum}} | sort-object -Property size&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-7380910121744605614?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/08/powershell-get-size-of-child.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-6465441172974950307</guid><pubDate>Wed, 08 Jul 2009 18:09:00 +0000</pubDate><atom:updated>2009-07-08T14:10:55.667-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">REST</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">architecture</category><title>Three Common Fallacies Concerning REST</title><description>&lt;blockquote&gt;   &lt;p&gt;Better to light a candle than to curse the darkness. -Chinese Proverb&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I purposely did not title this post “&lt;u&gt;&lt;a href="http://blogs.sun.com/jag/resource/Fallacies.html" target="_blank"&gt;The 3 Fallacies of RESTful Computing&lt;/a&gt;&lt;/u&gt;” as I am certainly not an expert in either REST or fallacy. :)&amp;#160; I am, however, quite well-versed in auto-didacticism, and over the past week I’ve been boning up on REST.&amp;#160; Along the way I’ve had one of my early notions of REST disabused (it is neither an architecture nor a protocol) and noticed a few other common misconceptions in the blogosphere and tweet stream.&amp;#160; If you are new to REST, or even if you aren’t, you might very well find a few edifying points in this post; I hope to light a candle or two out there. &lt;/p&gt;  &lt;p&gt;Without further ado, here are three common fallacies concerning REST.&amp;#160; &lt;/p&gt;  &lt;h3&gt;&lt;a name="fallacy1"&gt;Fallacy #1 REST is CRUD&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;Perhaps the most common fallacy of RESTful computing is that &lt;a href="http://twitter.com/dnene/status/2052779808" target="_blank"&gt;REST is simply CRUD&lt;/a&gt; (Create, Read, Update, and Delete) over HTTP.&amp;#160; &lt;a href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" target="_blank"&gt;Microsoft’s ADO.NET Data Services&lt;/a&gt; endeavors to provide developers a “data service being surfaced to the web as a REST-style resource collection[…]”; this would seem to further the notion that REST is another way of doing CRUD.&lt;/p&gt;  &lt;p&gt;However, &lt;a href="http://www.stucharlton.com/blog/archives/000551.html" target="_blank"&gt;REST is not CRUD&lt;/a&gt; as Stu Charlton states in a blog post about REST design guidelines; &lt;a href="http://www.rgoarchitects.com/nblog/2009/06/23/CRUDIsBadForREST.aspx" target="_blank"&gt;Arnon Rotem-Gal-Oz says CRUD is bad for REST&lt;/a&gt;, too.&amp;#160; If we are going to attempt to abridge RESTful architecture with an innocuous statement of the form “REST is X over HTTP” let us say that &lt;strong&gt;REST is using URLs to facilitate application state changes over HTTP&lt;/strong&gt;.&lt;/p&gt;  &lt;h3&gt;&lt;a name="fallacy2"&gt;Fallacy #2 POST is not RESTful&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;First, it is very important to note that REST is not tied to a specific protocol.&amp;#160; As an architectural style, it is protocol agnostic; though to be sure HTTP is a natural fit for many reasons.&amp;#160; As Fielding said in &lt;a href="http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post" target="_blank"&gt;It is okay to use POST&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Search my dissertation and you won’t find any mention of CRUD or POST. The only mention of PUT is in regard to HTTP’s lack of write-back caching.&amp;#160; The main reason for my lack of specificity is because the methods defined by HTTP are part of the Web’s architecture definition, not the REST architectural style.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Since the nominal use of POST is orthogonal to RESTfulness, by definition, it cannot be the case that POST is antithetical to REST.&amp;#160; Nevertheless, it is important to understand the reasoning that generally goes into this fallacy, because it speaks directly to a core principle of REST.&amp;#160; Most architectures expose an API that allows consumers to affect the state of the application only indirectly.&amp;#160; To understand the implications of your actions as a consumer, you then have—at best—to be very familiar with the application architecture and be aware that you are making a lot of assumptions.&amp;#160; The state mechanics are hidden from you.&amp;#160; You cannot explicitly move the application from one state to another, nor can you directly observe the transition(s) that have taken place.&amp;#160; &lt;/p&gt;  &lt;p&gt;A primary goal of Representational State Transfer is to make the application’s state machine unambiguous by exposing representations of application resources that have embedded within them &lt;a href="http://www.w3.org/Addressing/" target="_blank"&gt;URI&lt;/a&gt;s pertinent to the resource.&amp;#160; In this way a consumer of a RESTful service can discover the current state of the resource, the mechanisms to affect change in the resource, and other resources related to the current resource in the application’s state.&amp;#160; This is what is known as Hypertext as the Engine of Application State (HatEoAS).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.stucharlton.com/blog/archives/000141.html" target="_blank"&gt;HatEoAS&lt;/a&gt; implies a model where all of your important resources are represented by unique URIs and all important state changes are done by interacting with representations sent to or retrieved from those URIs. Most people first approaching REST view it in terms of opposing other architectural “styles” such as SOA or get mired in implementation immediately and begin contrasting their understanding of REST over HTTP against WS-*. Another common problem is reducing the ethos of REST to “RPC is bad” and “we don’t need all that complexity, we have HTTP” (see &lt;a href="#fallacy3"&gt;REST is better than WS-*&lt;/a&gt;).&amp;#160; These views are commonplace because REST is being promulgated as a better solution for many types of applications on the Web.&lt;/p&gt;  &lt;p&gt;The specifics of how REST works over HTTP are beyond the scope of this article, and the subject of a &lt;a href="http://www.tbray.org/ongoing/When/200x/2009/07/02/Slow-REST" target="_blank"&gt;lot of debate&lt;/a&gt;, but, since a &lt;a href="http://www.tbray.org/ongoing/When/200x/2009/03/20/Rest-Casuistry" target="_blank"&gt;lot of uses of POST seem very much like RPC-style invocations&lt;/a&gt;, people have a knee-jerk reaction that POST is not RESTful.&amp;#160; By now you know this is not the case, but let’s hear from the experts.&lt;/p&gt;  &lt;p&gt;From Fielding:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;POST only becomes an issue when it is used in a situation for which some other method is ideally suited: e.g., retrieval of information that should be a representation of some resource (GET), complete replacement of a representation (PUT) […]&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Stu Charlton’s &lt;a href="http://www.stucharlton.com/blog/archives/000551.html" target="_blank"&gt;design guidelines&lt;/a&gt; say nearly the same thing:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The problem with POST is when we abuse it by having it perform things that are more expressive in one of the other methods. GET being the obvious one that needs no hypermedia description. For the other methods, a good design guideline is that you MUST not break the general contract of the HTTP method you choose -- but you SHOULD describe the specific intent of that method in hypermedia.&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;&lt;a name="fallacy3"&gt;Fallacy #3 REST is better than WS-*&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;In fact, Fielding’s thesis does address many of the problems and advantages of various &lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/net_arch_styles.htm" target="_blank"&gt;network-based architectural styles&lt;/a&gt;, but no where does he claim REST is the one ring to rule them all.&amp;#160; In his aforementioned blog post Fielding says (emphasis my own),&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;[…]there are plenty of information systems that can be designed using the &lt;strong&gt;REST architectural style&lt;/strong&gt; and gain the &lt;strong&gt;associated benefits&lt;/strong&gt;. Managing cloud instances is certainly one of those applications for which REST is a good fit[…]&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;From his thesis, here is the definition of the &lt;strong&gt;REST architectural style&lt;/strong&gt;.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;REST consists of a set of architectural constraints chosen for the properties they induce on candidate architectures. […] [It] is an abstraction of the architectural elements within a distributed hypermedia system. […] It encompasses the fundamental constraints upon components, connectors, and data that define the basis of the Web architecture, and thus the essence of its behavior as a network-based application.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So, the &lt;strong&gt;associated benefits&lt;/strong&gt; are induced by constraints that collectively are referred to as the REST architectural style.&amp;#160; The benefits are myriad, and many of the constraints are are recognizable in how the web works. Section #5 of the thesis is concise and readable, and I encourage the reader to internalize it.&amp;#160; &lt;/p&gt;  &lt;p&gt;The salient point here is that REST is not a protocol; it’s not even an architecture.&amp;#160; REST is an architectural &lt;strong&gt;&lt;em&gt;style!&lt;/em&gt;&lt;/strong&gt; By understanding its constraints and benefits, we can make informed decisions about its applicability to our problem domain and appropriation of technologies.&amp;#160; Comparing REST to the WS-* suite of protocols is comparing apples to oranges, though there are those who &lt;a href="http://blog.therestfulway.com/2009/06/rest-and-http-services-as-business.html" target="_blank"&gt;strongly argue the benefits of REST and HTTP over SOAP&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/6928325842095718321-6465441172974950307?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/07/three-common-fallacies-concerning-rest.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-1882311768173650630</guid><pubDate>Sat, 27 Jun 2009 15:28:00 +0000</pubDate><atom:updated>2009-06-27T11:28:29.452-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">architecture</category><title>What, Not How &amp; Why, Not When</title><description>&lt;p&gt;It occurred to me this morning that many software development principles seem to emerge from the rigorous application of the following principle:&lt;/p&gt; &lt;blockquote&gt;Your architecture and code should make What &amp;amp; Why explicit without specifying How &amp;amp; When.&lt;/blockquote&gt; &lt;dl&gt; &lt;dt&gt;What, Not How&lt;dt&gt; &lt;dl&gt;&lt;p&gt;It is well known that we should prefer declarative over imperative code. By observing the Law of Demeter, we are in fact forced to create declarative, What, semantics in our interfaces since we can't get at the How, the imperative constructs. The Single-Responsibility Principle tends to force us to factor out the How into other classes, leaving us to consume other classes with What semantics. Further, the Interface Segregation Principle requires us to explicity segregate the interfaces our clients consume based on What they are trying to accomplish; if our focus was How, such segregation would be less of a concern.&lt;/p&gt; &lt;p&gt;Event-Driven Architectures (EDA) are another example of What, Not How.  Whereas the SOLID principles operate at the class design level of abstraction, EDA is concerned with system-level architecture. In an Event-Drive Architecture, we explicitly model happenings in the domain.  Rather than coupling the site of the happening to a specific party designating for dealing with that happening, we create an Event and use reliabile messaging and subscription schemes to allow one or many services to handle it. In other words, instead of specifying How to deal with a happening at the site that generates it, we explicitly model What happened and let other parties worry about How to deal with it.&lt;/p&gt;&lt;/dl&gt; &lt;dt&gt;Why, Not When&lt;/dt&gt; &lt;dl&gt;&lt;p&gt;This maxim is both more subtle and more prosaic than What, Not How.  It is probably pretty obvious that when given a requirement stated, "if the purchase order acknowledgement is not received within two hours, notify someone in fulfillment," we should model an Event "POAckIsLate" as opposed to "TwoHoursHaveElapsedWithoutReceivingPOAck". We will have different SLAs with different vendors; those SLAs will change, etc. So we can say, when modeling Events in our domain, we should prefer specifying Why, Not When.&lt;/p&gt; &lt;p&gt;Perhaps more subtle is the implications for communication semantics between modules.  If we model our communications with Why in mind, we don't get mired in the concurrency problems of specifying When.  Consider a workflow.  If we specify When to go to a particular step, the underlying reason may have changed unless we take some sort of explicit lock on shared state.  If we instead specify Why a particular state transition takes place, we can avoid inconsistent states through continuous evaluation. If we make Why explicit and consequently create semantics to evaluate Why independently of "current" state, it becomes possible to evaluate the state consistently without any shared state, i.e. without a notion of When.&lt;/p&gt;&lt;/dl&gt;  &lt;p&gt;As an example, if we had the requirement, "when a PO is received with a quantity for part X above a twenty units, move the order to the top of the work queue," we should model a "BulkProductionRequest" Event and an "ExpediteProduction"; we should not implement a "Reprioritize Production Queue For Order of PartX Over Twenty Units".  Begin with the end in mind and ask What do we want to do (expedite production) not How (re-prioritize production queue).  Ask Why are we expediting this order? Because it is Bulk.  What is Bulk?  Bulk is a quality determined by a CapacityPlanning service and implies that the quantity exceeds some production capacity threshold.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-1882311768173650630?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/06/what-not-how-why-not-when.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-5717631758636986403</guid><pubDate>Fri, 26 Jun 2009 18:33:00 +0000</pubDate><atom:updated>2009-06-26T14:33:16.042-04:00</atom:updated><title>Pareto, Zipf, Heap: The 80-20 Rule, Language, and Diminishing Returns</title><description>&lt;p&gt;Please consider this a sort of layman’s disambiguation page.&lt;/p&gt;  &lt;p&gt;The classic “80-20 rule” refers to a Pareto distribution.&amp;#160; The thin distribution of the 20% is the subject of Chris Anderson’s “The Long Tail”.&amp;#160; Originally, the Pareto distribution referred to the fact that 20% of the people control 80% of the wealth, but it has turned up in many other contexts.&lt;/p&gt;  &lt;p&gt;A Zipf’s Law is about rankings and frequency.&amp;#160; The second item’s frequency will be half of the first; the third’s frequency will be half the second, and so on.&amp;#160; The “half” may be some other factor, but it remains constant in the distribution; the rank is inversely proportional to the frequency. The item in Zipf’s Law is a word and its frequency is its appearance in a corpus of English text.&amp;#160; However, Zipf’s Law holds for texts generated from a fixed alphabet by picking letters randomly with a uniform distribution.&lt;/p&gt;  &lt;p&gt;Heaps’ Law is about diminishing returns.&amp;#160; It has an exact formula, but generally it says that the more you look into a text, the fewer new discoveries of words you’ll find.&amp;#160; So, as you read through the text it takes longer and longer to find new words in the text.&amp;#160; Heaps’ Law applied to the general case where the “words” are just classifiers of some collection of things.&amp;#160; So, it could be applied to the nationality of a collection of people; you’d have to gather more and more people from a random sampling to get a representative from all countries.&lt;/p&gt;  &lt;p&gt;The implications of these laws in various contexts are the subject of much interesting study and postulation.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-5717631758636986403?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/06/pareto-zipf-heap-80-20-rule-language.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-8552488741575482016</guid><pubDate>Wed, 17 Jun 2009 01:29:00 +0000</pubDate><atom:updated>2009-06-16T21:58:05.872-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">powershell</category><category domain="http://www.blogger.com/atom/ns#">C#</category><category domain="http://www.blogger.com/atom/ns#">wcf</category><title>Value Objects and Value Domains</title><description>&lt;p&gt;I’ve written relatively extensively on the topic of &lt;a href="http://iformattable.blogspot.com/2007/09/replacing-enum-constructs-with-classes.html" target="_blank"&gt;replacing enum constructs with classes&lt;/a&gt;, so I won’t rehash the topic. Instead, I’d like to introduce you to some code I’ve written that enables you to create finite domains of Value Objects in C#.&amp;#160; Please see my two &lt;a href="http://iformattable.blogspot.com/2007/09/replacing-enum-constructs-with-classes.html" target="_blank"&gt;previous&lt;/a&gt; &lt;a href="http://iformattable.blogspot.com/2007/07/replace-enum-constructs-with-classes.html" target="_blank"&gt;posts&lt;/a&gt; on the subject to learn more about the benefits of this approach.&amp;#160; To see how the Value Object semantics and making a finite domain a first class concept in the pattern improves the approach, read on.&lt;/p&gt;  &lt;p&gt;First, we need some definitions.&amp;#160; We are taking the concept of a Value Object from Eric Evans’ book “Domain Driven Design” p.99:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;When you care only about the attributes of an element of the model, classify it as a Value Object. Make it express the meaning of the attributes it conveys and give it related functionality. Treat the Value Object as immutable.&amp;#160; Don’t give it any identity […] The attributes that make up a Value Object should form a &lt;a href="http://fit.c2.com/wiki.cgi?WholeValue" target="_blank"&gt;conceptual whole&lt;/a&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;An example here is useful.&amp;#160; Consider modeling the domain of a book publisher.&amp;#160; At some point you need to capture all the different formats of books: A4, B, Pinched Crown, etc.&amp;#160; The attributes of width, height, unit of measure, and name would go into your model.&amp;#160; But, any instance of your A4 Value Object should be completely interchangeable from any other A4.&amp;#160; And, it goes without saying that you can’t change the width or height or any other attribute of A4.&lt;/p&gt;  &lt;p&gt;All of the different formats of books belong to a &lt;em&gt;Value Domain&lt;/em&gt;. According to &lt;a href="http://wordnetweb.princeton.edu/perl/webwn?s=domain" target="_blank"&gt;WordNet&lt;/a&gt;, a domain (we are using the mathematical notion) is:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;the set of values of the independent variable for which a function is defined&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The functional complement of a domain is the range of the function; i.e. domain is what you can put in, the range is what you can expect to get out.&amp;#160; I like calling this concept in my approach a domain instead of a set, because it neatly captures a key benefit.&amp;#160; When we are writing code.&amp;#160; We want to declare our parameters as being a proper member of domain of values, instead of just primitive types or strings.&lt;/p&gt;  &lt;p&gt;Now we’re ready to dive into the implementation.&amp;#160; Let’s begin with the end in mind.&amp;#160; I want to write a function, say, that let’s me search for a document with a particular format about an arbitrary topic.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;SearchDocs(DocFormat docFormat, &lt;span style="color: blue"&gt;string &lt;/span&gt;topic)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Ok, so we could create a base class or an interface called DocFormat and create Word doc, PDF, etc. that inherit from or implement DocFormat.&amp;#160; Easy.&amp;#160; But, SearchDocs has to be able to handle all current and future implementations of DocFormat; it must not violate the &lt;a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle" target="_blank"&gt;Liskov substitution principle&lt;/a&gt;. What if the repository or search algorithm depends on the what the doc format actually is?&amp;#160; Also, we’d have a subclass of DocFormat to write for every document type, and we’d have to do a &lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx" target="_blank"&gt;lot of work&lt;/a&gt; to remove object identity, since your instance of PDF is not the same as my instance of PDF.&amp;#160; And, don’t forget to make the whole thing &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx" target="_blank"&gt;immutable&lt;/a&gt;. [Note: I know this is a contrived example with well-established OOP solutions that don’t require LSP violation.&amp;#160; Work with me here. :)]&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Clearly we have a lot of work to do to make our Value Objects a reality.&amp;#160; It’s not impossible, though, and a quick &lt;strike&gt;Bing&lt;/strike&gt; Google turns up a couple of investigations and approaches.&amp;#160; &lt;a href="http://grabbagoft.blogspot.com/2007/06/generic-value-object-equality.html" target="_blank"&gt;Jimmy Bogard’s approach&lt;/a&gt; gave me a clue that I needed to get it working.&amp;#160; What I wanted was a base type, ValueObject, that I could inherit from and get the Value Object semantics described in Evans.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Jimmy’s approach used a self-referencing &lt;a href="http://msdn.microsoft.com/en-us/library/sz6zd40f(VS.80).aspx" target="_blank"&gt;open constructed type&lt;/a&gt; to allow the ValueObject base class to do all the work of providing Value Object semantics.&amp;#160; This base class uses dynamic reflection to determine what properties to use in the derived class to do equality comparisons (an approach &lt;a href="http://elegantcode.com/2009/06/07/generic-value-object/" target="_blank"&gt;nominally improved upon here&lt;/a&gt;). He saw his approach as having a single fundamental flaw; it only worked for the first level of inheritance, i.e. the first descendent from ValueObject.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;For my purposes—creating a bounded, finite domain of Value Objects to replace enum-type classes--this is not a flaw.&amp;#160; Substantively, all that remains to do is introduce the concept of the the Value Domain into Jimmy’s approach and put the Value Objects in it.&amp;#160; Because I wanted to use these Value Domains throughout the enterprise, I baked WCF support into my approach.&amp;#160; Further, because the Value Domain is defined &lt;em&gt;a priori&lt;/em&gt;, I didn’t have to play with object identity; I could simply look the value up in the domain.&amp;#160; (It took a little out-of-the-box thinking to get that to work transparently.)&amp;#160; Finally, I wanted it to be trivially easy to create these Value Domains, so I created a snippet for use in Visual Studio.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here’s an example of Value Domain and Value Objects implementation:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;DataContract&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: blue"&gt;public sealed class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DocFormats &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ValueObject&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DocFormats&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;DocFormat&lt;/span&gt;, &lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DocFormats&lt;/span&gt;&amp;gt;.&lt;span style="color: #2b91af"&gt;Values&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DocFormats&lt;/span&gt;&amp;gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;private &lt;/span&gt;DocFormats()&lt;br /&gt;    {&lt;br /&gt;        Word = Add(&lt;span style="color: #a31515"&gt;&amp;quot;Word&amp;quot;&lt;/span&gt;);&lt;br /&gt;        PDF = Add(&lt;span style="color: #a31515"&gt;&amp;quot;PDF&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;]&lt;br /&gt;    &lt;span style="color: blue"&gt;public readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;BindingType &lt;/span&gt;Word, PDF;&lt;br /&gt;&lt;br /&gt;    [&lt;span style="color: #2b91af"&gt;Serializable&lt;/span&gt;]&lt;br /&gt;    &lt;span style="color: blue"&gt;public sealed class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DocFormat &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ValueObject&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DocFormat&lt;/span&gt;, &lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DocFormats&lt;/span&gt;&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;private &lt;/span&gt;DocFormat(&lt;span style="color: blue"&gt;string &lt;/span&gt;v) : &lt;span style="color: blue"&gt;base&lt;/span&gt;(v) { }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;DocFormats is the Value Domain.&amp;#160; DocFormat is the type of the Value Object.&amp;#160; String is the underlying type of the values, but the pattern supports anything that implements IEquatable and IComparable.&amp;#160; Methods can accept DocFormats.DocFormat as a parameter and only Word and PDF will be valid.&amp;#160; Code can specify those values through a Singleton accessor: DocFormats.Instance.PDF.&amp;#160; You’ll notice that the only constructor is private; the Singleton implementation is in the base value domain base class (ValueObject&amp;lt;…&amp;gt;.Values&amp;lt;…&amp;gt;).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// our new method interface&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;SearchDocs(DocFormats.DocFormat docFormat, &lt;span style="color: blue"&gt;string &lt;/span&gt;topic)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: green"&gt;// referencing an individual value&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(DocFormats.Instance.Word == docFormat)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: green"&gt;//...&lt;br /&gt;    &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Above you’ll note that the Value Object type definition (subclass of ValueObject&amp;lt;…&amp;gt;) is nested inside of the Value Domain.&amp;#160; Doing that groups the two together syntactically in a very natural way (FooTypes.FooType); the entire domain of values is contained in one place.&amp;#160; That locality makes the snippet to produce them cohesive too.&amp;#160; [Note: I’ve included the snippet XML at the end of this post.] &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Interestingly, the underlying implementation necessarily inverts this nesting; the Value Domain base class is nested in the Value Object base class.&amp;#160; That allows the Value Domain Singleton to create instances of Value Objects.&amp;#160; I only had to resort to reflection in order to allow the Value Domain base class to provide the Singleton implementation.&amp;#160; Inversion of Control containers like Unity and Castle Windsor do this kind of reflection all the time, and it’s cheap since .NET 2.0.&amp;#160; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Without further ado, here’s the base classes implementation.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Collections.Generic;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Reflection;&lt;br /&gt;&lt;br /&gt;[&lt;span style="color: #2b91af"&gt;Serializable&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: blue"&gt;public abstract class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ValueObject&lt;/span&gt;&amp;lt;T, TValue, TValues&amp;gt; : &lt;span style="color: #2b91af"&gt;IEquatable&lt;/span&gt;&amp;lt;T&amp;gt;, &lt;span style="color: #2b91af"&gt;IComparable&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IComparable&lt;/span&gt;&amp;lt;T&amp;gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;where &lt;/span&gt;T : ValueObject&amp;lt;T, TValue, TValues&amp;gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;where &lt;/span&gt;TValue : &lt;span style="color: #2b91af"&gt;IEquatable&lt;/span&gt;&amp;lt;TValue&amp;gt;, &lt;span style="color: #2b91af"&gt;IComparable&lt;/span&gt;&amp;lt;TValue&amp;gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;where &lt;/span&gt;TValues : ValueObject&amp;lt;T, TValue, TValues&amp;gt;.Values&amp;lt;TValues&amp;gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// &lt;/span&gt;&lt;span style="color: green"&gt;This is the encapsulated value.&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;public readonly &lt;/span&gt;TValue Value;&lt;br /&gt;    &lt;span style="color: blue"&gt;protected &lt;/span&gt;ValueObject(TValue value)&lt;br /&gt;    {&lt;br /&gt;        Value = value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;#region &lt;/span&gt;equality&lt;br /&gt;    &lt;span style="color: blue"&gt;public override bool &lt;/span&gt;Equals(&lt;span style="color: blue"&gt;object &lt;/span&gt;other)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;return &lt;/span&gt;other != &lt;span style="color: blue"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; other &lt;span style="color: blue"&gt;is &lt;/span&gt;T &amp;amp;&amp;amp; Equals(other &lt;span style="color: blue"&gt;as &lt;/span&gt;T);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;public override int &lt;/span&gt;GetHashCode()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: green"&gt;// TODO provide an efficient implementation&lt;br /&gt;        // http://www.dotnetjunkies.com/weblog/tim.weaver/archive/2005/04/04/62285.aspx&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;Value.GetHashCode();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;Equals(T other)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;return &lt;/span&gt;other != &lt;span style="color: blue"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; Value.Equals(other.Value);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;public static bool operator &lt;/span&gt;==(ValueObject&amp;lt;T, TValue, TValues&amp;gt; x, ValueObject&amp;lt;T, TValue, TValues&amp;gt; y)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: green"&gt;// pointing to same heap location&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(ReferenceEquals(x, y)) &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: green"&gt;// both references are null&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;null &lt;/span&gt;== (&lt;span style="color: blue"&gt;object&lt;/span&gt;)(x ?? y)) &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: green"&gt;// auto-boxed LHS is not null&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;((&lt;span style="color: blue"&gt;object&lt;/span&gt;)x != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;            &lt;span style="color: blue"&gt;return &lt;/span&gt;x.Equals(y);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;public static bool operator &lt;/span&gt;!=(ValueObject&amp;lt;T, TValue, TValues&amp;gt; x, ValueObject&amp;lt;T, TValue, TValues&amp;gt; y)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;return &lt;/span&gt;!(x == y);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: blue"&gt;#endregion&lt;br /&gt;&lt;br /&gt;    public static implicit operator &lt;/span&gt;TValue(ValueObject&amp;lt;T, TValue, TValues&amp;gt; obj)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;return &lt;/span&gt;obj.Value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;public static implicit operator &lt;/span&gt;ValueObject&amp;lt;T, TValue, TValues&amp;gt;(TValue val)&lt;br /&gt;    {&lt;br /&gt;        T valueObject;&lt;br /&gt;        &lt;span style="color: blue"&gt;if &lt;/span&gt;(Values&amp;lt;TValues&amp;gt;.Instance.TryGetValue(val, &lt;span style="color: blue"&gt;out &lt;/span&gt;valueObject))&lt;br /&gt;            &lt;span style="color: blue"&gt;return &lt;/span&gt;valueObject;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InvalidCastException&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;{0} cannot be converted&amp;quot;&lt;/span&gt;, val));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;public override string &lt;/span&gt;ToString()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;return &lt;/span&gt;Value.ToString();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;#region &lt;/span&gt;comparison&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;public int &lt;/span&gt;CompareTo(T other)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;return &lt;/span&gt;Value.CompareTo(other);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;public int &lt;/span&gt;CompareTo(&lt;span style="color: blue"&gt;object &lt;/span&gt;obj)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;null &lt;/span&gt;== obj)&lt;br /&gt;            &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;if &lt;/span&gt;(obj &lt;span style="color: blue"&gt;is &lt;/span&gt;T)&lt;br /&gt;            &lt;span style="color: blue"&gt;return &lt;/span&gt;Value.CompareTo((obj &lt;span style="color: blue"&gt;as &lt;/span&gt;T).Value);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;Must be of type {0}&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T)));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue"&gt;#endregion&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;[&lt;span style="color: #2b91af"&gt;Serializable&lt;/span&gt;]&lt;br /&gt;    &lt;span style="color: blue"&gt;public abstract class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Values&lt;/span&gt;&amp;lt;TDomain&amp;gt; &lt;span style="color: blue"&gt;where &lt;/span&gt;TDomain : Values&amp;lt;TDomain&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        [&lt;span style="color: #2b91af"&gt;NonSerialized&lt;/span&gt;]&lt;br /&gt;        &lt;span style="color: blue"&gt;protected readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;TValue, T&amp;gt; _values = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;TValue, T&amp;gt;();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;private void &lt;/span&gt;Add(T valueObject)&lt;br /&gt;        {&lt;br /&gt;            _values.Add(valueObject.Value, valueObject);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected &lt;/span&gt;T Add(TValue val)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;valueObject = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T).InvokeMember(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T).Name,&lt;br /&gt;                           &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.CreateInstance | &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.Instance |&lt;br /&gt;                           &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.NonPublic, &lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;new object&lt;/span&gt;[] { val }) &lt;span style="color: blue"&gt;as &lt;/span&gt;T;&lt;br /&gt;            Add(valueObject);&lt;br /&gt;            &lt;span style="color: blue"&gt;return &lt;/span&gt;valueObject;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;public bool &lt;/span&gt;TryGetValue(TValue value, &lt;span style="color: blue"&gt;out &lt;/span&gt;T valueObject)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue"&gt;return &lt;/span&gt;_values.TryGetValue(value, &lt;span style="color: blue"&gt;out &lt;/span&gt;valueObject);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;public bool &lt;/span&gt;Contains(T valueObject)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue"&gt;return &lt;/span&gt;_values.ContainsValue(valueObject);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;static volatile &lt;/span&gt;TDomain _instance;&lt;br /&gt;        &lt;span style="color: blue"&gt;static readonly object &lt;/span&gt;Lock = &lt;span style="color: blue"&gt;new object&lt;/span&gt;();&lt;br /&gt;        &lt;span style="color: blue"&gt;public static &lt;/span&gt;TDomain Instance&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue"&gt;get&lt;br /&gt;            &lt;/span&gt;{&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(_instance == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;                    &lt;span style="color: blue"&gt;lock &lt;/span&gt;(Lock)&lt;br /&gt;                    {&lt;br /&gt;                        &lt;span style="color: blue"&gt;if &lt;/span&gt;(_instance == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;                            _instance = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(TDomain)&lt;br /&gt;                                .InvokeMember(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(TDomain).Name,&lt;br /&gt;                                                  &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.CreateInstance |&lt;br /&gt;                                                  &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.Instance |&lt;br /&gt;                                                  &lt;span style="color: #2b91af"&gt;BindingFlags&lt;/span&gt;.NonPublic, &lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;) &lt;span style="color: blue"&gt;as &lt;/span&gt;TDomain;&lt;br /&gt;                    }&lt;br /&gt;                &lt;span style="color: blue"&gt;return &lt;/span&gt;_instance;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I’d love to hear your feedback.&amp;#160; This is approach is not intended to support unbounded Value Domains, such as the canonical example of Address.&amp;#160; It is meant for the enums-as-classes problem, i.e. finite, bounded Value Domains.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;ValueObject.snippet&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml &lt;/span&gt;&lt;span style="color: red"&gt;version&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;?&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;CodeSnippets  &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;CodeSnippet &lt;/span&gt;&lt;span style="color: red"&gt;Format&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;1.0.0&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Header&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;ValueOjbect&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Shortcut&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;vo&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Shortcut&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Description&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Code snippet for ValueObject and domain&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Description&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Author&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Christopher Atkins&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Author&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;SnippetTypes&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;SnippetType&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Expansion&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;SnippetType&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;SnippetTypes&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Header&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Snippet&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Declarations&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Literal&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;domain&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Value domain name&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Default&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;MyValues&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Default&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;                &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Literal&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Literal&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;value&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;ValueObject Class name&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Default&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;MyValueObject&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Default&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Literal&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Literal&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;type&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Value Type&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;          &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Default&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;string&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Default&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Literal&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Declarations&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Code &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;csharp&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;![CDATA[    &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: gray"&gt;[DataContract]&lt;br /&gt;    public sealed class $domain$ : ValueObject&amp;lt;$domain$.$value$, $type$, $domain$&amp;gt;.Values&amp;lt;$domain$&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        private $domain$()&lt;br /&gt;        {&lt;br /&gt;            Value1 = Add(String.Empty);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        [DataMember]&lt;br /&gt;        public readonly $value$ Value1;&lt;br /&gt;&lt;br /&gt;        [Serializable]&lt;br /&gt;        public sealed class $value$ : ValueObject&amp;lt;$value$, $type$, $domain$&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            private $value$($type$ v) : base(v) { }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;]]&amp;gt;&lt;br /&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Code&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Snippet&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;CodeSnippet&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;CodeSnippets&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-8552488741575482016?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/06/value-objects-and-value-domains.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-7274348729478024879</guid><pubDate>Thu, 28 May 2009 20:57:00 +0000</pubDate><atom:updated>2009-05-28T16:57:21.998-04:00</atom:updated><title>Google Wave</title><description>&lt;p&gt;Upon the day mankind's children ask    &lt;br /&gt;Who it was made their world intelligible,     &lt;br /&gt;Those who set about the grand task     &lt;br /&gt;of creating the &lt;a href="http://wave.google.com/" target="_blank"&gt;Wave&lt;/a&gt; will be eligible. &lt;/p&gt;  &lt;p&gt;For never will they have occasion to think    &lt;br /&gt;how to create discourse, share knowledge,     &lt;br /&gt;Wonder about the universe and link     &lt;br /&gt;Without the this wonderful prodigy. &lt;/p&gt;  &lt;p&gt;Like hieroglyphs in the tombs of Kings,    &lt;br /&gt;eee-may-uhls voy-s'-may-uhls eye-ems and tweets     &lt;br /&gt;will serious study to the curious bring,     &lt;br /&gt;to be shared in Waves while ancestors sleep. &lt;/p&gt;  &lt;p&gt;How is it the first step of a journey    &lt;br /&gt;Can put the past so far behind thee?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-7274348729478024879?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/05/google-wave.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-7762982293106810697</guid><pubDate>Mon, 25 May 2009 17:34:00 +0000</pubDate><atom:updated>2009-05-25T15:51:52.912-04:00</atom:updated><title>Connascence: The Underlying Principle of OO Design?</title><description>&lt;p&gt;This is a great talk at a Ruby conference by Jim Weirich about his attempt to frame all object-oriented design (OOD) principles as special cases of an underlying principle called “connascence”.&amp;#160; Connascence is a term co-opted by Meilir Page-Jones in the ‘90s for use in OOD; below is the definition from his book with Larry Constantine entitled, “Fundamentals of Object-Oriented Design in UML” (page 214):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Connascence between two software elements A and B means either&lt;/p&gt;    &lt;ol&gt;     &lt;li&gt;that you can postulate some change to A that would require B to be changed (or at least carefully checked) in order to perserve overall correctness, or &lt;/li&gt;      &lt;li&gt;that you can postulate some change that would require both A and B to be changed together in order to preserve overall correctness. &lt;/li&gt;   &lt;/ol&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;embed src="http://mwrc2009.confreaks.com/player.swf" height="620" width="960" allowscriptaccess="always" allowfullscreen="true" flashvars="image=images%2F14-mar-2009-18-10-the-building-blocks-of-modularity-jim-weirich-preview.png&amp;file=http%3A%2F%2Fmwrc2009.confreaks.com%2Fvideos%2F14-mar-2009-18-10-the-building-blocks-of-modularity-jim-weirich-small.mp4&amp;state=PLAYING&amp;plugins=viral-1" /&gt;&lt;/embed&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-7762982293106810697?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/05/connascence-underlying-principle-of-oo.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-2413651036772682449</guid><pubDate>Thu, 21 May 2009 15:24:00 +0000</pubDate><atom:updated>2009-05-21T11:54:51.740-04:00</atom:updated><title>WolframAlpha: A New Kind of Site</title><description>&lt;p&gt;&lt;a href="http://www.techcrunch.com/2009/05/12/what-is-google-squared-it-is-how-google-will-crush-wolfram-alpha-exclusive-video/" target="_blank"&gt;TechCrunch called Google Squared the imminent Cain to WolframAlpha’s Abel&lt;/a&gt;. &lt;a href="http://www.25hoursaday.com/weblog/2009/05/16/WolframAlphaTheWikipediaKiller.aspx" target="_blank"&gt;Dare Obsanajo warns Wikipedia to beware the ides of March&lt;/a&gt;, casting WolframAlpha as Brutus.&amp;#160; But, I would cast WolframAlpha in quite a different role: Hamlet.&lt;/p&gt;  &lt;p&gt;If you’ve not used &lt;a href="http://www.wolframalpha.com/" target="_blank"&gt;WolframAlpha&lt;/a&gt;, head over there come back once you’ve exhausted its novelty.&amp;#160; Go ahead, I’ll wait.&lt;/p&gt;  &lt;p&gt;So, now you know why they call it a “computational knowledge engine” whose mission it is to “make the world’s knowledge computable”.&amp;#160; Ignoring, for the present, the interesting epistemological discussion viz. the validity of that mission, let’s instead talk about why you might use it.&lt;/p&gt;  &lt;p&gt;If you are looking for something, go to Google.&amp;#160; This is not a search engine.&lt;/p&gt;  &lt;p&gt;If you are looking to mine the web for hard data, be patient, Google Squared will be your guide (when it is baked).&lt;/p&gt;  &lt;p&gt;If you would like to learn about a particular topic, Wikipedia stands ready to help you begin.&lt;/p&gt;  &lt;p&gt;If you want to apply your existing domain knowledge to posing interesting questions about a wide variety of topics, if you can phrase such questions as nominal computations, then go to WolframAlpha, though your attempts might be frustrated, e.g. it fails to compute the following “annual energy consumption of the average American * projected worldwide population in 2020.”&lt;/p&gt;  &lt;p&gt;In other words for 98% of the world, WolframAlpha is simply a curiosity. For the other 2%, it’s only useful as a way to experiment with such questions, since the rigor required of formal academia is not satisfied by simply saying, “WolframAlpha said so.”&lt;/p&gt;  &lt;p&gt;To understand WolframAlpha’s raison d'être, you have to understand NKS: Stephen Wolfram’s “New Kind of Science”.&amp;#160; To understand NKS you can either go read the book or trust what I’m about to say.&amp;#160; At its core, the claim it makes to novelty is based on the notion that all phenomena can be viewed as computations, and thus real science can be done by exploring the “universe” of possible computations.&amp;#160; Of course the only apparatus sufficient for doing this “new” science is Wolfram’s own Mathematica program, a program originally created by Dr. Wolfram in a single summer.&amp;#160; Twenty or so years later after leaving academia to build the company that develops and sells Mathematica, Wolfram brought forth the the 1,200+ page tome that is NKS.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_FQ1igFTZD04/ShVyROlZ0KI/AAAAAAAAAEs/M3mulvQSmXo/s1600-h/101440%5B2%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="101440" border="0" alt="101440" src="http://lh6.ggpht.com/_FQ1igFTZD04/ShVyRIvUg8I/AAAAAAAAAEw/7KnhSnU1NOs/101440_thumb.jpg?imgmax=800" width="244" height="196" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Wolfram is no lightweight; we’re talking about one of those few people in the world with the intellectual capacity and training to do modern quantum mechanics at age 17—when it comes to mathematics he is the real McCoy.&amp;#160; But, very few seriously look at NKS as being fundamentally new, and no few academics treat Wolfram with vitriol and ire due to his claim of novelty.&amp;#160; We all—it is universally agreed—stand upon the shoulders of giants.&amp;#160; Further, many argue that NKS contributes nothing new to the existing corpus of mathematics or science.&amp;#160; Here are some notes for the dramaturg:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The NKS book was self-published by Wolfram-Media &lt;/li&gt;    &lt;li&gt;Wolfram opens the book with a statement of his childhood dream to “know everything” &lt;/li&gt;    &lt;li&gt;NKS is the culmination of twenty years of work outside of academia &lt;/li&gt;    &lt;li&gt;The precipitating event that put him on that path was his not being able to understand the pattern generated by a cellular automata (simple computer program) he’d written &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;My personal belief is that the cognitive dissonance created by having not contributed to science in any recognized, significant way over twenty years, in the face of soaring hubris born out of his prodigious intellect and early summiting of some of the highest peaks of academia, forces Dr. Wolfram to eschew—even denigrate—the trappings of mainstream academia and embrace his self-created role of the father of a new kind of science.&amp;#160; But, hey, I don’t know the guy; and it goes without saying that I’m criticizing Michael Jordan’s cross-over.&amp;#160; Maybe it will take twenty years for everyone else to get it; if it is new, it's nascent, and you have to walk before you can crawl.&lt;/p&gt;  &lt;p&gt;He may be an egoist, but he has excellent taste.&amp;#160; I think he’d make Edward Tufte proud.&lt;/p&gt;  &lt;p&gt;What WolframAlpha owes its life to is the attempt to make NKS immediately relevant in a roundabout way.&amp;#160; Remember, everything—everything—is simply a computation.&amp;#160; Another concept that is critical to understanding WolframAlpha from NKS is “computational equivalence”; essentially this is the reason why NKS doesn’t permit predicting the future: to do that you would need a computer the equivalent of our universe.&amp;#160; Reality, you see, is simply the current result of the continuous computation being performed by the fabric of our universe.&amp;#160; (As strange as that may sound, it is not dissimilar from the beliefs of proponents of the much vaunted string theories of the universe.)&lt;/p&gt;  &lt;p&gt;Since we don’t have a computer the size of the world, we can’t calculate everything in reality.&amp;#160; What we can do, though, is examine the current results of the computation, in the form of data that can be collected and mined and extruded by domain experts into an symbolic ontology that is computable by Mathematica.&amp;#160; We can then run computations with these synthetic ontologies, because they can be related via formal ontology of units we have created throughout human history.&amp;#160; To what end?&amp;#160; Well, I suppose that depends on the answers you get.&lt;/p&gt;  &lt;p&gt;I hope by now you understand why it is called WolframAlpha.&amp;#160; And, for those lovers of the theater who haven’t yet guessed, here is the cast of characters.&lt;/p&gt; &lt;dl&gt;&lt;dt&gt;Hamlet&lt;/dt&gt;&lt;dd&gt;WolframAlpha&lt;/dd&gt;&lt;dt&gt;Fortinbras&lt;/dt&gt;&lt;dd&gt;Google Squared &lt;/dd&gt;&lt;dt&gt;Gertrude&lt;/dt&gt;&lt;dd&gt;Capitalism&lt;/dd&gt;&lt;dt&gt;Ophelia&lt;/dt&gt;&lt;dd&gt;Wikipedia &lt;/dd&gt;&lt;dt&gt;Claudius&lt;/dt&gt;&lt;dd&gt;Academia&lt;/dd&gt;&lt;/dl&gt;  &lt;p&gt;I think it is obvious who plays the role of the murdered king. Ok, I've surely stretched the metaphor a bit too thin, but I really like the notion that these kinds of current events are manifestations of the same archetypes described in our great literature. I think Wolfram would like it too, but I have no doubt his protagonist wouldn't be from one of Shakespeare's tragedies.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-2413651036772682449?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/05/wolframalpha-new-kind-of-site.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-2131652274283759420</guid><pubDate>Mon, 11 May 2009 05:05:00 +0000</pubDate><atom:updated>2009-05-11T01:05:07.600-04:00</atom:updated><title>Microsoft TechEd: Day 0</title><description>&lt;p&gt;It’s the evening before the official start of the Microsoft’s annual IT conference, TechEd.&amp;#160; In 2009 we find ourselves in sunny, yet cool, Los Angeles.&amp;#160; I couldn’t be happier with the weather and the hotel, but so far the conference sucks.&lt;/p&gt;  &lt;p&gt;Why—or, more appropriately, how can I say it sucks when the conference hasn’t begun?&amp;#160; Easy, go to msteched.com and attempt to build a schedule.&amp;#160; Well, you have to be signed in with Windows Live and a registered attendee I believe, but if you could and did you would quickly discover a rather pathetic fail on the part of the conference planners.&amp;#160; The session builder is garbage.&amp;#160; You’ll spend the majority time watching this animation, since they’ve not seemed to master the partial page update without updating the entire 670K+ page weight.&amp;#160; Seriously, I’d rather look at the source and see and XML Data Island than wait for the entire page to reload every time I updated my schedule.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_FQ1igFTZD04/Sgex9jzHN-I/AAAAAAAAAEc/6CezBJ9LAkc/s1600-h/image%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_FQ1igFTZD04/Sgex-IvHGzI/AAAAAAAAAEg/8JvS7kkCJ6A/image_thumb.png?imgmax=800" width="244" height="88" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Aesthetically, it isn’t bad, the site I mean, but the session builder is garbage.&amp;#160; The session builder for Web 2.0 Expo at least displayed all the tracks and timeslots in a calendar-like fashion, so you could make your decision by sight and rather quickly.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_FQ1igFTZD04/Sgex_-V52lI/AAAAAAAAAEk/29stAGhf6iU/s1600-h/image%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_FQ1igFTZD04/SgeyAgYFHvI/AAAAAAAAAEo/pA20lZd0w4k/image_thumb%5B1%5D.png?imgmax=800" width="244" height="209" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;But, you know, if the content is there, if the sessions are just awesome, who cares about some clunky, hacked-together conference website?&amp;#160; Don’t judge a book by its cover, right?&amp;#160; So, what are my options for tomorrow’s 11am timeslot?&amp;#160; Well, the first keynote is this one.&lt;/p&gt; &lt;form id="aspnetForm" method="post" name="aspnetForm" action="https://www.msteched.com/schedulebuilder.aspx" jquery1242016308914="21" sizset="1" sizcache="179" oldonsubmit="null"&gt;   &lt;div id="page" jquery1242016308914="20" sizset="1" sizcache="179"&gt;     &lt;div id="content" jquery1242016308914="19" sizset="1" sizcache="179"&gt;       &lt;table width="100%" jquery1242016308914="18" sizset="1" sizcache="179"&gt;&lt;tbody jquery1242016308914="17" sizset="1" sizcache="179"&gt;           &lt;tr jquery1242016308914="16" sizset="1" sizcache="179"&gt;             &lt;td valign="top" sizset="1" sizcache="179"&gt;               &lt;div style="padding-bottom: 5px; padding-left: 5px; width: 545px; padding-right: 5px; height: 218px; padding-top: 5px" sizset="1" sizcache="179"&gt;                 &lt;div id="topicInfoTabContainer" sizset="1" sizcache="179"&gt;                   &lt;div id="topicInfoDiv" sizset="1" sizcache="179"&gt;                     &lt;div style="display: block" id="selectedItemDetails" jquery1242016308914="26" sizset="125" sizcache="169"&gt;                       &lt;div id="selectedTitle"&gt;KEY01 Moving Forward Together: The Potential of IT Innovation&lt;/div&gt;                        &lt;div style="font-size: 8pt" id="selectedPresenter"&gt;Presenter: Bill Veghte&lt;/div&gt;                        &lt;div style="font-size: 8pt" id="selectedTimeslotInfo" sizset="125" sizcache="168"&gt;                         &lt;div class="sessionInfo"&gt;Mon 5/11 | 10:00 AM-11:30 AM | West Hall A&lt;/div&gt;                       &lt;/div&gt;                        &lt;br /&gt;&lt;/div&gt;                      &lt;div id="pnlContainer" sizset="1" sizcache="179"&gt;                       &lt;div style="display: block" id="pnlAbstract" jquery1242016308914="28" sizset="0" sizcache="180"&gt;                         &lt;div class="desc"&gt;In today's economic environment, your company is faced with unprecedented pressures to reduce costs and drive operating efficiencies. At the same time, the demands on IT to deliver more connected services and greater flexibility continue to grow. With the upcoming release of Windows 7, Windows Server 2008 R2, and Exchange &amp;quot;14,&amp;quot; Microsoft helps IT organizations better meet these competing demands. Join Bill Veghte, Senior Vice President of Windows Business, as we explore how these technologies combine to give you the tools and resources to better manage your infrastructure--from back-end services through client-side experiences, and the network in between.&lt;/div&gt;                       &lt;/div&gt;                     &lt;/div&gt;                   &lt;/div&gt;                 &lt;/div&gt;               &lt;/div&gt;             &lt;/td&gt;           &lt;/tr&gt;         &lt;/tbody&gt;&lt;/table&gt;     &lt;/div&gt;      &lt;div jquery1242016308914="19" sizset="1" sizcache="179"&gt;Doesn’t exactly inspire.&amp;#160; But, never fear, there is an alternative!&lt;/div&gt;   &lt;/div&gt; &lt;/form&gt;&lt;form id="aspnetForm" method="post" name="aspnetForm" action="https://www.msteched.com/schedulebuilder.aspx" jquery1242016308914="21" sizset="1" sizcache="162" oldonsubmit="null"&gt;   &lt;div id="page" jquery1242016308914="20" sizset="1" sizcache="162"&gt;     &lt;div id="content" jquery1242016308914="19" sizset="1" sizcache="162"&gt;       &lt;table width="100%" jquery1242016308914="18" sizset="1" sizcache="162"&gt;&lt;tbody jquery1242016308914="17" sizset="1" sizcache="162"&gt;           &lt;tr jquery1242016308914="16" sizset="1" sizcache="162"&gt;             &lt;td valign="top" sizset="1" sizcache="162"&gt;               &lt;div style="padding-bottom: 5px; padding-left: 5px; width: 519px; padding-right: 5px; height: 161px; padding-top: 5px" sizset="1" sizcache="162"&gt;                 &lt;div id="topicInfoTabContainer" sizset="1" sizcache="162"&gt;                   &lt;div id="topicInfoDiv" sizset="1" sizcache="162"&gt;                     &lt;div style="display: block" id="selectedItemDetails" jquery1242016308914="26" sizset="125" sizcache="152"&gt;                       &lt;div id="selectedTitle"&gt;PAN59 Agile: A Process or an Excuse?&lt;/div&gt;                        &lt;div style="font-size: 8pt" id="selectedPresenter"&gt;Presenters: Richard Campbell, Stephen Forte, Chris Menegay, Joel Semeniuk&lt;/div&gt;                        &lt;div style="font-size: 8pt" id="selectedTimeslotInfo" sizset="125" sizcache="151"&gt;                         &lt;div class="sessionInfo"&gt;Mon 5/11 | 11:00 AM-12:00 PM | 501C&lt;/div&gt;                       &lt;/div&gt;                        &lt;br /&gt;&lt;/div&gt;                      &lt;div id="pnlContainer" sizset="1" sizcache="162"&gt;                       &lt;div style="display: block" id="pnlAbstract" jquery1242016308914="28" sizset="0" sizcache="163"&gt;                         &lt;div class="desc"&gt;Over the last few years, the community at large has created a number of agile development styles; Scrum, XP, and more are there for you and your team to choose. However, is agile really a process? On the other hand, is it an excuse to avoid accountability and proper development techniques? Come to this interactive session to see what Chris, Steve, and Joel have to say, and, if you are up for it, share your opinion.&lt;/div&gt;                       &lt;/div&gt;                     &lt;/div&gt;                   &lt;/div&gt;                 &lt;/div&gt;               &lt;/div&gt;             &lt;/td&gt;           &lt;/tr&gt;         &lt;/tbody&gt;&lt;/table&gt;     &lt;/div&gt;   &lt;/div&gt; &lt;/form&gt;  &lt;p&gt;Seriously, I’m not making this up.&amp;#160; I came to Los Angeles for this?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-2131652274283759420?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/05/microsoft-teched-day-0.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-4373118901024978152</guid><pubDate>Thu, 09 Apr 2009 17:52:00 +0000</pubDate><atom:updated>2009-04-09T13:52:10.683-04:00</atom:updated><title>The Coming Apocalypse of your "Friends"</title><description>&lt;p&gt;What's a friend on MySpace, Facebook, and Orkut?&amp;#160; If you have five hundred friends, are they really friends?&amp;#160; These are the main reasons why I have not, to this point, joined any of those sites.&amp;#160; I don't have many friends, because I just can't give a lot of people the energy needed to maintain a true, lasting friendship.&lt;/p&gt;  &lt;p&gt;What does this have to do with technology?&amp;#160; Well, Facebook Connect and Google FriendConnect are two apis, with many more to come, that allow you to take your social graph with you.&amp;#160; So now, instead of just being a bunch of people that post something they copy and pasted onto your &amp;quot;wall&amp;quot; at major holidays, they are now people who are going to affect recommendations you get on other websites.&lt;/p&gt;  &lt;p&gt;Tell me, do you want five hundred of your &amp;quot;closest&amp;quot; friends opinions, tastes, and web surfing habits to have a direct effect on your web experience?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-4373118901024978152?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/04/coming-apocalypse-of-your.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-5891745495833848830</guid><pubDate>Fri, 03 Apr 2009 19:10:00 +0000</pubDate><atom:updated>2009-04-03T15:10:50.157-04:00</atom:updated><title>Web 2.0 Expo Day 2</title><description>&lt;p&gt;This morning started with keynotes, though there didn't seem to be a theme beyond &amp;quot;here is who we could get to come and talk.&amp;quot; The sole exception was the very first speaker, &lt;a href="http://rushkoff.com/" target="_blank"&gt;Douglas Rushkoff&lt;/a&gt;, was fantastic.&amp;#160; I'm really excited about his new book, Life Inc.&amp;#160; His main theses were that corporations were not created to allow competition and artificial currency was not &lt;/p&gt;  &lt;p&gt;Nokia's CEO showed us his vision for ten years from now.&amp;#160; Wearable computers?&amp;#160; Wow, now that's innovative.&amp;#160; He got off on some weird metaphysical rant about projecting our consciousness into the 'net.&amp;#160; What he really means is a constant data stream of my location, mood, and random thoughts.&amp;#160; The only interesting thing he mentioned was geolocation through photography.&amp;#160; I really feel like that is an idea whose time has come.&lt;/p&gt;  &lt;p&gt;Next I attended a session that discussed the relative merits of building directly for the iPhone or the web, and the conclusion was use PhoneGap to do both.&amp;#160; it had some interesting points in making the case to stay web-based, but none of them were very convincing.&amp;#160; He attacked the following five arguments for going native:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Performance--the recent &amp;quot;fast javascript&amp;quot; movement combined with paring down the page bloat that has occurred in recent years &lt;/li&gt;    &lt;li&gt;Offline Usage--there is HTML 5 (and thus embedded mySQL support) in iPhone since v2.0 &lt;/li&gt;    &lt;li&gt;Findability--there are now 25K+ apps in the AppStore &lt;/li&gt;    &lt;li&gt;Device Capabilities (GPS, camera, accelerometer, etc.)--the GPS capabilities are &amp;quot;opening up&amp;quot;, and PhoneGap let's you go native &lt;/li&gt;    &lt;li&gt;Monetization--4% of devices get turned down, people use iPhone apps like tissue paper, you have to sell your app for $0.99 to get any traction &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Some valid points there, but it's ironic that the solution proffered is to start web-based and enhance to native.&lt;/p&gt;  &lt;p&gt;Microsoft Bizspark were the underwriters for Launch Pad at Web 2.0 Expo.&amp;#160; There were five companies who presented:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.phonegap.com"&gt;PhoneGap&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.80legs.com"&gt;80legs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;zeaLOG &lt;/li&gt;    &lt;li&gt;Dub (at &lt;a href="http://www.dubmenow.com"&gt;DubMeNow&lt;/a&gt;) &lt;/li&gt;    &lt;li&gt;Bantam (&lt;a href="http://www.bantamlive.com"&gt;Bantam Networks&lt;/a&gt;) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Honestly, I wish I had gone to a different session.&amp;#160; I already knew about PhoneGap from the ten other times it was mentioned this week.&amp;#160; What they are doing at 80legs is really cool, but I'm not sure about its applicability.&amp;#160; They've made something that is really hard to do really cheap, but they've not made it easy.&amp;#160; That is, you still have to write Java code.&amp;#160; I'm more excited about what people are doing with it, a sure sign of a platform play.&amp;#160; I hope they get acquired and rewarded for their hard work.&amp;#160; One last thing, there was maybe a hundred people in the room.&amp;#160; Maybe.&lt;/p&gt;  &lt;p&gt;I went to a talk from the guys at EngineYard.&amp;#160; Pretty good talk, but really centered on the implications of systems management in the could-era.&amp;#160; I really enjoyed the talk, pretty fun.&amp;#160; The gave it in this paired presenter style where one would pick up where the other left off.&amp;#160; Nothing terrible prescient or relevant to me, but they host a lot of really awesome new companies, like github.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-5891745495833848830?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/04/web-20-expo-day-2.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-6305261274278119099</guid><pubDate>Thu, 02 Apr 2009 01:17:00 +0000</pubDate><atom:updated>2009-04-01T21:17:51.009-04:00</atom:updated><title>Werner Vogels</title><description>&lt;p&gt;Super cool guy.&amp;#160; He's one of those super geeks that's past the point where he feels it necessary to get dragged into details but is totally upbeat.&amp;#160; It's good to be the king, right?&amp;#160; Perhaps my biggest surprise was to learn just how much Amazon views itself as a technology company.&amp;#160; Amazon's retail experience is just a customer of AWS.&amp;#160; Riiiight.&amp;#160; I find that hard to believe, but he claims that Amazon.com the retail site is not even the biggest customer of AWS.&amp;#160; Whoa.&lt;/p&gt;  &lt;p&gt;My big takeaway from his talk and comments afterward is that only companies that really, really must scale to incredible extremes should build their applications for AWS, i.e. bake in use of SimpleDB, SQS, etc.&amp;#160; What he said to me was, &amp;quot;run your Linux infrastructure on EC2 so you can leave if you don't like us.&amp;quot;&amp;#160; So, really, build great SOA systems and use AWS as a virtualization provider.&amp;#160; He had a lot of great principles in his talk for building scalable systems, including:&lt;/p&gt; &lt;dl&gt;&lt;dt&gt;Autonomy &lt;/dt&gt;&lt;dd&gt;individual components make decisions only based on local information &lt;/dd&gt;&lt;dt&gt;Asynchrony&lt;/dt&gt;&lt;dd&gt;Make progress under all circumstances &lt;/dd&gt;&lt;dt&gt;Controlled Concurrency&lt;/dt&gt;&lt;dd&gt;operations are designed such that limmited or no concurrency control is required &lt;/dd&gt;&lt;dt&gt;Controlled Parallelism&lt;/dt&gt;&lt;dd&gt;use fully decentralized (p2p) techniques to remove bottlenecks &lt;/dd&gt;&lt;dt&gt;Decentralize&lt;/dt&gt;&lt;dd&gt;Remove dependencies &lt;/dd&gt;&lt;dt&gt;Decompose&lt;/dt&gt;&lt;dd&gt;Break up into more granular services &lt;/dd&gt;&lt;dt&gt;Failure Tolerant&lt;/dt&gt;&lt;dd&gt;Failure is a normal part of operation &lt;/dd&gt;&lt;dt&gt;Local Responsibility for Consistency&lt;/dt&gt;&lt;dd&gt;Similar to Autonomy, don't look elsewhere for consistent state &lt;/dd&gt;&lt;dt&gt;Simplicity&lt;/dt&gt;&lt;dd&gt;pare away functionality until you cannot &lt;/dd&gt;&lt;dt&gt;Symmetry&lt;/dt&gt;&lt;dd&gt;all nodes can do any function in the system &lt;/dd&gt;&lt;/dl&gt;  &lt;p&gt;Some other interesting bits were that the Amazon Homepage is produced by 200-300 services. Every service at Amazon is developed and operated by the same team. There are about 500-600 services/teams. Elasticity is both shrinking AND growing on demand.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-6305261274278119099?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/04/werner-vogels.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-6298343166500452071</guid><pubDate>Thu, 02 Apr 2009 01:04:00 +0000</pubDate><atom:updated>2009-04-01T21:04:17.600-04:00</atom:updated><title>Geolocation: The new W3C API</title><description>&lt;p&gt;A thought leader in geolocation from the company that created Loki gave a talk about geolocation on the web.&amp;#160; His first recommendation was to build your applications to adopt latitude and longitude as the basic unit of location.&amp;#160; He then went on to talk about all the other ways location can be represented.&amp;#160; For example, the names of business, location descriptions, planar areas (rather than points) on a map, etc.&amp;#160; These are generally much more welcome in the UX than map coordinates.&lt;/p&gt;  &lt;p&gt;Some ways of getting local businesses are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Yahoo! Local Search API&lt;/li&gt;    &lt;li&gt;Yelp&lt;/li&gt;    &lt;li&gt;Localeze&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The skinny on geolocation for the web right now is that it relies on browser plug-ins or extensions.&amp;#160; The nice thing is that a W3C working group put together a standard for accessing the geolocation capabilities of the browser from Javascript.&amp;#160; It's quite easy to use, if not widely available.&lt;/p&gt;  &lt;p&gt;One interesting stat is the precision one can expect from the various means of geolocation.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;GPS can be accurate to within 10m for commercial applications&lt;/li&gt;    &lt;li&gt;Wifi (database lookup and triangulation from SSIDs and signal strength) can be as good as 20m up to 80m&lt;/li&gt;    &lt;li&gt;Cell towers are up around 1000m&lt;/li&gt;    &lt;li&gt;IP address based schemes are wildly inaccurate and limited to city/region precision&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Loki.com/how and Google Gears utilize hybrid approaches to do geolocation, obviously, to balance speed of acquisition, device capability, desire precision, etc.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-6298343166500452071?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/04/geolocation-new-w3c-api.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-4441300661661801130</guid><pubDate>Thu, 02 Apr 2009 00:49:00 +0000</pubDate><atom:updated>2009-04-01T20:49:39.259-04:00</atom:updated><title>Web Developer Tools from Web 2.0</title><description>&lt;p&gt;This was by far the best presentation I saw today.&amp;#160; A couple of Mozilla guys gave this great talk really about the past, present, and future of the web developer experience.&amp;#160; I'm really buzzed about the near future of HTML 5, &amp;quot;fast javascript&amp;quot;, and the &amp;quot;web worker&amp;quot; model, enabling the kind of interactivity available on desktop applications.&lt;/p&gt;  &lt;p&gt;The introduced a lot of tools, mostly around Firebug and its extensions.&amp;#160; I wasn't familiar with the unit testing stuff in that space: Code Coverage and FireUnit.&amp;#160; Some of the more interesting tools were the CSS tools: &lt;a href="http://developer.yahoo.com/yui/grids/builder/" target="_blank"&gt;YUI CSS Grid Builder&lt;/a&gt;, &lt;a href="http://www.blueprintcss.org/" target="_blank"&gt;blueprint&lt;/a&gt;, and the recently announced &lt;a href="http://blogs.msdn.com/xweb/archive/2009/03/18/Microsoft-Expression-Web-SuperPreview-for-Windows-Internet-Explorer.aspx" target="_blank"&gt;Microsoft SuperPreview&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;They also mentioned some &amp;quot;future&amp;quot; tools like Bespin and Thunderhead.&amp;#160; Bespin is wonderful, a source code editor on the web, with concurrent-versioning system support (git now and later SVN?).&amp;#160; I really feel like this is boostrapping the web, you can begin to think of creating the web ON the web.&amp;#160; Avi Bryant has already plugged Seaside into Bespin.&amp;#160; Thunderhead is a prototype for marrying grid-layouts with the HTML 5 canvas.&amp;#160; They are talking about doing an &amp;quot;Open Tools Directory&amp;quot;.&lt;/p&gt;  &lt;p&gt;One thing they mentioned that was only tagentially related to their talk was &lt;a href="http://phonegap.com/" target="_blank"&gt;PhoneGap&lt;/a&gt;.&amp;#160; This let's HTML/Javascript developers create native mobile phone applications (iPhone, Android, and Blackberrry are supported to different extents at this time).&amp;#160; Atlas, which let's you write native Cocoa (Mac OS) applications in Javascript (their Objective J) was given an excited nod, too.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-4441300661661801130?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/04/web-developer-tools-from-web-20.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-7863972162865414454</guid><pubDate>Thu, 02 Apr 2009 00:32:00 +0000</pubDate><atom:updated>2009-04-01T20:32:49.788-04:00</atom:updated><title>Why Scala?</title><description>&lt;p&gt;I'm trying to catch up with blogging about the sessions I've attended this first day of the Web 2.0 Expo.&amp;#160; The second session I attended today was entitled, &amp;quot;Why Scala?&amp;quot; Presented by a fellow from Twitter, it was essentially a discussion on their adoption of Scala from their initial appraisal of the technology landscape through the pilot project successes to their company-wide embrace of Scala.&lt;/p&gt;  &lt;p&gt;Despite not having any major investment in Java code, the JVM platform gave them access to the myriad Java libraries already out there, as well as the ability to do things like hydrate JSON as a JVM object and reason about it naturally within Scala.&amp;#160; Given that they were looking for a language with a great concurrency story, this appears to be the number one reason for choosing Scala, that it is a JVM language written by people who really understand the JVM internals.&amp;#160; Some of the other reasons put forth were:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Actor model--like Erlang the primary programming paradigm of Scala is independent workers that share no state and pass messages&lt;/li&gt;    &lt;li&gt;Immutability--with built-in immutable data structures and the Actor model, Scala heavily encourages immutability, but doesn't force it, meaning you can take advantage of mutability when it is more expressive or performant&lt;/li&gt;    &lt;li&gt;Type inference--yay, strong typing AND pretty code&lt;/li&gt;    &lt;li&gt;First-class functions&lt;/li&gt;    &lt;li&gt;Traits--not real clear on what this is, I think the Erlang/OTP equivalent would be behaviors&lt;/li&gt;    &lt;li&gt;Pattern matching--this is similar to what Erlang does, but isn't limited to tuples or other terms, i.e. you can match objects&lt;/li&gt;    &lt;li&gt;XML Literals &amp;amp; Query methods baked into the language&lt;/li&gt;    &lt;li&gt;Case Classes--these sound like structs, maybe message types?&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The &amp;quot;bad&amp;quot; thing about Scala is that it forces you to learn a bit more about the JVM than perhaps you were inclined to learn, and it is very complex.&amp;#160; There seems to be quite a community evolving around Scala, and the mainstreaam web framework is called Lift.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-7863972162865414454?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/04/why-scala.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-6266396974476382550</guid><pubDate>Wed, 01 Apr 2009 23:49:00 +0000</pubDate><atom:updated>2009-04-01T19:49:29.434-04:00</atom:updated><title>Identity Wars and Joseph Smarr</title><description>&lt;p&gt;I remember Mr. Smarr's talk about OpenID and OAuth from a couple of years ago.&amp;#160; I got the impression that his biggest fear was that Facebook would always be a walled garden.&amp;#160; For reasons I don't quite understand, perhaps a sort of social consciousness (no pun intended), Facebook has opened their platform up, albeit in a limited and proprietary way.&lt;/p&gt;  &lt;p&gt;Fortunately, there are companies like Google and JanRain who are hiding the differences between the Open Stack and Facebook's APIs.&amp;#160; First, let's have a look at the Open Stack proper.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;OpenID for authentication &lt;/li&gt;    &lt;li&gt;OAuth for authorization &lt;/li&gt;    &lt;li&gt;XRD a service discovery protocol&lt;/li&gt;    &lt;li&gt;&lt;a href="http://portablecontacts.net/" target="_blank"&gt;Portable Contacts&lt;/a&gt; (self-explanatory)&lt;/li&gt;    &lt;li&gt;&lt;a href="http://code.google.com/apis/opensocial/" target="_blank"&gt;Open Social&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://www.janrain.com/products/rpx_faq" target="_blank"&gt;JanRain has RPX&lt;/a&gt;, and &lt;a href="http://www.google.com/friendconnect/" target="_blank"&gt;Google has FriendConnect&lt;/a&gt;, so using the OpenID/OAuth stuff is easy without really knowing a lot.&amp;#160; What is needed is a way to marry the existing authentication stacks of all the common web platforms (ASP.NET, PHP, etc.) with the Open Stack, I think.&lt;/p&gt;  &lt;p&gt;For more information, here are some blogs:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;TheSocialWeb.tv &lt;/li&gt;    &lt;li&gt;JosephSmarr.com &lt;/li&gt;    &lt;li&gt;TheRealMcCrea.com &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-6266396974476382550?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/04/identity-wars-and-joseph-smarr.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-1909731660141018568</guid><pubDate>Wed, 01 Apr 2009 16:22:00 +0000</pubDate><atom:updated>2009-04-01T12:22:46.489-04:00</atom:updated><title>SEO: From Soup to Nuts--Web 2.0 Expo Workshop</title><description>&lt;p&gt;It's workshop day in the first and only pre-conference day of Web 2.0 Expo San Francisco.&amp;#160; Among the first sessions of the day, I opted to attend the presentation given by Stephan Spencer of Netconcepts: &amp;quot;SEO: From Soup to Nuts.&amp;quot; &lt;/p&gt;  &lt;p&gt;His presentation was organized around his &amp;quot;three pillars of SEO&amp;quot;: Content, Architecture, and Links.&amp;#160; His SEO practice is very data driven as evidenced by his egregious use of statistics.&amp;#160; Among the highlights of those statistics:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;1.25 to 1.5 times more conversions to PPC versus &amp;quot;natural&amp;quot; (normal search result click-through) &lt;/li&gt;    &lt;li&gt;86% of search engine clicks are natural &lt;/li&gt;    &lt;li&gt;47% click-through on first Google result falls to 10% on second, and half of the first natural for the first paid &lt;/li&gt;    &lt;li&gt;Double click through rate for short URLs according to Marketing Sherpa &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It definitely isn't all about statistics in the SEO game, though.&amp;#160; In fact, it seemed as if getting hard data about efficacy was the biggest and enduring challenge.&amp;#160; There are some hard-and-fast techniques to employ, thankfully.&amp;#160; Page titles, using 301s, nofollow links, canonical tags, there should be only one url for any given content, etc., as well as some great tools (both free and pay) including:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;SEOmoz.org's LinkScape &lt;/li&gt;    &lt;li&gt;SEObrowser.com &lt;/li&gt;    &lt;li&gt;Google Web Optimizer &lt;/li&gt;    &lt;li&gt;SIFR &lt;/li&gt;    &lt;li&gt;Adobe Search Engine SDK &lt;/li&gt;    &lt;li&gt;Yahoo! Site Explorer &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There were also a lot of surprises, at least to me:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Search result rankings can vary from city to city (of searcher) &lt;/li&gt;    &lt;li&gt;Underscores do not count as word separators to Google &lt;/li&gt;    &lt;li&gt;YouTube doesn't give link juice (nofollow) &lt;/li&gt;    &lt;li&gt;Digg users do not buy anything &lt;/li&gt;    &lt;li&gt;User generated content can get you so-called &amp;quot;long tail terms&amp;quot; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_FQ1igFTZD04/SdOU0_CxtgI/AAAAAAAAAEU/z9k3CevNsZE/s1600-h/eyetrackingseo4.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="eyetrackingseo" src="http://lh5.ggpht.com/_FQ1igFTZD04/SdOU1fOYq7I/AAAAAAAAAEY/qmgppn6kLDk/eyetrackingseo_thumb2.jpg?imgmax=800" width="169" align="left" border="0" /&gt;&lt;/a&gt;One thing I wondered, looking at this image that shows the distribution of eye movement on the Google results page, is what are people actually looking for one Google.&amp;#160; They aren't looking for knowledge, but information, a gateway to knowledge, perhaps.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-1909731660141018568?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/04/seo-from-soup-to-nuts-web-20-expo.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-7359336337206279143</guid><pubDate>Sun, 29 Mar 2009 16:48:00 +0000</pubDate><atom:updated>2009-03-29T12:48:40.923-04:00</atom:updated><title>Web 2.0 Expo travel</title><description>We have just been incredibly fortunate this far. I last flew commercial soon after 9/11, and the experience was harsh to say the least. Anotinio Gramsci once wrote that the downfall of a secular democracy was the continuous surrendering of freedoms in exchange for protection from our fellow citizens. Our travel experience to SF this weekend has taught me how much the human spirit can shine despite and perhaps paradoxically because of difficult circumstance. We have been graced by the goodwill of so many of our fellow citizens that I am tacitly aware of Gramsci's error if unable to put words to it.&lt;br /&gt;&lt;br /&gt;Today has been incredible, but I must save my emotive prose for another time. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href='http://blogpress.w18.net/photos/09/03/29/165.jpg'&gt;&lt;img src='http://blogpress.w18.net/photos/09/03/29/s_165.jpg' border='0' width='280' height='281' style='margin:5px'&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-7359336337206279143?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/03/web-20-expo-travel.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-4078913350720578645</guid><pubDate>Thu, 19 Mar 2009 02:35:00 +0000</pubDate><atom:updated>2009-03-18T22:35:23.926-04:00</atom:updated><title>Sex-Software Simile</title><description>&lt;p&gt;Using software vendors' technology demos as the metric for your software development is like measuring your sexual prowess by watching porn films: accurate for edge cases but ultimately not relevant.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-4078913350720578645?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/03/sex-software-simile.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6928325842095718321.post-339166809452097069</guid><pubDate>Fri, 13 Mar 2009 17:51:00 +0000</pubDate><atom:updated>2009-03-13T14:09:38.325-04:00</atom:updated><title>Why ORM? Why Cloud Computing?</title><description>&lt;p&gt;I think it was Fred Brooks that once wrote that someone will inevitably look at any software system and ask, &amp;quot;how did we get here?&amp;quot; And, the answer is invariably, &amp;quot;one logical choice at a time.&amp;quot;&amp;#160; Rather than answer the questions, &amp;quot;Why ORM?&amp;quot; and &amp;quot;Why Cloud Computing?&amp;quot;, I will endeavor to elucidate those logical choices.&lt;/p&gt;  &lt;p&gt;The monolithic database model (MDM) has served the IT sector very well for about fifty years.&amp;#160; I will explicitly define it as a model of software development where myriad applications are integrated through a shared database, or--more accurately--more than one user interface is provided to a database.&amp;#160; In this model the database itself is where business processes and domain modeling exist.&amp;#160; Enterprises often expanded these databases to include all aspects of the business, or perhaps a few databases integrated via ETL, until the number of objects exceeded any one person's capacity to understand the system.&amp;#160; EDI, data warehousing, and data marts are all extensions of the (MDM) for dealing with M&amp;amp;A, e-biz partners, etc.&amp;#160; Given a large number of well-trained database professionals with rigorous communication and documentation requirements, the monolithic database model is efficacious and expedient. &lt;/p&gt;  &lt;p&gt;As object-oriented programming techniques became more well-known, developers began modeling the domain and business process using advanced general purpose programming languages like Lisp, Smalltalk, C++, etc.&amp;#160; They used object databases to persist these models and all was good and productive.&amp;#160; Unfortunately, few developers grok those technologies, and even fewer have a mastery of the techniques needed to use them well, so it didn't catch on.&amp;#160; Perhaps the biggest impediment to adoption was the success of the MDM. The MDM was working and understood.&amp;#160; The deficiencies of the model were insufficient to move IT development en masse to the object crowd. &lt;/p&gt;  &lt;p&gt;Still, a lot of software was being written outside of IT.&amp;#160; Embedded developers loved object programming and had no need to store loads of data.&amp;#160; So, the hardcore programmers--those that relish writing life support systems, flight control systems, nuclear power plant control systems, etc.--were exclusively &amp;quot;object guys&amp;quot;.&amp;#160; Meanwhile, Sun Microsystems was building a runtime for embedded systems to simplify programming across hardware--Java.&amp;#160; A 4GL, Java had all the object-oriented bells and whistles, and Sun had written runtimes for Unix, Solaris, and even Windows!&amp;#160; These runtimes came bundled with AWT, allowing developers to nominally &amp;quot;write once, run anywhere.&amp;quot;&lt;/p&gt;  &lt;p&gt;Suddenly there was the WWW.&amp;#160; I say suddenly because even Bill Gates once purportedly remarked that it was irrelevant.&amp;#160; As IT understood the implications of Metcalfe's Law for the Internet, it became the elephant in every boardroom.&amp;#160; No single company in the world wanted to be a loser in the new, connected economy.&amp;#160; All IT decisions were tempered by the Internet revolution.&lt;/p&gt;  &lt;p&gt;Now the cohesive, insular world of the MDM was really looking problematic.&amp;#160; Still, that's where the data was, and ultimately the Internet was about access to information.&amp;#160; So, every IT vendor that wanted to compete was pitching platforms that claimed to do one central task better than anyone else: turn relational data into web pages.&amp;#160; These platforms were either backed by scripting or 4GL, and DBI, JDBC, ODBC, ADO, etc., in all their versions and iterations were simply libraries used by the object guys to get at the data.&lt;/p&gt;  &lt;p&gt;Concurrently, universities had been turning out software developers who started writing C++ or Java in their freshman year, graduating to &amp;quot;real&amp;quot; object languages in subsequent years.&amp;#160; The worldwide demand for IT developers skyrocketed, and technical colleges met the challenge with programs designed to get people into the market with the minimal set of skills to create web applications.&amp;#160; At this point the technologies for building web applications were infantile relative to RDBMS technologies.&amp;#160; The result was a lot of really bad developers developing really bad applications, slowly.&lt;/p&gt;  &lt;p&gt;The good developers, the object guys with strong Lisp kung fu, really resented having to interface with databases--to go from their object model to a data model.&amp;#160; IT programmers oft complained of the inordinate amount of time they spent move data in and out of databases.&amp;#160; Architects started designing systems built around messaging again, calling them web services this time, and the canon said that these messages were serialization of object state.&amp;#160; So smart people started writing libraries for interfacing with databases in a tacit fashion, attempting to abstract away the &amp;quot;implementation details&amp;quot; of data storage and retrieval: object-relational mappers (ORM).&amp;#160; The &amp;quot;real&amp;quot; model of business entities and processes, after all, were their objects.&lt;/p&gt;  &lt;p&gt;Now, the old IT systems in DB2 and Cobol were &amp;quot;legacy&amp;quot; systems to be tolerated until they could eventually be re-written.&amp;#160; New IT initiatives would set out in their own silo (usually an application server), with their own persistence engines that utilized ORM, and integrate with the legacy systems via message-oriented middleware (MOM): Biztalk, SOA, ESB, etc.&amp;#160; Vendors were happy because MOM was expensive; object-guys were happy because their jobs now matched up with their education; and business owners were hopefully optimistic because mainframe vendors all operate on an annuity model, and the owners' hope was to escape from a world of multi-million dollar support contracts.&lt;/p&gt;  &lt;p&gt;Lo, the MDM guys sneered, since the whole enterprise--the business itself--was still built upon their systems, and every attempt to re-write their systems was an incredibly expensive failure.&lt;/p&gt;  &lt;p&gt;Business owners were getting pretty angry, too.&amp;#160; All these application servers needed lots of new hardware, and the new servers needed to be partitioned by firewalls, and they needed new database servers too, since RDBMS was still the persistence engine of choice, and of course all of this needed fail-over and clustering.&amp;#160; Meanwhile, what the developers were producing wasn't sufficient to run the entire business on, so they now had to maintain two systems in parallel, putting increased strain on the middleware servers.&amp;#160; Further, the developer's velocity was slow, since everything had to be integrated, and years and years of process refinements implicit in the MDM had to be re-imagined and re-discovered.&amp;#160; This integration stuff was expensive.&lt;/p&gt;  &lt;p&gt;Again, though, not all software was being written in IT shops.&amp;#160; There were companies building applications hosted on web servers that were available on-demand, so called Application Service Providers (ASP).&amp;#160; These companies didn't have any legacy systems and drew the smartest object guys.&amp;#160; Many of them were wildly successful, but when the dot-com bubble burst, the idea that a company that you relied upon for mission critical systems could just disappear caused many IT shops to reject the idea out-of-hand.&amp;#160; The ASPs that survived were those companies that offered important but not &amp;quot;mission-critical&amp;quot; (like email, production data management, etc.) services, such as sales force automation or marketing support.&amp;#160; Another class of ASPs that won were those that offered hosted services to SME customers who could not or chose not to afford the sunk costs of providing their own infrastructure.&lt;/p&gt;  &lt;p&gt;In the U.S., capital was king; the financial markets were providing great returns and due to foreign investment and interest rate cuts the cost of capital was low.&amp;#160; Businesses were now faced with enormous capital expenditures from their IT operations during a time when capital investments were the most prudent choice, but no one was willing to give up the very real productivity gains that had been made steadily in the last decade.&amp;#160; The solution to the dilemma was to defer expenditures, to lease.&lt;/p&gt;  &lt;p&gt;At the same time, the business owner's frustration with the lack of agility of their IT operations peaked.&amp;#160; The costs were high, the pace of development was slow, the requirements gathering and definition process was pain-staking, and the failure rate was abominable.&amp;#160; The maintenance costs alone for all the manifold servers, languages, and platforms was choking the life out of new business opportunities before they could be explored.&lt;/p&gt;  &lt;p&gt;So, the market itself demanded cloud-computing.&amp;#160; Rather than buying the infrastructure and paying to provision it, they wanted to &amp;quot;pay as you go.&amp;quot;&amp;#160; Elastic demand on IT systems meant provisioning for the worst-possible scenario; cloud-computing meant scaling-up (and down) on demand.&amp;#160; Rather than having to pay for and maintain application servers, database servers, load-balancers, etc., they could just write the app and see if it sticks.&lt;/p&gt;  &lt;p&gt;Yea, though I walk through the valley of the shadow of integration, I shall fear no SQL.&lt;/p&gt;  &lt;p&gt;The problem of integration remains.&amp;#160; No cloud platform fits any enterprise's IT needs completely, so now the challenge is how to integrate a world where the web application server platform is considered a legacy.&amp;#160; Microsoft's solution is to position all ASP.NET development as &amp;quot;cloud&amp;quot; development, making it easy to keep the application on-premise or move it to the cloud (Azure).&amp;#160; Ironically, the major impediment to this approach is the persistence engine: the database.&amp;#160; &lt;/p&gt;  &lt;p&gt;Moving a database that fully exploits the RDBMS platform to the cloud is non-trivial.&amp;#160; In other words, developers that wrote stored procedures, utilized event brokers or extended stored procedures, created ETL jobs, made it unlikely that they can move their applications to Azure.&amp;#160; If they instead had only used pure ORM (LINQ2SQL), this could be done mechanically.&lt;/p&gt;  &lt;p&gt;This property of not violating the ORM abstraction, namely the ease with which the backing data store can be mechanically replaced, is the key reason why ORM advocates promulgate the principle that the application should never accept a dependency on the data store.&amp;#160; In other words, no stored procedures allowed.&amp;#160; The Entity Data Model is an attempt to abstract the universality of the data model--arguably the best feature of MDM--away from the persistent storage engine(s), in order to ensure the portability of the data model in the enterprise and beyond, i.e. to the cloud.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6928325842095718321-339166809452097069?l=iformattable.blogspot.com'/&gt;&lt;/div&gt;</description><link>http://iformattable.blogspot.com/2009/03/why-orm-why-cloud-computing.html</link><author>noreply@blogger.com (Christopher)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></item></channel></rss>
