<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Honest to a Segfault &#187; Pragmatic Programming</title>
	<atom:link href="http://blog.cdleary.com/tag/pragmatic-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.cdleary.com</link>
	<description>__author__ = &#039;Chris Leary&#039;</description>
	<lastBuildDate>Sun, 05 Sep 2010 20:41:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Why you should bother!</title>
		<link>http://blog.cdleary.com/2009/10/why-you-should-bother/</link>
		<comments>http://blog.cdleary.com/2009/10/why-you-should-bother/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 07:40:34 +0000</pubDate>
		<dc:creator>cdleary</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[Interviews]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Pragmatic Programming]]></category>

		<guid isPermaLink="false">http://blog.cdleary.com/?p=648</guid>
		<description><![CDATA[<p>I write this entry in response to <a class="reference external" href="http://sayamindu.randomink.org/ramblings/2009/04/29/why-should-i-bother/">Why Should I Bother?</a>. The answer, in short, is that I find Python to be a great language for getting things done, and you shouldn't let stupid interviewers deter you from learning a language that allows you to get more done.</p>
<p>I think I'm a pretty tough interviewer, so I also describe the things I'd recommend that a Python coder knows before applying to a Java position, based on my own technical-interview tactics.</p>]]></description>
			<content:encoded><![CDATA[<p>I write this entry in response to <a class="reference external" href="http://sayamindu.randomink.org/ramblings/2009/04/29/why-should-i-bother/">Why Should I Bother?</a>. The answer, in short, is that I find Python to be a great language for getting things done, and you shouldn&#8217;t let stupid interviewers deter you from learning a language that allows you to get more done.</p>
<p>I think I&#8217;m a pretty tough interviewer, so I also describe the things I&#8217;d recommend that a Python coder knows before applying to a Java position, based on my own technical-interview tactics.</p>
<div class="section" id="a-spectrum-of-formality">
<h3>A spectrum of formality</h3>
<p>As <a class="reference external" href="http://twitter.com/gok">my friend</a> pointed out to me long ago, many computer scientists don&#8217;t care about effective programming methods, because they prefer theory. Understandably, we computer scientists qua programmers (AKA software engineers) find ourselves rent in twain.</p>
<p>As a computer science degree candidate, you are inevitably enamored with complex formalities, terminology, <a class="footnote-reference" href="#id4" id="id3"><tt>[*]</tt></a> and a robust knowledge of mathematical models that you&#8217;ll use a few times per programming project (if you&#8217;re lucky). Pragmatic programming during a course of study often takes a back seat to familiar computer science concepts and conformance to industry desires.</p>
<p>As a programmer, I enjoy Python because I find it minimizes boilerplate, maximizes my time thinking about the problem domain, and permits me to use whichever paradigm works best. I find that I write programs more quickly and spend less time working around language deficiencies.  Importantly, the execution model fits in my brain.</p>
<p>Real Computer Scientists (TM) tend to love pure-functional programming languages because they fit into mathematical models nicely &#8212; founded on recursion, <a class="reference external" href="http://en.wikipedia.org/wiki/Curry-Howard_isomorphism">Curry-Howard isomorphism</a>, and what have you &#8212; whereas Python is strongly imperative and, <a class="reference external" href="http://www.youtube.com/watch?v=OKFeLZqLxzQ">in its dynamism, lacks the same sort of formality</a>.</p>
<p>Languages like Java sit somewhere in the middle. They&#8217;re still strongly imperative (there are no higher-order functions in Java), but there are more formalities. As the most notable example, compile-time type checking eliminates the possibility of type errors, which gives some programmers a sense of safety. <a class="footnote-reference" href="#id8" id="id7"><tt>[†]</tt></a> Such languages still let scientists chew on some computer sciencey problems; for example, where values clash with the type system, like <a class="reference external" href="http://www.youtube.com/watch?v=3d0YlZbY92U">provably eliminating NullPointerExceptions</a>, which <a class="reference external" href="http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake">is fun, but difficult</a>!</p>
<p>As the cost of increased formality, this class of languages is more syntax-heavy and leans on design patterns to get some of the flexibility dynamic typing gives you up front.</p>
<p>It&#8217;s debatable which category of languages is easiest to learn, but Java-like languages have footholds in the industry from historical C++ developer bases, Sun&#8217;s successful marketing of Java off of C++, and the more recent successes of the C# .NET platform.</p>
<p>It makes sense that we&#8217;re predominantly taught this category of languages in school: as a result, we can play the percentages and apply for most available developer jobs. Given that we have to learn it, you might as well do some <a class="reference external" href="http://en.wikipedia.org/wiki/Kata_%28programming%29">throw-away programming</a> in it now and again to keep yourself from forgetting everything; however, I&#8217;d recommend, as a programmer, that you save the fun projects for whichever language(s) that you find most intriguing.</p>
<p>I picture ease-and-rapidity of development-and-maintenance on a spectrum from low to high friction &#8212; other languages I&#8217;ve worked in fall somewhere on that spectrum as higher friction than Python. Though many computer scientists much smarter than I seem to conflate formality and safety, I&#8217;m fairly convinced I attain code completion and maintainability goals more readily with the imperative and flexible Python language. Plus, perhaps most importantly, <a class="reference external" href="http://imgs.xkcd.com/comics/python.png">I have fun</a>.</p>
</div>
<div class="section" id="my-technical-interview-protocol">
<h3>My technical-interview protocol</h3>
<p>The protocol I use to interview candidates is pretty simple. <a class="footnote-reference" href="#id14" id="id13"><tt>[‡]</tt></a></p>
<ul class="simple">
<li>Analyze their background experience for potential weaknesses that would affect their ability to perform in the position.</li>
<li>Don&#8217;t let the candidate talk about anything until the last <em>n</em> minutes, when they can ask questions or comment on the interview experience.</li>
<li>Hone in on the areas of potential weakness to determine how bad they are (if they&#8217;re bad at all).</li>
<li>Evaluate how easy it is to overcome those weaknesses. Determine where their level in relevant areas falls in the <a class="reference external" href="http://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition">Dreyfus model</a> and how much it matters to the description of the position.</li>
</ul>
</div>
<div class="section" id="potential-java-interview-weaknesses">
<h3>Potential Java interview weaknesses</h3>
<p>Interviewing a candidate whose background is primarily Python based for a <em>generic</em> Java developer position (as in <a class="reference external" href="http://sayamindu.randomink.org/ramblings/2009/04/29/why-should-i-bother/">Sayamindu&#8217;s entry</a>), I would immediately flag the following areas as potential weaknesses:</p>
<dl class="docutils">
<dt><strong>Primitive data types</strong></dt>
<dd>
<p class="first">A programmer can pretty much get away never knowing how a number works in Python, since you typically overflow to appropriately sized data types automatically.</p>
<p class="last">The candidate needs to know what <a class="reference external" href="http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html">all the Java primitives</a> are when the names are provided to them, and must be able to describe why you would choose to use one over another. Knowing pass-by-value versus pass-by-reference is a plus. In Python there is a somewhat similar distinction between mutable and immutable types &#8212; if they understand the subtleties of identifier binding, learning by-ref versus by-value will be a cinch. If they don&#8217;t know either, I&#8217;ll be worried.</p>
</dd>
<dt><strong>Object oriented design</strong></dt>
<dd>
<p class="first">The candidate&#8217;s Python background must not be entirely procedural, or they won&#8217;t fare well in a Java environment (which forces object orientation). Additionally, this would indicate that they probably haven&#8217;t done much design work: even if they&#8217;re an object-orientation iconoclast, they have to know what they&#8217;re rebelling against and why.</p>
<p>They need to know:</p>
<ul class="simple">
<li>When polymorphism is appropriate.</li>
<li>What should be exposed from an encapsulation perspective.</li>
<li>What the benefits of interfaces are (in a statically typed, single-inheritance language).</li>
</ul>
<p class="last">Basically, if they don&#8217;t know the fundamentals of object oriented design, I&#8217;ll assume they&#8217;ve only ever written &quot;scripts,&quot; by which I mean, &quot;Small, unimportant code that glues the I/O of several real applications together.&quot; I don&#8217;t use the term lightly.</p>
</dd>
<dt><strong>Unit testing</strong></dt>
<dd>
<p class="first">If they&#8217;ve been writing real-world Python without a single unit test or doctest, they&#8217;ve been Doing it Wrong (TM).</p>
<p class="last"><tt class="docutils literal"><span class="pre">unittest</span></tt> is purposefully modeled on xUnit. They may have to learn the new jUnit 4 decorator syntax when they start work, but they should be able to claim they&#8217;ve worked with a jUnit 3 -like API.</p>
</dd>
<dt><strong>Abstract data structures</strong></dt>
<dd>
<p class="first">Python has tuples, lists and dictionaries &#8212; all polymorphic containers &#8212; and they&#8217;ll do everything that your programmer heart desires. <a class="footnote-reference" href="#id18" id="id17"><tt>[§]</tt></a> Some other languages don&#8217;t have such nice abstractions.</p>
<p>It&#8217;d be awesome if they knew:</p>
<ul class="simple">
<li>The difference between injective and bijective and how those terms are important to hash function design. If they can tell me this, I&#8217;ll let them write my high-performance hash functions.</li>
</ul>
<p>They must know (in ascending importance):</p>
<ul class="simple">
<li>The difference between a <a class="reference external" href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/HashMap.html">HashMap</a> and a <a class="reference external" href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/TreeMap.html">TreeMap</a>.</li>
<li>The difference between a vector and a linked list, or when one should preferred over the other.  The names are unimportant &#8212; I&#8217;d clarify that a vector was a dynamically growing array.</li>
<li>The &quot;difference&quot; between a tree and a graph.</li>
</ul>
<p>Turning attention to you, the reader: if you&#8217;re lacking in data structures knowledge, I recommend you read a data structures book and actually implement the data structures. Then, take a few minutes to figure out where you&#8217;d actually use them in an application. They stick in your head fairly well once you&#8217;ve implemented them once.</p>
<p class="last">Some interviewers will ask stupid questions like how to implement sorting algorithms. Again, just pick up a data structures book and implement them once, and you&#8217;ll get the gist. Refresh yourself before the interview, because these are a silly favorite &#8212; <a class="reference external" href="http://en.wikipedia.org/wiki/Qsort_%28C_standard_library%29">very few people have to implement sorting functions anymore</a>.</p>
</dd>
<dt><strong>Design patterns</strong></dt>
<dd>
<p class="first">Design patterns serve several purposes:</p>
<ul class="simple">
<li>They establish a common language for communicating proposed solutions to commonly found problems.</li>
<li>They prevent developers for inventing stupid solutions to a solved class of problems.</li>
<li>They contain a suite of workarounds for inflexibilities in statically typed languages.</li>
</ul>
<p>I would want to assure myself that you had an appropriate knowledge of relevant design patterns. More important than the names: if I describe them to you, will you recognize them and their useful applications?</p>
<p class="last">For example, have you ever used the observer pattern? Adapter pattern? Proxying? Facade? You almost certainly had to use all of those if you&#8217;ve done major design work in Python.</p>
</dd>
<dt><strong>Background concepts</strong></dt>
<dd>
<p class="first">These are some things that I would feel extra good about if the candidate knew and could accurately describe how they relate to their Python analogs:</p>
<ul class="last simple">
<li>The importance of string builders (Python list joining idiom)</li>
<li>Basic idea of how I/O streams work (Python <tt class="docutils literal"><span class="pre">file</span></tt>s under the hood)</li>
<li>Basic knowledge of typecasting (Python has implicit polymorphism)</li>
</ul>
</dd>
</dl>
</div>
<div class="section" id="practical-advice">
<h3>Practical advice</h3>
<p>Some (bad) interviewers just won&#8217;t like you because you don&#8217;t know their favorite language. If you&#8217;re interviewing for a position that&#8217;s likely to be Java oriented, find the easiest IDE out there and write an application in it for fun. Try porting a Python application you wrote and see how the concepts translate &#8212; that&#8217;s often an eye-opener. Or <a class="reference external" href="http://en.wikipedia.org/wiki/Kata_%28programming%29">katas</a>!</p>
<p>If you find yourself unawares in an interview with these &quot;language crusaders,&quot; there&#8217;s nothing you can do but <strong>show that you have the capacity to learn their language in the few weeks vacation you have before you start</strong>. If it makes you feel better, keep a mental map from languages to number of jerks you&#8217;ve encountered &#8212; even normalizing by developer-base size the results can be surprising. ;-)</p>
</div>
<div class="section" id="footnotes">
<h3>Footnotes</h3>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id3"><tt>[*]</tt></a></td>
<td>Frequently <em>unncessary</em> terminology, often trending towards hot enterprise jargon, since that&#8217;s what nets the most jobs and grant money.</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id8" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id7"><tt>[†]</tt></a></td>
<td>Dynamic typing proponents are quick to point out that this doesn&#8217;t prevent flaws in reasoning, which are the more difficult class of errors, and that you&#8217;ll end up writing tests for these anyway.</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id14" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id13"><tt>[‡]</tt></a></td>
<td>Clearly candidates could exploit a vulnerability in my interview protocol: leave off things they know I&#8217;m likely to test that they know particularly well; however, I generally ask them to stop after I&#8217;m satisfied they know something. Plus, the less I know about their other weaknesses the more unsure I am about them, and thus the less likely I am to recommend them.</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id18" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id17"><tt>[§]</tt></a></td>
<td>Though not necessarily in a performant way; i.e. note the existence of <tt class="docutils literal"><span class="pre">collections.deque</span></tt> and <tt class="docutils literal"><span class="pre">bisect</span></tt>. Knowing Python, I&#8217;d quiz the candidate to see if they knew of the performant datatypes.</td>
</tr>
</tbody>
</table>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.cdleary.com/2009/10/why-you-should-bother/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Eliminating web service dependencies with a language-specific abstraction barrier</title>
		<link>http://blog.cdleary.com/2009/04/eliminating-web-service-dependencies-with-a-language-specific-abstraction-barrier/</link>
		<comments>http://blog.cdleary.com/2009/04/eliminating-web-service-dependencies-with-a-language-specific-abstraction-barrier/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 16:00:36 +0000</pubDate>
		<dc:creator>cdleary</dc:creator>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[The Web]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Data Structures]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Encapsulation]]></category>
		<category><![CDATA[Gentlemen's Privacy]]></category>
		<category><![CDATA[Indirection]]></category>
		<category><![CDATA[Pragmatic Programming]]></category>
		<category><![CDATA[Problem Domain]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[WSDL]]></category>

		<guid isPermaLink="false">http://blog.cdleary.com/?p=473</guid>
		<description><![CDATA[Hyperbolic analogy: Saying, "You shouldn't need to wrap the web service interface, because it already provides an API," is like saying, "You shouldn't need different programming languages, because they're all Turing complete." [...]]]></description>
			<content:encoded><![CDATA[<p>Hyperbolic analogy: Saying, &#8220;You shouldn&#8217;t need to wrap the web service interface, because it already provides an API,&#8221; is like saying, &#8220;You shouldn&#8217;t need different programming languages, because they&#8217;re all Turing complete.&#8221;</p>
<p>Web services tend to deliver <em>raw data</em> payloads from a flat interface and thus lack the usability of native language APIs. Inevitably, <strong>when you program RPC-like interfaces for no language in particular, you incur incompatibilities for every <em>particular</em> language&#8217;s best practices, idioms, and data models</strong>. <tt>[*]</tt> The issue of appropriately representing exceptions and/or error codes in RPC-like services is a notorious example of this.</p>
<p>There are additional specification mechanisms like <a href="http://en.wikipedia.org/wiki/Web_Services_Description_Language#Example_WSDL_file">WSDL</a> <tt>[@]</tt> that allow us to make the payloads more object-like. Additional structure is indicated through the use of user-defined &#8220;complex types,&#8221; but this only gets you part of the way to a usable API for any given language. In Python, it&#8217;s a lot more sensible to perform an operation like in the following abstraction:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> internal_tracker.<span style="color: black;">service</span> <span style="color: #ff7700;font-weight:bold;">import</span> InternalTracker
bug_serivce = InternalTracker<span style="color: black;">&#40;</span>username=<span style="color: #dc143c;">getpass</span>.<span style="color: black;">getuser</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
    password=<span style="color: #dc143c;">getpass</span>.<span style="color: #dc143c;">getpass</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
bug = bug_service.<span style="color: black;">get_bug</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">123456</span><span style="color: black;">&#41;</span>
bug.<span style="color: black;">actionable</span>.<span style="color: black;">add</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Chris Leary'</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># may raise ReadOnlyException</span>
comment = Comment<span style="color: black;">&#40;</span>text=<span style="color: #483d8b;">'Adding self to actionable'</span><span style="color: black;">&#41;</span>
bug.<span style="color: black;">arbs</span>.<span style="color: black;">add_comment</span><span style="color: black;">&#40;</span>comment<span style="color: black;">&#41;</span>
bug.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># may raise instanceof ServiceWriteException</span></pre></div></div>

<p>Than to use an external web service API solution directly (despite using the excellent <a href='https://fedorahosted.org/suds/'>Suds library</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># Boilerplate</span>
client = suds.<span style="color: black;">client</span>.<span style="color: black;">Client</span><span style="color: black;">&#40;</span>wsdl=wsdl_uri<span style="color: black;">&#41;</span>
security = suds.<span style="color: black;">wsse</span>.<span style="color: black;">Security</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
security.<span style="color: black;">tokens</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>UsernameToken<span style="color: black;">&#40;</span><span style="color: #dc143c;">getpass</span>.<span style="color: black;">getuser</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
    <span style="color: #dc143c;">getpass</span>.<span style="color: #dc143c;">getpass</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
client.<span style="color: black;">set_options</span><span style="color: black;">&#40;</span>wsse=security<span style="color: black;">&#41;</span>
internal_tracker_service = client.<span style="color: black;">service</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Usage</span>
service_bug = internal_tracker_service.<span style="color: black;">GetBug</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">123456</span><span style="color: black;">&#41;</span>
service_bug.<span style="color: black;">actionable</span> += <span style="color: #483d8b;">', Chris Leary'</span>
<span style="color: #808080; font-style: italic;"># Do we check the response for all WebFault exceptions?</span>
<span style="color: #808080; font-style: italic;"># (Do we check for and handle all the possible transport issues?)</span>
internal_tracker_service.<span style="color: black;">UpdateBug</span><span style="color: black;">&#40;</span>service_bug<span style="color: black;">&#41;</span>
Comment = internal_tracker_service.<span style="color: black;">factory</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'Comment'</span><span style="color: black;">&#93;</span>
comment = Comment<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
comment.<span style="color: black;">BugId</span> = service_bug.<span style="color: black;">Id</span>
comment.<span style="color: black;">Text</span> = <span style="color: #483d8b;">'Adding self to actionable'</span>
<span style="color: #808080; font-style: italic;"># Again, what should we check?</span>
internal_tracker_service.<span style="color: black;">AddComment</span><span style="color: black;">&#40;</span>comment<span style="color: black;">&#41;</span></pre></div></div>

<h3>Why is it good to have the layer of indirection?</h3>
<p>Lemma 1: The former example <strong>actually reads like Python code</strong>. It raises problem-domain-relevant exceptions, uses keyword arguments appropriately, follows language naming conventions, and uses sensible language-specific data types that may be poorly represented in the web service. For example, <tt>actionable</tt> may be a big comma-delimited string according to the service, whereas it should clearly be modeled as a set of (unique) names, using Python&#8217;s <tt>set</tt> data type. Another example is <tt>BigInteger</tt>s being poorly represented as strings in order to keep the API language-neutral.</p>
<p>Lemma 2: The layer <strong>represents an extremely maintainable abstraction barrier</strong> between the client and the backing service. Should a team using the abstraction decide it&#8217;s prudent to switch to, say, Bugzilla, I would have no trouble writing a port for the backing service in which all client code would continue to work. Another example is a scenario in which we determine that the transport is unreliable for some reason, so decide all requests should be retried three times instead of one. <tt>[!]</tt> How many places will I need to make changes? How many client code bases do I potentially need to keep track of?</p>
<h3>Why is it risky to use the web service interface?</h3>
<p>If the web service API represents the problem domain correctly with constructs that make sense for your language, it&#8217;s fine to use directly. (As long as you&#8217;re confident you won&#8217;t have transport-layer issues.) If you&#8217;re near-certain that the backing service <em>will not change</em>, and/or you&#8217;re willing to risk all the client code that will depend on that API directly being instantaneously broken, it&#8217;s fine. The trouble occurs when one of these is not the case.</p>
<p>Let&#8217;s say that the backing service <em>does</em> change to Bugzilla. Chances are that <strong>hacking in adapter classes for the new service would be a horrible upgrade experience</strong> that entails:</p>
<ol>
<li>Repeated discovery of <a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html">leaky abstractions</a>,</li>
<li>Greater propensity to bugs, <tt>[^]</tt> and
<li>More difficult maintenance going forward.
</ol>
<p>Client code that is tightly coupled to the service API would force a rewrite in order to avoid these issues.</p>
<p><a href="http://www.pragprog.com/">Pragmatic Programming</a> says to <em>rely on reliable things</em>, which is a rule that any reasonable person will agree with. <tt>[&amp;]</tt> The abstraction barrier is reliable in its loose coupling (direct modeling of the problem domain), whereas direct use of the web service API could force a reliance on quirky external service facts, perhaps deep into client code.</p>
<h3>Is there room for compromise?</h3>
<p>This is the point in the discussion where we think something along the lines of, &#8220;Well, I can just fix the quirky things with a bunch of shims between my code and the service itself.&#8221; At that point, I contend, you&#8217;re really just implementing a half-baked version of the language-specific API. It&#8217;s better to make the abstractions appropriate for the target language and problem domain the <em>first time</em> around than by incrementally adding shims and hoping client code didn&#8217;t use the underlying quirks before you got to them. Heck, if the web service is extremely well suited to your language, you&#8217;ll end up <a href="http://en.wikipedia.org/wiki/Proxy_pattern">proxying</a> most of the time anyway, and the development will be relatively effortless. <tt>[$]</tt></p>
<h3>What about speed of deployment?</h3>
<p><em>If we have language-specific APIs, won&#8217;t there be additional delay waiting for it to update when additional capabilities are added to the backing service?</em></p>
<p>First of all, if the new capability is not within the problem domain of the library, it should be a separate API. This is the <a href='http://en.wikipedia.org/wiki/Single_responsibility_principle'>single responsibility principle</a> applied to interfaces &#8212; you should be programming to an interface abstraction. Just because a backing service has a hodgepodge of responsibilities doesn&#8217;t mean that our language-specific API should as well. In fact, it probably shouldn&#8217;t. Let&#8217;s assume it <em>is</em> in the problem domain.</p>
<p>If the functionality is sane and ready for use in the target language, it should be really simple for the library owner to extend the language-specific API. In fact, if you&#8217;re using the proxy pattern, you may not have to do anything at all. Let&#8217;s assume that the functionality is <em>quirky</em> and you&#8217;re blocked waiting for the library owner to update with the language-specific shim, because it&#8217;s non-trivial.</p>
<p>Now our solution tends to vary based on the language. Languages like Python have what&#8217;s known as &#8220;gentlemen&#8217;s privacy&#8221;, based on the notion of a <a href='http://en.wikipedia.org/wiki/Gentlemen%27s_agreement'>gentlemen&#8217;s agreement</a>. Privacy constraints are not enforced at compile-time and/or run-time, so you can just reach through the abstraction barrier if you believe you know what you&#8217;re doing. Yes, you&#8217;re making an informed decision to violate encapsulation. Cases like this are exactly when it comes in handy.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>bug_service, <span style="color: #483d8b;">'super_new_method_we_need'</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># HACK: Violate abstraction -- we need this new capability right now</span>
<span style="color: #808080; font-style: italic;"># and Billy-Bo, the library owner, is swamped!</span>
suds_client = bug_service._suds_client
result = suds_client.<span style="color: black;">SuperNewMethodWeNeed</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
target_result = de_quirkify<span style="color: black;">&#40;</span>result<span style="color: black;">&#41;</span></pre></div></div>

<p>As you can see, we end up implementing the method <tt>de_quirkify</tt> to de-quirk the quirky web service result into a more language-specific data model &#8212; it&#8217;s bad form to make the code dependent on the web service&#8217;s quirky output form. We then submit our code for this method to the library owner and suggest that they use it as a basis for their implementation, so that a) they can get it done faster, and b) we can seamlessly factor the hack out.</p>
<p>For privacy-enforcing languages, you would need to expose a public API for getting at the private service, then tell people not to use it unless they know what they&#8217;re doing. As you can tell, you pretty much wind up with gentlemen&#8217;s privacy on that interface, anyway.</p>
<h3>Footnotes</h3>
<p><tt>[*]</tt> In EE we call this kind of phenomenon an <a href="http://en.wikipedia.org/wiki/Impedance_mismatch">impedance mismatch</a>, which results in power loss.<br />
<tt>[@]</tt> And many others, with <a href="http://xmlsucks.org/but_you_have_to_use_it_anyway/">few successful ones</a>.<br />
<tt>[!]</tt> Or maybe we want to switch from HTTP transport to SMTP. Yes, this is actually possible. :-)<br />
<tt>[^]</tt> In duplicating exact web service behaviors &#8212; you have to be backwards compatible with whichever behaviors the existing client code relies on.<br />
<tt>[&amp;]</tt> It&#8217;s a syntactic tautology. The caveat is that reasonable people will almost certainly quibble over the classification of <em>what&#8217;s</em> reliable.<br />
<tt>[$]</tt> At least in Python or other languages with a good degree of dynamism, it will.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cdleary.com/2009/04/eliminating-web-service-dependencies-with-a-language-specific-abstraction-barrier/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
