<?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>OhPauleez // Paul deGrandis</title>
	<atom:link href="http://www.pauldee.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pauldee.org/blog</link>
	<description>Pushing the proverbial technology envelope</description>
	<lastBuildDate>Mon, 04 Mar 2013 17:49:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>ClojureScript and Node.js &#8211; an experience report</title>
		<link>http://www.pauldee.org/blog/2012/clojurescript-and-node-js-an-experience-report/</link>
		<comments>http://www.pauldee.org/blog/2012/clojurescript-and-node-js-an-experience-report/#comments</comments>
		<pubDate>Fri, 26 Oct 2012 23:50:05 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[ClojureScript]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=431</guid>
		<description><![CDATA[ClojureScript on Node.js is a (potentially) compelling story for writing scripting apps with Clojure. I am just now finishing up the first of a handful of example apps to help tease out the approach, tooling, and ClojureScript patches needed to make Clojure a viable option in this regard. git-ttt git-ttt is a git-backed, text-based, ticket [...]]]></description>
			<content:encoded><![CDATA[<p>ClojureScript on Node.js is a (potentially) compelling story for writing scripting apps with Clojure.</p>
<p>I am just now finishing up the first of a handful of example apps to help tease out the approach, tooling, and ClojureScript patches needed to make Clojure a viable option in this regard.</p>
<h2>git-ttt</h2>
<p>git-ttt is a git-backed, text-based, ticket tracker written in ClojureScript, making use of EDN as the storage format, supporting datalog-like query driven by core.logic, running on Node.js.  I pushed an <a href="https://github.com/ohpauleez/ttt">early glimpse</a> of it to github and published an <a href="http://www.pauldee.org/TTT-Intro.mov">intro screencast</a> to allow those that are curious to see it in action.</p>
<p>Two interesting pieces of the project are its use of protocols and the approach to avoiding constant callbacks.</p>
<h3>Protocols</h3>
<p>&#8220;Program to an interface, never to an implementation.&#8221; and &#8220;Favor composition over inheritance.&#8221;  &#8211; Gang of Four</p>
<p>Protocols enable developers to open their systems for extension, while also allowing others to compose targeted functionality ala carte.  Shoreleave&#8217;s pubsub abstractions and git-ttt&#8217;s search abstraction are two concrete examples to see these benefits.  In Shoreleave, one can extend the full functionality of the pubsub to any object in ClojureScript<sup><a href="http://www.pauldee.org/blog/2012/clojurescript-and-node-js-an-experience-report/#footnote_0_431" id="identifier_0_431" class="footnote-link footnote-identifier-link" title="By default Shoreleave extends the abstraction to functions and atoms, allowing construction of reactive dataflows">1</a></sup> and extend the pubsub bus abstraction to any implementation.  Participation in this system is open to all, from all directions.</p>
<p>In TTT, the search protocol specifies a function to compare two attributes, while falling back on equality in the default case.  This allows plugins to extend search functionality and behavior.</p>
<h3>Blocking Deref</h3>
<p>One challenge when working with ClojureScript is staying true to Clojure style and programming with values, while also conforming to JavaScript&#8217;s callbacks.  One strategy in the browser is isolating those cases and placing them at the end of a threading macro.  Node rests its foundation on callbacks, so a strategy built around promises becomes useful.</p>
<p>Promises within JavaScript provide freedom from the constant callback concern, enable proper exception handling within the context of the exception, return the programmer to focusing on values, and allow for styling and composing ClojureScript like traditional Clojure code.  The pattern I&#8217;ve fallen back on is a combination of dynamic vars, promises, and a function called blocking-deref.</p>
<p>Scripting applications usually have some global constants (for example a file path string), which you might need to set from an external system call.  A more concrete example- TTT needs to know some of the user&#8217;s git settings, which are fetched with the git command via Node&#8217;s system exec call.  The result (a map of git config keys to their values) is bound to a dynamic var and the rest of code is written against that dynamic var.  To actually get that result though, we use an atom, a promise, and the threading macro.</p>
<p>First we write the system call to git in a standard callback style, except an atom will contain the eventual result.</p>
<div id="gist3962043" class="gist">
      <div class="gist-file">
        <div class="gist-data gist-syntax">



  <div class="file-data">
    <table cellpadding="0" cellspacing="0" class="lines highlight">
      <tr>
        <td class="line-numbers">
          <span class="line-number" id="file-gitcore-cljs-L1" rel="file-gitcore-cljs-L1">1</span>
          <span class="line-number" id="file-gitcore-cljs-L2" rel="file-gitcore-cljs-L2">2</span>
          <span class="line-number" id="file-gitcore-cljs-L3" rel="file-gitcore-cljs-L3">3</span>
          <span class="line-number" id="file-gitcore-cljs-L4" rel="file-gitcore-cljs-L4">4</span>
          <span class="line-number" id="file-gitcore-cljs-L5" rel="file-gitcore-cljs-L5">5</span>
          <span class="line-number" id="file-gitcore-cljs-L6" rel="file-gitcore-cljs-L6">6</span>
          <span class="line-number" id="file-gitcore-cljs-L7" rel="file-gitcore-cljs-L7">7</span>
          <span class="line-number" id="file-gitcore-cljs-L8" rel="file-gitcore-cljs-L8">8</span>
          <span class="line-number" id="file-gitcore-cljs-L9" rel="file-gitcore-cljs-L9">9</span>
          <span class="line-number" id="file-gitcore-cljs-L10" rel="file-gitcore-cljs-L10">10</span>
          <span class="line-number" id="file-gitcore-cljs-L11" rel="file-gitcore-cljs-L11">11</span>
        </td>
        <td class="line-data">
          <pre class="line-pre"><div class="line" id="file-gitcore-cljs-LC1"><span class="p">(</span><span class="kd">defn </span><span class="nv">git-config-atom</span></div><div class="line" id="file-gitcore-cljs-LC2">  <span class="s">&quot;Call the `git config` command to grab the value of a given key.</span></div><div class="line" id="file-gitcore-cljs-LC3"><span class="s">Return an atom that will hold the return/output string in a map {k output-value}.</span></div><div class="line" id="file-gitcore-cljs-LC4"><span class="s">Optionally pass in an atom (allowing you to build up many returns)&quot;</span></div><div class="line" id="file-gitcore-cljs-LC5">  <span class="p">([</span><span class="nv">k</span><span class="p">]</span></div><div class="line" id="file-gitcore-cljs-LC6">   <span class="p">(</span><span class="nf">git-config-atom</span> <span class="nv">k</span> <span class="p">(</span><span class="nf">atom</span> <span class="p">{})))</span></div><div class="line" id="file-gitcore-cljs-LC7">  <span class="p">([</span><span class="nv">k</span> <span class="nv">ret</span><span class="p">]</span></div><div class="line" id="file-gitcore-cljs-LC8">   <span class="p">(</span><span class="k">do </span><span class="p">(</span><span class="nf">sys-exec</span> <span class="p">(</span><span class="nb">str </span><span class="s">&quot;git config --get &quot;</span> <span class="p">(</span><span class="nb">name </span><span class="nv">k</span><span class="p">))</span></div><div class="line" id="file-gitcore-cljs-LC9">                 <span class="p">(</span><span class="k">fn </span><span class="p">[</span><span class="nv">_</span> <span class="nv">out</span> <span class="nv">_</span><span class="p">]</span></div><div class="line" id="file-gitcore-cljs-LC10">                   <span class="p">(</span><span class="nf">swap!</span> <span class="nv">ret</span> <span class="nb">assoc </span><span class="p">(</span><span class="nb">keyword </span><span class="nv">k</span><span class="p">)</span> <span class="p">(</span><span class="nf">cstr/trim</span> <span class="nv">out</span><span class="p">))))</span></div><div class="line" id="file-gitcore-cljs-LC11">   <span class="nv">ret</span><span class="p">)))</span></div></pre>
        </td>
      </tr>
    </table>
  </div>

        </div>

        <div class="gist-meta">
          <a href="https://gist.github.com/ohpauleez/3962043/raw/e8519f1158e07dd1d3b4d53e7bb0a1344221a24f/gitcore.cljs" style="float:right">view raw</a>
          <a href="https://gist.github.com/ohpauleez/3962043#file-gitcore-cljs" style="float:right; margin-right:10px; color:#666;">gitcore.cljs</a>
          <a href="https://gist.github.com/ohpauleez/3962043">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
        </div>
      </div>
</div>

<p>Multiple requests are threaded, passing the atom along and building up the data.</p>
<div id="gist3962043" class="gist">
      <div class="gist-file">
        <div class="gist-data gist-syntax">



  <div class="file-data">
    <table cellpadding="0" cellspacing="0" class="lines highlight">
      <tr>
        <td class="line-numbers">
          <span class="line-number" id="file-configmap-cljs-L1" rel="file-configmap-cljs-L1">1</span>
          <span class="line-number" id="file-configmap-cljs-L2" rel="file-configmap-cljs-L2">2</span>
          <span class="line-number" id="file-configmap-cljs-L3" rel="file-configmap-cljs-L3">3</span>
          <span class="line-number" id="file-configmap-cljs-L4" rel="file-configmap-cljs-L4">4</span>
          <span class="line-number" id="file-configmap-cljs-L5" rel="file-configmap-cljs-L5">5</span>
          <span class="line-number" id="file-configmap-cljs-L6" rel="file-configmap-cljs-L6">6</span>
          <span class="line-number" id="file-configmap-cljs-L7" rel="file-configmap-cljs-L7">7</span>
          <span class="line-number" id="file-configmap-cljs-L8" rel="file-configmap-cljs-L8">8</span>
          <span class="line-number" id="file-configmap-cljs-L9" rel="file-configmap-cljs-L9">9</span>
        </td>
        <td class="line-data">
          <pre class="line-pre"><div class="line" id="file-configmap-cljs-LC1"><span class="c1">;; This is the direct Result object you can use to access</span></div><div class="line" id="file-configmap-cljs-LC2"><span class="c1">;; a git config map</span></div><div class="line" id="file-configmap-cljs-LC3"><span class="p">(</span><span class="k">def </span><span class="nv">git-config-res</span></div><div class="line" id="file-configmap-cljs-LC4">  <span class="p">(</span><span class="k">let </span><span class="p">[</span><span class="nv">res</span> <span class="p">(</span><span class="nf">goog.result.SimpleResult.</span><span class="p">)]</span></div><div class="line" id="file-configmap-cljs-LC5">    <span class="p">(</span><span class="nf">-&gt;&gt;</span></div><div class="line" id="file-configmap-cljs-LC6">      <span class="p">(</span><span class="nf">git-config-atom</span> <span class="s">&quot;user.email&quot;</span><span class="p">)</span></div><div class="line" id="file-configmap-cljs-LC7">      <span class="p">(</span><span class="nf">git-config-atom</span> <span class="s">&quot;user.name&quot;</span><span class="p">)</span></div><div class="line" id="file-configmap-cljs-LC8">      <span class="p">((</span><span class="k">fn </span><span class="p">[</span><span class="nv">a</span><span class="p">]</span> <span class="p">(</span><span class="nf">blocking-deref</span> <span class="nv">a</span> <span class="nv">res</span> <span class="o">#</span><span class="p">(</span><span class="nb">&lt; </span><span class="p">(</span><span class="nb">count </span><span class="nv">%</span><span class="p">)</span> <span class="mi">2</span><span class="p">)))))</span></div><div class="line" id="file-configmap-cljs-LC9">    <span class="nv">res</span><span class="p">))</span></div></pre>
        </td>
      </tr>
    </table>
  </div>

        </div>

        <div class="gist-meta">
          <a href="https://gist.github.com/ohpauleez/3962043/raw/89df7981c3c3c041174f10af8633c66d80fdaeab/configmap.cljs" style="float:right">view raw</a>
          <a href="https://gist.github.com/ohpauleez/3962043#file-configmap-cljs" style="float:right; margin-right:10px; color:#666;">configmap.cljs</a>
          <a href="https://gist.github.com/ohpauleez/3962043">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
        </div>
      </div>
</div>

<p>A promise awaits the values in the atom.  Blocking-deref just ticks away Node&#8217;s internal process until the promise is fulfilled.</p>
<div id="gist3962043" class="gist">
      <div class="gist-file">
        <div class="gist-data gist-syntax">



  <div class="file-data">
    <table cellpadding="0" cellspacing="0" class="lines highlight">
      <tr>
        <td class="line-numbers">
          <span class="line-number" id="file-blockingderef-cljs-L1" rel="file-blockingderef-cljs-L1">1</span>
          <span class="line-number" id="file-blockingderef-cljs-L2" rel="file-blockingderef-cljs-L2">2</span>
          <span class="line-number" id="file-blockingderef-cljs-L3" rel="file-blockingderef-cljs-L3">3</span>
          <span class="line-number" id="file-blockingderef-cljs-L4" rel="file-blockingderef-cljs-L4">4</span>
          <span class="line-number" id="file-blockingderef-cljs-L5" rel="file-blockingderef-cljs-L5">5</span>
          <span class="line-number" id="file-blockingderef-cljs-L6" rel="file-blockingderef-cljs-L6">6</span>
          <span class="line-number" id="file-blockingderef-cljs-L7" rel="file-blockingderef-cljs-L7">7</span>
          <span class="line-number" id="file-blockingderef-cljs-L8" rel="file-blockingderef-cljs-L8">8</span>
          <span class="line-number" id="file-blockingderef-cljs-L9" rel="file-blockingderef-cljs-L9">9</span>
          <span class="line-number" id="file-blockingderef-cljs-L10" rel="file-blockingderef-cljs-L10">10</span>
          <span class="line-number" id="file-blockingderef-cljs-L11" rel="file-blockingderef-cljs-L11">11</span>
        </td>
        <td class="line-data">
          <pre class="line-pre"><div class="line" id="file-blockingderef-cljs-LC1"><span class="p">(</span><span class="kd">defn </span><span class="nv">blocking-deref</span></div><div class="line" id="file-blockingderef-cljs-LC2">  <span class="s">&quot;Given an atom and a Result object, attempt to cycle the process tick on derefing until `pred-fn` isn&#39;t true</span></div><div class="line" id="file-blockingderef-cljs-LC3"><span class="s">By default, `pred-fn` is nil?</span></div><div class="line" id="file-blockingderef-cljs-LC4"><span class="s">Once the condition doesn&#39;t hold, the Result will be set to @a, and @a is returned&quot;</span></div><div class="line" id="file-blockingderef-cljs-LC5">  <span class="p">([</span><span class="nv">a</span> <span class="nv">r</span><span class="p">]</span></div><div class="line" id="file-blockingderef-cljs-LC6">   <span class="p">(</span><span class="nf">blocking-deref</span> <span class="nv">a</span> <span class="nv">r</span> <span class="nv">nil?</span><span class="p">))</span></div><div class="line" id="file-blockingderef-cljs-LC7">  <span class="p">([</span><span class="nv">a</span> <span class="nv">r</span> <span class="nv">pred-fn</span><span class="p">]</span></div><div class="line" id="file-blockingderef-cljs-LC8">   <span class="p">(</span><span class="k">if </span><span class="p">(</span><span class="nf">pred-fn</span> <span class="o">@</span><span class="nv">a</span><span class="p">)</span></div><div class="line" id="file-blockingderef-cljs-LC9">     <span class="p">(</span><span class="nf">node/process.nextTick</span> <span class="o">#</span><span class="p">(</span><span class="nf">blocking-deref</span> <span class="nv">a</span> <span class="nv">r</span> <span class="nv">pred-fn</span><span class="p">))</span></div><div class="line" id="file-blockingderef-cljs-LC10">     <span class="p">(</span><span class="k">do </span><span class="p">(</span><span class="nf">.setValue</span> <span class="nv">r</span> <span class="o">@</span><span class="nv">a</span><span class="p">)</span></div><div class="line" id="file-blockingderef-cljs-LC11">       <span class="o">@</span><span class="nv">a</span><span class="p">))))</span></div></pre>
        </td>
      </tr>
    </table>
  </div>

        </div>

        <div class="gist-meta">
          <a href="https://gist.github.com/ohpauleez/3962043/raw/b0cc2de9f6fda70b2a98121a881286107a8c8da5/blockingderef.cljs" style="float:right">view raw</a>
          <a href="https://gist.github.com/ohpauleez/3962043#file-blockingderef-cljs" style="float:right; margin-right:10px; color:#666;">blockingderef.cljs</a>
          <a href="https://gist.github.com/ohpauleez/3962043">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
        </div>
      </div>
</div>

<p>This overall approach is similar in notion to how transients work.  From a top-level, the value of the promises set the dynamic vars or are passed in before kicking off the main application loop.</p>
<div id="gist3962043" class="gist">
      <div class="gist-file">
        <div class="gist-data gist-syntax">



  <div class="file-data">
    <table cellpadding="0" cellspacing="0" class="lines highlight">
      <tr>
        <td class="line-numbers">
          <span class="line-number" id="file-main-cljs-L1" rel="file-main-cljs-L1">1</span>
          <span class="line-number" id="file-main-cljs-L2" rel="file-main-cljs-L2">2</span>
          <span class="line-number" id="file-main-cljs-L3" rel="file-main-cljs-L3">3</span>
          <span class="line-number" id="file-main-cljs-L4" rel="file-main-cljs-L4">4</span>
          <span class="line-number" id="file-main-cljs-L5" rel="file-main-cljs-L5">5</span>
          <span class="line-number" id="file-main-cljs-L6" rel="file-main-cljs-L6">6</span>
          <span class="line-number" id="file-main-cljs-L7" rel="file-main-cljs-L7">7</span>
        </td>
        <td class="line-data">
          <pre class="line-pre"><div class="line" id="file-main-cljs-LC1"><span class="p">(</span><span class="kd">defn </span><span class="nv">-main</span> <span class="p">[</span><span class="o">&amp;</span> <span class="nv">args</span><span class="p">]</span></div><div class="line" id="file-main-cljs-LC2">  <span class="p">(</span><span class="k">let </span><span class="p">[</span><span class="nv">git-root</span> <span class="nv">core/git-root-res</span></div><div class="line" id="file-main-cljs-LC3">        <span class="nv">git-conf</span> <span class="nv">core/git-config-res</span><span class="p">]</span></div><div class="line" id="file-main-cljs-LC4">    <span class="p">(</span><span class="nf">result/wait</span> <span class="nv">git-root</span></div><div class="line" id="file-main-cljs-LC5">      <span class="o">#</span><span class="p">(</span><span class="nb">binding </span><span class="p">[</span><span class="nv">core/*repo-root*</span> <span class="p">(</span><span class="nf">.getValue</span> <span class="nv">git-root</span><span class="p">)]</span></div><div class="line" id="file-main-cljs-LC6">         <span class="p">(</span><span class="nf">result/wait</span> <span class="nv">git-conf</span></div><div class="line" id="file-main-cljs-LC7">           <span class="p">(</span><span class="k">fn </span><span class="p">[]</span> <span class="p">(</span><span class="nf">main-control</span> <span class="nv">git-conf</span> <span class="nv">args</span><span class="p">)))))))</span></div></pre>
        </td>
      </tr>
    </table>
  </div>

        </div>

        <div class="gist-meta">
          <a href="https://gist.github.com/ohpauleez/3962043/raw/fdba25adc1dfd7fccf8d8bd5052762824494917c/main.cljs" style="float:right">view raw</a>
          <a href="https://gist.github.com/ohpauleez/3962043#file-main-cljs" style="float:right; margin-right:10px; color:#666;">main.cljs</a>
          <a href="https://gist.github.com/ohpauleez/3962043">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
        </div>
      </div>
</div>

<p>Scripting Clojure apps on Node.js is a real possibility and a complete pleasure by using the platform (Google Closure), the host (Node.js), and the language cooperatively.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_431" class="footnote">By default Shoreleave extends the abstraction to functions and atoms, allowing construction of reactive dataflows</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2012/clojurescript-and-node-js-an-experience-report/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.pauldee.org/TTT-Intro.mov" length="3601936" type="video/quicktime" />
		</item>
		<item>
		<title>Clojure-powered Startups and the upcoming Conj</title>
		<link>http://www.pauldee.org/blog/2012/clojure-powered-startups-and-the-upcoming-conj/</link>
		<comments>http://www.pauldee.org/blog/2012/clojure-powered-startups-and-the-upcoming-conj/#comments</comments>
		<pubDate>Fri, 26 Oct 2012 21:33:44 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Talks]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=429</guid>
		<description><![CDATA[Earlier in the year I spoke at Clojure/West on &#8220;Clojure-powered Startups.&#8221;  The talk was limited to 25 minutes and sadly was light on supporting data.  The point I really wanted to drive home was a roadmap of successfully adopting Clojure for production work. At the upcoming Conj, I&#8217;ll be speaking about Production ClojureScript &#8211; and [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier in the year I spoke at Clojure/West on &#8220;<a href="http://www.infoq.com/presentations/Clojure-powered-Startups">Clojure-powered Startups</a>.&#8221;  The talk was limited to 25 minutes and sadly was light on supporting data.  The point I really wanted to drive home was a roadmap of successfully adopting Clojure for production work.</p>
<p>At the upcoming <a href="http://clojure-conj.org/">Conj</a>, I&#8217;ll be speaking about Production ClojureScript &#8211; and this time I&#8217;m bringing the data <img src='http://www.pauldee.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2012/clojure-powered-startups-and-the-upcoming-conj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Production ClojureScript</title>
		<link>http://www.pauldee.org/blog/2012/production-clojurescript/</link>
		<comments>http://www.pauldee.org/blog/2012/production-clojurescript/#comments</comments>
		<pubDate>Thu, 21 Jun 2012 15:23:24 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Talks]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=425</guid>
		<description><![CDATA[Last night I presented at ClojureNYC on my experience putting ClojureScript into production. A few have asked for the slides. The presentation discusses some features of Shoreleave, the suite of utilities Tutorspree built up for building ClojureScript apps.  The slides also provide some suggestions on how to build out or structure your ClojureScript applications. Coming [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I presented at ClojureNYC on my experience putting ClojureScript into production.<br />
A few have asked for the <a href="http://pauldee.org/ClojureNYC-Shoreleave.pdf">slides</a>.</p>
<p>The presentation discusses some features of <a href="https://github.com/ohpauleez/shoreleave">Shoreleave</a>, the suite of utilities Tutorspree built up for building ClojureScript apps.  The slides also provide some suggestions on how to build out or structure your ClojureScript applications.</p>
<p>Coming soon are two example apps (one of which was demo&#8217;d during the talk) &#8211; a SOLR-connected CLJS client a TodoMVC example.  Both will come bundled with a teaching/exploration tool (which was also demo&#8217;d last night).</p>
<p>Once the demo apps are done, I&#8217;ll be doing a quick screencast on getting the most out of Shoreleave.</p>
<p>Lastly, thanks to everyone who has help shaped Shoreleave and provided me with feedback.  It&#8217;s all greatly appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2012/production-clojurescript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Culture, Data, Networks, People</title>
		<link>http://www.pauldee.org/blog/2012/culture-data-networks-people/</link>
		<comments>http://www.pauldee.org/blog/2012/culture-data-networks-people/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 01:00:00 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Talks]]></category>
		<category><![CDATA[Useful Tips]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=421</guid>
		<description><![CDATA[I gave a talk a few nights ago, Data, Networks, Culture, Data &#8211; or How to be a total baller when it comes to executing on ideas.  The talk analyzed when I felt like I was making something people wanted and the four common themes in all of those situations: Data, Culture, Networks, People (my [...]]]></description>
			<content:encoded><![CDATA[<p>I gave a talk a few nights ago, <em>Data, Networks, Culture, Data &#8211; or How to be a total baller when it comes to executing on ideas</em>.  The talk analyzed when I felt like <strong>I was making something people wanted</strong> and the four common themes in all of those situations: <a href="http://www.pauldee.org/DataCultureNetworksPeople.pdf">Data, Culture, Networks, People</a> (my slides for the talk)</p>
<p><iframe src="http://www.youtube.com/embed/aw3a-y8EyHs" frameborder="0" width="560" height="315"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2012/culture-data-networks-people/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Grok it, Rock it, Drop it</title>
		<link>http://www.pauldee.org/blog/2012/grok-it-rock-it-drop-it/</link>
		<comments>http://www.pauldee.org/blog/2012/grok-it-rock-it-drop-it/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 07:50:19 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Useful Tips]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=399</guid>
		<description><![CDATA[Quickly evaluating ways to simplify your problem space is an essential problem solving skill.1  However, this is extremely difficult to do in fields where possible solutions are rapidly growing (like software).  To overcome this, I present Grok It, Rock It, Drop It. The goal is simple: Continually be learning something new.  Experiment and explore the [...]]]></description>
			<content:encoded><![CDATA[<p>Quickly evaluating ways to simplify your problem space is an essential problem solving skill.<sup><a href="http://www.pauldee.org/blog/2012/grok-it-rock-it-drop-it/#footnote_0_399" id="identifier_0_399" class="footnote-link footnote-identifier-link" title="This is greatly stressed in Polya&rsquo;s How to Solve It">1</a></sup>  However, this is extremely difficult to do in fields where possible solutions are rapidly growing (like software).  To overcome this, I present <strong>Grok It, Rock It, Drop It</strong>.</p>
<p>The goal is simple: Continually be learning something new.  Experiment and explore the new material or technology.  Integrate the knowledge or technology and use the integration as the platform to launch into a new learning area.  Following these three steps will allow you to quickly evaluate technology and effortlessly adopt it.</p>
<p style="text-align: center;"><a href="http://www.pauldee.org/blog/wp-content/uploads/2012/02/GrokItRockItDropIt.png"><img class="alignnone size-medium wp-image-404" title="GrokItRockItDropIt" src="http://www.pauldee.org/blog/wp-content/uploads/2012/02/GrokItRockItDropIt-300x206.png" alt="" width="300" height="206" /></a></p>
<h2>Grok It</h2>
<p>Continual learning is essential for producing an ideal solution to a problem.  Getting in the habit of constantly reading, discovering, evaluating, and discussing new technologies grows your toolbox of approaches and maps out solution spaces for classes of problems. Deciding what to learn and how much to learn is tricky.  Follow your own curiosity or try <em>Just Enough Learning</em>.<sup><a href="http://www.pauldee.org/blog/2012/grok-it-rock-it-drop-it/#footnote_1_399" id="identifier_1_399" class="footnote-link footnote-identifier-link" title="This term is glommed from the book, Just Enough Software Architecture">2</a></sup><br />
Identify areas of your problem that are high risk (if you get them wrong, your entire solution is guaranteed to fail) and areas of deep impact (where an ideal solution greatly reduces the overall problem).  Spend no more than one hour quickly searching Google, Google Scholar, and tech news resources.  Identify the few ideas, concepts, or tools to <em>Rock</em>.</p>
<h2>Rock It</h2>
<p>Pick the technologies up and USE THEM.  Go beyond recreating an example.  Use the technology to solve a subset or possible subset of your problem.  Your goal should be understanding the benefits, tradeoffs, and limitations to the technology.  This is raw <a href="http://www.pauldee.org/blog/2011/realizing-true-validation-a-follow-up/">validation</a> by means of a prototype.</p>
<h2>Drop It</h2>
<p>Integrate.  Right now, do it.  Integrate the knowledge you gained in better focusing your own approach or integrate the technology.  The more often you integrate smaller pieces that simplify your problem, the quicker you&#8217;ll arrive at an ideal solution.  The natural byproduct of integration is a new perspective to tackle another area in the problem space, launching you back into a phase of learning and exploration.</p>
<ol class="footnotes"><li id="footnote_0_399" class="footnote">This is greatly stressed in Polya&#8217;s <a href="http://www.amazon.com/How-Solve-Aspect-Mathematical-Method/dp/4871878309/ref=sr_1_1?ie=UTF8&amp;qid=1329722751&amp;sr=8-1">How to Solve It</a></li><li id="footnote_1_399" class="footnote">This term is glommed from the book, <a href="http://www.amazon.com/Just-Enough-Software-Architecture-Risk-Driven/dp/0984618104/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1329723183&amp;sr=1-1">Just Enough Software Architecture</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2012/grok-it-rock-it-drop-it/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The power of cultures</title>
		<link>http://www.pauldee.org/blog/2012/the-power-of-cultures/</link>
		<comments>http://www.pauldee.org/blog/2012/the-power-of-cultures/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 18:27:35 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Software Project Management]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=51</guid>
		<description><![CDATA[Our world and behaviors are shaped by the cultures and rules that conform it. 1  The power of people and the culture they embrace are some of the most powerful tools in the software engineer&#8217;s toolbox, and are also the greatest hurdles.  The best solution to any problem is the non-technical solution, that uses the power [...]]]></description>
			<content:encoded><![CDATA[<p>Our world and behaviors are shaped by the cultures and rules that conform it. <sup><a href="http://www.pauldee.org/blog/2012/the-power-of-cultures/#footnote_0_51" id="identifier_0_51" class="footnote-link footnote-identifier-link" title="Much work has gone into studying the network and behavioral effects of populations given different societal inputs.&nbsp; See Networks, Crowds, and Markets by Easley and Kleinberg">1</a></sup>  The power of people and the culture they embrace are some of the most powerful tools in the software engineer&#8217;s toolbox, and are also the greatest hurdles.  The best solution to any problem is the non-technical solution, that uses the power of culture and community to achieve a greater goal.<sup><a href="http://www.pauldee.org/blog/2012/the-power-of-cultures/#footnote_1_51" id="identifier_1_51" class="footnote-link footnote-identifier-link" title="Here I&rsquo;m using powerful in the terms of &ldquo;work effort over time,&rdquo; based on an assumption that social interaction amongst people is solving a specific problem.&nbsp; In the same regards, I&rsquo;m using best to refer the lack of software/hardware/&rdquo;systems&rdquo; engineering in the elegant solution.">2</a></sup></p>
<h2>Engineering Cultures</h2>
<p>There are many examples of the deep impact positive cultures have on their populations, no matter how large or small the population is.  For example, take Do-It-Yourself (DIY)- the culture and camaraderie within it have existed for decades.  It&#8217;s become a way-of-life for some individuals.  The culture is so powerful, it has even been adapted into a personality trait ala <em>I&#8217;m a real do-it-yourself&#8217;er</em>.</p>
<p>Similar effects can be found in technical organizations and even within software projects.  Ruby has had a profound effect on the approach and adoption of software testing.  TDD is the norm for Ruby developers (especially those using Rails), to a degree that wasn&#8217;t previously seen in other languages or projects.  Likewise, I&#8217;d argue that Clojure is causing a &#8220;Thinking&#8221; culture to emerge- where careful, deep, purposeful thought and dissection of the problem space are the first steps of all ideal solutions.</p>
<p>This concept of &#8220;purposeful culture&#8221; can be leveraged to boost your own engineering team.</p>
<h2>A tale of engineering at Etsy</h2>
<p>I credit my experience at Etsy as the first great example of how powerful a team/company culture can be and what results given one.  At the earlier days of Etsy, everyone was more or less equal.  The entire company (at the time I left, 65 employees), was roughly a horizontal organization.  Every idea and criticism was valuable and received the same amount of attention- as long as you had the data to back it up.<br />
We decided as a team (and to some degree, as a family) what was important to us, what we thought we should work towards, and how we should go about doing that.  Employees were valued above everything else.  Being in a room where everyone was a first class employee not only allowed us to get to the winning ideas faster, but made everyone feel important.<br />
<strong>Data and democracy ruled</strong>.</p>
<p>It didn&#8217;t stop there either.  Etsy has continued this tradition of optimizing for the employee and driving all their decisions by real data.  Chad Dickerson sums it up nicely in a <a href="http://codeascraft.etsy.com/2011/06/06/optimizing-for-developer-happiness/">talk he delivered at railsconf</a>.</p>
<h2>Culture&#8217;s effects on process</h2>
<p>Effective process comes from effective cultures, not the other way around.<br />
If you want the best possible process for your team, you must first create a culture where the natural outcome is that process.  Here are some things that worked for Etsy and have continue to work for me as I&#8217;ve built out engineering teams:</p>
<ul>
<li>Strive to be objective, always.</li>
<li>Give everyone access to all points of data</li>
<li>Encourage innovation and create clear paths for bringing the fruits of labor before the group</li>
<li>Drive ownership across everyone</li>
<li>Continual and constant learning</li>
<li>Mistakes are ok, Failures are ok, Adaptation is essential</li>
<li>Ask &#8220;why&#8221; more than &#8220;what&#8221;</li>
</ul>
<ol class="footnotes"><li id="footnote_0_51" class="footnote">Much work has gone into studying the network and behavioral effects of populations given different societal inputs.  See <a href="http://www.amazon.com/Networks-Crowds-Markets-Reasoning-Connected/dp/0521195330/ref=sr_1_1?ie=UTF8&amp;qid=1326305774&amp;sr=8-1">Networks, Crowds, and Markets</a> by Easley and Kleinberg</li><li id="footnote_1_51" class="footnote">Here I&#8217;m using <em>powerful</em> in the terms of &#8220;work effort over time,&#8221; based on an assumption that social interaction amongst people is solving a specific problem.  In the same regards, I&#8217;m using best to refer the lack of software/hardware/&#8221;systems&#8221; engineering in the elegant solution.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2012/the-power-of-cultures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Discussing and evaluating architectures; pt 2</title>
		<link>http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-2/</link>
		<comments>http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-2/#comments</comments>
		<pubDate>Sun, 31 Jul 2011 04:32:13 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Software Architecture]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=348</guid>
		<description><![CDATA[In the last installment of this series, I presented the foundations of software architecture.  To recap, they were Every piece of software has an architecture, whether intentional or not Every architecture is created by at least one architect Architecture appears in the small (software design patterns) and in the large (architectural styles) Architecture is independent [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.pauldee.org/blog/?p=47">last installment</a> of this series, I presented the foundations of software architecture.  To recap, they were</p>
<ul>
<li>Every piece of software has an architecture, whether intentional or not</li>
<li>Every architecture is created by at least one architect</li>
<li>Architecture appears in the small (software design patterns) and in the large (architectural styles)</li>
<li>Architecture is independent of technology choice.  Abstract styles allow for composability</li>
<li>Architectures are objective, allowing us to say one architecture is more elegant, efficient, or better than another</li>
</ul>
<p>This installment will cover how to recognize the styles being applied in an architecture through a process of analyzing for completeness, consistency, compatibility, and correctness.  The post will finish with how to evaluate an architecture after it&#8217;s gone through appropriate analysis.  The main goal here is to use purposeful, objective decision making and problem solving skills, to move forward in building the best possible system and enable us to have a higher chance of software project success.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-2/#footnote_0_348" id="identifier_0_348" class="footnote-link footnote-identifier-link" title="A successful project is most often defined as being on time, under budget, meeting all functional and nonfunctional requirements, and being constructed in a way that enables ease of maintenance and desirable evolution.">1</a></sup></p>
<h2>Analyzing an architecture</h2>
<p>Most often architectures need manual analysis, however, there are automatic and semi-automatic analysis techniques and tools.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-2/#footnote_1_348" id="identifier_1_348" class="footnote-link footnote-identifier-link" title="Automated analysis usually comes from using formal or semi-formal architectural methods, like xADL or one of SEI&rsquo;s methods">2</a></sup>  I&#8217;m primarily going to be discussing how to use general inspection and review based analysis and specifically Architectural Trade-Off Analysis Method (ATAM).  Both of these methods are manual, involving discussion,<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-2/#footnote_2_348" id="identifier_2_348" class="footnote-link footnote-identifier-link" title="Any sort of collaborative communication will work, I prefer a wiki because it documents the history of the analysis nicely">3</a></sup> and usually include iteration.  As always, this is just a foundation for these two methods, please feel free to adjust them for your own purposes or seek out more resources.</p>
<h3>Terms and goals</h3>
<p>Here is simple language used discuss and analyze architectures in an objective way:</p>
<ul>
<li><strong>Completeness</strong> &#8211; The system captures all functional and nonfunctional requirements.  The architecture itself fully captures all views and components of the system, as well as dynamic behaviors, interfaces, and contracts.</li>
<li><strong>Consistency</strong> &#8211; The absence of contradictions within the system.  These can appear as naming or interface inconsistencies with components or connectors, behavioral inconsistencies between components, and interaction or protocol inconsistencies.</li>
<li><strong>Compatibility</strong> &#8211; The system correctly applies and adheres to the constraints of the styles and reference architectures.  That is, you&#8217;re not trying to compose styles in an inefficient or incorrect way.</li>
<li><strong>Correctness</strong> &#8211; A relative property that refers to if an architecture captures all design decisions and if a system&#8217;s implementation fully captures the architecture, correctly implementing all design decisions</li>
</ul>
<p>When analyzing an architecture using this language, highlight:</p>
<ul>
<li>The data exchange within the system or subsystem &#8211; most systems (especially web-based systems) are data-intensive or data-centric.  The structure of the data, the flow of data, and its general properties and characteristics should all be analyzed</li>
<li>The structural characteristics of the architecture, ie: how everything connects or if components are missing necessary connections</li>
<li>The behaviors of components</li>
<li>The interaction between components</li>
<li>The nonfunctional characteristics of all components and connectors &#8211; often the critical dimension of all software systems</li>
</ul>
<p>Given this language and framework, architectures can be objectively inspected, discussed, compared, and analyzed.</p>
<h3>Inspection and review</h3>
<p>An architecture inspection and review can be thought of like a code review, but for the system&#8217;s architecture and design decisions.  Just like in a code review, quality and knowledge transfer are the two major takeaways from the process.  That is, inspection and review will find defects and shortcomings, better address design decisions, and allow all team members to fully understand the entire system&#8217;s architecture.  The scope, goal, and concern of the review is determined by the team and project, but the process is the same no matter what.</p>
<p>Individuals first conduct their own review, creating whatever artifacts (models, notes, written assessments, reference architectures) they feel they need.  A group then conducts a review together guided and supported by the individuals&#8217; reviews.  This can be done in any fashion, but there are specific formats, such as the ATAM.</p>
<h3>Architectural Trade-off Analysis Method</h3>
<p>The details of the method can be found at the <a href="http://www.sei.cmu.edu/architecture/tools/evaluate/atam.cfm">Software Engineering Institute&#8217;s site</a> but a graph will be sufficient:</p>
<div class="wp-caption alignnone" style="width: 472px"><img title="ATAM Flow" src="http://www.sei.cmu.edu/architecture/tools/evaluate/images/atam_flow_2-gif.jpg" alt="" width="462" height="295" /><p class="wp-caption-text">ATAM&#39;s flow</p></div>
<p>ATAM centers on a scenario based approach, which include:</p>
<ul>
<li>Use-case scenarios &#8211; how the system is envisioned to be used</li>
<li>Growth scenarios &#8211; planned and envisioned modifications to the system and architecture</li>
<li>Exploratory scenarios &#8211; the limits of the architecture&#8217;s adaptability when given major changes to the functionality, operational profiles, and underlying platform</li>
</ul>
<p>ATAM then uses technical constraints, external and integrated systems, and architectural approaches, to find the best possible match between the scenarios (which determine quality attributes of the system while expressing the requirements) and the best design decision.  ATAM is useful in that it inherently includes capacity planning, which is critical for most web systems that get deployed.</p>
<h2>Evaluating a candidate architecture</h2>
<p>It&#8217;s sometimes helpful to have a tangible working artifact when designing, analyzing and evaluating an architecture.  Creating a prototype or architectural skeleton are two ideal techniques, but are not substitutes for the methods described above.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-2/#footnote_3_348" id="identifier_3_348" class="footnote-link footnote-identifier-link" title="These terms were lifted from Arnon Rotem-Gal-Oz&rsquo;s blog">4</a></sup>  A prototype is useful in understanding how an architecture or reference architecture &#8220;holds together&#8221; or &#8220;stands up.&#8221;  For some architects, it&#8217;s an easier visualization of multiple components and connectors without getting lost in the functional and non-functional requirements.  As a consequence, prototypes prematurely force you into technology choice before a real architecture can be distinguished.  Prototypes come in two major forms:</p>
<ul>
<li>Horizontal prototype – which models wide aspects of a single layer,  i.e. many features with little details. The most common example for  Horizontal prototype is a  user interface prototype which is used to  test the overall interaction with the system.</li>
<li>Vertical prototype -Implementing some sub-system or a limited set of features across all layers /modules.</li>
</ul>
<p>An architectural skeleton is the first iteration of a candidate architecture, trying to loosely tie together the various technology choices that make up your components and connectors.  I strongly suggest all architects do this, as it gets you to a useable product early on and allows for experimentation and exploration within a live version of the architecture.</p>
<ol class="footnotes"><li id="footnote_0_348" class="footnote">A successful project is most often defined as being on time, under budget, meeting all functional and nonfunctional requirements, and being constructed in a way that enables ease of maintenance and desirable evolution.</li><li id="footnote_1_348" class="footnote">Automated analysis usually comes from using formal or semi-formal architectural methods, like xADL or one of SEI&#8217;s methods</li><li id="footnote_2_348" class="footnote">Any sort of collaborative communication will work, I prefer a wiki because it documents the history of the analysis nicely</li><li id="footnote_3_348" class="footnote">These terms were lifted from <a href="http://arnon.me/2010/05/saf-architecture-evaluation-evaluation-code/">Arnon Rotem-Gal-Oz&#8217;s blog</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Discussing and evaluating architectures; pt 1</title>
		<link>http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/</link>
		<comments>http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#comments</comments>
		<pubDate>Tue, 12 Jul 2011 07:29:40 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Software Architecture]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Useful Tips]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=47</guid>
		<description><![CDATA[Previously, I discussed how to Lose Weight Exercise validation at various points in the software development life cycle, but left out many details pertaining to software architecture.  Software architecture&#8217;s sheer depth and influence on a project was the rationale for doing so.  Being able to fluently dissect, analyze, discuss, evaluate, and compose software architectures is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.pauldee.org/blog/?p=144">Previously, I discussed</a> how to <a href="http://www.willbeta.com/lose-weight-exercise/"><span style="display:none;">Lose Weight </span>Exercise</a> validation at various points in the software development life cycle, but left out many details pertaining to software architecture.  Software architecture&#8217;s sheer depth and influence on a project was the rationale for doing so.  Being able to fluently dissect, analyze, discuss, evaluate, and compose software architectures is a core (and useful) skill for any software engineer or manager of software engineers.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_0_47" id="identifier_0_47" class="footnote-link footnote-identifier-link" title="In a later post I plan on appropriately defining the field of software engineering, as I most often make use of it.&nbsp; I feel like some people needlessly narrow the scope of &ldquo;software engineering&rdquo; &ndash; I try to somewhat establish a definition in this comment.&nbsp; The Parnas paper mentioned in a previous post details it better than I ever could.">1</a></sup></p>
<p>A system&#8217;s architecture is an expression of its characteristics.  It is the combination of all design decisions, tradeoffs, and constraints.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_1_47" id="identifier_1_47" class="footnote-link footnote-identifier-link" title="Understanding an architecture is the pursuit of exploring and understanding those decisions.&nbsp; Reviewing an architecture is similar to reading and reflecting upon  someone&rsquo;s biography or recognizing the quality of construction in a new  building or automobile.">2</a></sup>  The validity of an architecture is determined by objectively evaluating how its design decisions and behaviors map to the system&#8217;s functional and nonfunctional requirements.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_2_47" id="identifier_2_47" class="footnote-link footnote-identifier-link" title="Nonfunctional requirements are often called the -ities. Security, scalability, dependability, adaptability, complexity, efficiency, and robustness are some of the more common nonfunctional requirements.&nbsp; Being explicit about these requirements allows for a more complete architecture and better visibility with regards to testing/verification">3</a></sup>  Let&#8217;s walk through some core concepts about software architecture and then enumerate various evaluation strategies.</p>
<h3>Every software system has an architecture</h3>
<p>Every piece of software has an architecture, whether intentional or not, and was created by at least one architect.  This idea can be seen in other forms of architecture, for example, every building has an architecture.  Not all architectures are elegant or complete, but nonetheless exist.</p>
<h3>Architecture appears in the small and in the large</h3>
<p>Software architectures are often split up into two categories.  Architectural Styles are named sets of design decisions that result in superior <em>system</em> properties<em>,</em> yielding something that is more &#8220;elegant, effective, efficient, dependable, evolvable, and scalable.&#8221;<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_3_47" id="identifier_3_47" class="footnote-link footnote-identifier-link" title="Software Architecture: Foundations, Theory, and Practice. Taylor. Dashofy.">4</a></sup>  These decisions are made at the system level and are abstract.  Some examples are <a href="http://en.wikipedia.org/wiki/Client_server">client-server</a>, <a href="http://en.wikipedia.org/wiki/REST">REST</a>, <a href="http://en.wikipedia.org/wiki/Pipe_and_filter">pipe-and-filter</a>, <a href="http://en.wikipedia.org/wiki/Peer-to-peer">peer-to-peer</a>, and <a href="http://en.wikipedia.org/wiki/Data_Distribution_Service">DDS</a>.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_4_47" id="identifier_4_47" class="footnote-link footnote-identifier-link" title="I used these styles because they all map to widely used successful system.&nbsp; Respectively, the Internet, web services, Unix &ndash; (including Mac OS X), bit torrent, radar systems and emerging &ldquo;real time&rdquo; web.&nbsp; DDS is data-centric specialized form of another style, publish-subscribe">5</a></sup></p>
<p>Architectural Patterns, often called <em>Design Patterns</em> or <em>Software Design Patterns</em>, are named sets of design decisions that result in superior properties for a <em>component</em> or <em>within a component</em>.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_5_47" id="identifier_5_47" class="footnote-link footnote-identifier-link" title="Design Patterns are the expression of desired functionality, within the constraints of given language or paradigm (and are therefore language or paradigm dependent).&nbsp; For example, many of the classical design patterns are obsolete or do not apply in functional languages, largely because they were written for Object Oriented languages.">6</a></sup>  These patterns are usually concrete or partially concrete implementations.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_6_47" id="identifier_6_47" class="footnote-link footnote-identifier-link" title="Some pieces of architecture fall between both categories, like Model-View-Controller, which is an architectural style that is implemented in frameworks for various languages.">7</a></sup></p>
<h3>Architecture is independent of technology</h3>
<p>Architectural styles are abstract and aren&#8217;t tied to any particular piece of software, technology, or language.  Doing so adds unnecessary constraints on the design,<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_7_47" id="identifier_7_47" class="footnote-link footnote-identifier-link" title="The constraints are the result of passively accepting the tradeoffs inherent to certain technologies">8</a></sup> similar to the result of premature optimization.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_8_47" id="identifier_8_47" class="footnote-link footnote-identifier-link" title="In software, premature optimization is often a root cause to inhibiting system flexibility, the cause of integration problems, and a telltale sign of an inexperience software engineer">9</a></sup>  These additional constraints will at best reduce your system&#8217;s efficiency and at worst prevent your architecture from being valid.  Additionally, architectural styles need to be abstract to enable composability.</p>
<h3>Architectures are objective</h3>
<p>Architecture is a continual effort throughout the entire life cycle of software.  A system&#8217;s architecture evolves as your team elicits new requirements and gains information in your problem domain.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_9_47" id="identifier_9_47" class="footnote-link footnote-identifier-link" title="Architectures help establish knowledge by applying information from a problem domain into a solution&rsquo;s architecture">10</a></sup>  Characteristics of an architecture are objectively evaluated, enabling us to say one architecture is more elegant or efficient than another.</p>
<p><strong>Your goal in design and creation is to purposefully apply design decisions, using established styles and patterns, to achieve the best architecture possible.</strong> A necessary step in <a href="http://www.pauldee.org/blog/?p=99">effective problem solving</a> is critically analyzing all possible solutions, and objectively determining the best one.  Evaluating architectures is a software engineering equivalent.</p>
<h3>Next installment and further reading</h3>
<p>The next part of this blog post will use examples to discuss:</p>
<ul>
<li>Recognizing styles</li>
<li>Analyzing an architecture&#8217;s completeness, consistency, compatibility, and correctness</li>
<li>Applying architectural components to achieve nonfunctional properties</li>
<li>Evaluating conceptual architectures</li>
</ul>
<p>A third and final post will use those skills to design a &#8220;real time&#8221; web system, like Gmail or Twitter, starting from requirements and delivering a valid architecture.</p>
<p>Interested readers will find more information in <a href="http://www.softwarearchitecturebook.com/">Software Architecture: Foundations, Theory, and Practice</a>.  I strongly recommend the book to all software engineers as a great reference.<sup><a href="http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/#footnote_10_47" id="identifier_10_47" class="footnote-link footnote-identifier-link" title="The book features a matrix that identifies how each style can be composed, and the system properties that result from such a composition.&nbsp; This matrix is worth the book price alone.">11</a></sup> <a href="http://arnon.me/category/blog/">Arnon Rotem-Gal-Oz&#8217;s Blog</a> is a solid source of higher-level software architecture discussions.  <a href="http://highscalability.com/">High Scalability</a> and <a href="http://www.webperformancematters.com/">Web Performance Matters</a> are two wonderful sites about internet architectures.</p>
<p>Lastly, reading and studying well composed architectural styles will make you a better architect.  Applying the same lessons when faced with similar requirements or constraints will produce a better systems.  <a href="http://www.aosabook.org/en/index.html">The Architecture of Open Source Applications</a> is great, recent source of architectural walk-throughs of some of the most popular, successful, and widely adopted open source projects.</p>
<ol class="footnotes"><li id="footnote_0_47" class="footnote">In a later post I plan on appropriately defining the field of <em>software engineering</em>, as I most often make use of it.  I feel like some people needlessly narrow the scope of &#8220;software engineering&#8221; &#8211; I try to somewhat establish a definition in this<a href="http://blog.rafaelferreira.net/2011/05/unsolicited-and-uninformed-rant-about.html?showComment=1306173222793#c7067316940477387506"> comment</a>.  The <a href="http://www.pauldee.org/se-must-have/parnas-se-not-cs.pdf">Parnas paper</a> mentioned in a <a href="http://www.pauldee.org/blog/?p=284">previous post</a> details it better than I ever could.</li><li id="footnote_1_47" class="footnote">Understanding an architecture is the pursuit of exploring and understanding those decisions.  Reviewing an architecture is similar to reading and reflecting upon  someone&#8217;s biography or recognizing the quality of construction in a new  building or automobile.</li><li id="footnote_2_47" class="footnote">Nonfunctional requirements are often called <em>the -ities</em>. Security, scalability, dependability, adaptability, complexity, efficiency, and robustness are some of the more common nonfunctional requirements.  Being explicit about these requirements allows for a more complete architecture and better visibility with regards to testing/verification</li><li id="footnote_3_47" class="footnote"><a href="http://www.softwarearchitecturebook.com/"><span style="text-decoration: underline;">Software Architecture: Foundations, Theory, and Practice</span></a>. Taylor. Dashofy.</li><li id="footnote_4_47" class="footnote">I used these styles because they all map to widely used successful system.  Respectively, the Internet, web services, Unix &#8211; (including Mac OS X), bit torrent, radar systems and emerging &#8220;real time&#8221; web.  DDS is data-centric specialized form of another style, <a href="http://en.wikipedia.org/wiki/Publish/subscribe">publish-subscribe</a></li><li id="footnote_5_47" class="footnote">Design Patterns are the expression of desired functionality, within the constraints of given language or paradigm (and are therefore language or paradigm dependent).  For example, many of the <a href="http://en.wikipedia.org/wiki/Design_Patterns">classical design patterns</a> are obsolete or do not apply in functional languages, largely because they were written for Object Oriented languages.</li><li id="footnote_6_47" class="footnote">Some pieces of architecture fall between both categories, like Model-View-Controller, which is an architectural style that is implemented in frameworks for various languages.</li><li id="footnote_7_47" class="footnote">The constraints are the result of passively accepting the tradeoffs inherent to certain technologies</li><li id="footnote_8_47" class="footnote">In software, <a href="http://en.wikipedia.org/wiki/Premature_optimization#When_to_optimize">premature optimization</a> is often a root cause to inhibiting system flexibility, the cause of integration problems, and a telltale sign of an inexperience software engineer</li><li id="footnote_9_47" class="footnote">Architectures help establish knowledge by applying information from a problem domain into a solution&#8217;s architecture</li><li id="footnote_10_47" class="footnote">The book features a matrix that identifies how each style can be composed, and the system properties that result from such a composition.  This matrix is worth the book price alone.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2011/discussing-and-evaluating-architectures-pt-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A list for software engineers, pt 2</title>
		<link>http://www.pauldee.org/blog/2011/a-list-for-software-engineers-pt-2/</link>
		<comments>http://www.pauldee.org/blog/2011/a-list-for-software-engineers-pt-2/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 22:11:27 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=324</guid>
		<description><![CDATA[In a previous post I presented a list of influential software engineering papers that greatly defined and shaped the field.  Additionally the papers provide a great introductory platform for building and sharpening personal software engineering skills.  I&#8217;m continuing in the second part of the post by listing books and videos that are great references to [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://www.pauldee.org/blog/?p=284">previous post</a> I presented a list of influential software engineering papers that greatly defined and shaped the field.  Additionally the papers provide a great introductory platform for building and sharpening personal software engineering skills.  I&#8217;m continuing in the second part of the post by listing books and videos that are great references to have, will provide you with concrete tools and techniques to better engineer solutions, and will open up the field of software engineering.</p>
<h3>Must-read list of software engineering books</h3>
<p><a href="http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959/ref=sr_1_1?ie=UTF8&amp;qid=1309456285&amp;sr=8-1">The Mythical Man-Month</a> &#8211; Frederick Brooks<br />
Software engineering is an objective practice, entangled with people and process.  This book offers great advice on how to approach managing software projects and the practice of software engineering.</p>
<p><a href="http://www.amazon.com/How-Solve-Aspect-Mathematical-Method/dp/4871878309/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1309466406&amp;sr=1-1">How to Solve It: A New Aspect of Mathematical Method</a> &#8211; George Polya<br />
&#8220;Solving problems is a practical art.&#8221;  This book does a great job of detailing the process and tools to decompose problems and build up ideal solutions.  It&#8217;s targeted at mathematics, but the subject matter is very much universal.</p>
<p><a href="http://www.amazon.com/Information-Technology-Project-Management-Organizational/dp/0471715395/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1309467208&amp;sr=1-1">Information Technology Project Management: Providing Measurable Organizational Value</a> &#8211; Jack T. Marchewka<br />
This entire book is practical in its material, none of it is theoretical.  It covers metrics, risk analysis, estimation techniques, and managing cycles.  I always reach for this book when spinning up new projects.</p>
<p><a href="http://www.amazon.com/Software-Architecture-Foundations-Theory-Practice/dp/0470167742/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1309468224&amp;sr=1-1">Software Architecture: Foundations, Theory, and Practice</a> &#8211; Taylor, Medvidoviƒá, Dashofy<br />
I have recommended this book in the footnotes of previous posts.  This book walks through architecture styles, composition, appropriate ways to approach designing, validation techniques, and more.  The composition matrix in the beginning chapters of the book is worth the purchase alone.  To boot, Nenad Medvidoviƒá is a professor with Barry Boehm.<sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers-pt-2/#footnote_0_324" id="identifier_0_324" class="footnote-link footnote-identifier-link" title="Boehm was the author of some of the most influential papers in software engineering">1</a></sup></p>
<p><a href="http://www.aosabook.org/en/index.html">The Architecture of Open Source Applications</a> &#8211; Edited by Amy Brown and Greg Wilson<br />
This book is <strong>FREE</strong> to read online.  It carefully walks through the architectures of some of the most used and successful open source projects, the tradeoffs made, and the dirty hacks that hold everything together.  Working through this book will allow any engineer to apply the lessons learned when faced with similar situations or constraints.</p>
<p><a href="http://www.amazon.com/Interaction-Design-Jenny-Preece/dp/0471492787/ref=sr_1_1?ie=UTF8&amp;qid=1309658354&amp;sr=8-1">Interaction Design</a> &#8211; Jenny Preece, Yvonne Rogers,      Helen Sharp<br />
A great book about user-centered interaction and experience design.  This book provides the tools to design, prototype, validate, and evolve interactions and interfaces for your systems.</p>
<p><a href="http://www.amazon.com/Hackers-Delight-Henry-S-Warren/dp/0201914654/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1309469420&amp;sr=1-1">Hacker&#8217;s Delight</a> &#8211; Henry S. Warren<br />
Hacker&#8217;s Delight is a collection of efficient, space-saving, performance hacks for common programming tasks and system operations.  I haven&#8217;t put a lot of the material of this book to use, but it&#8217;s useful to have and interesting to paw through.  This book has little to do with the practice of software engineering, but still should sit proudly on your shelf.</p>
<p><a href="http://www.amazon.com/Seven-Languages-Weeks-Programming-Programmers/dp/193435659X/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1309469653&amp;sr=1-1">Seven languages in seven weeks</a> &#8211; Bruce Tate<br />
Learning and applying multiple paradigms allows you to find best tool for the job.  Opening your engineering-vision to what is possible will enable you to engineer more elegant systems.</p>
<h3>Must-watch list of software engineering videos</h3>
<p><a href="http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey">Are we there yet?</a> &#8211; Rich Hickey<br />
Has Object-Oriented programming delivered on the software engineering principles it promised?  Are we engineering better systems because of OOP, or have we missed the mark?</p>
<p><a href="http://blip.tv/clojure/hammock-driven-development-4475586">Hammock driven development</a> &#8211; Rich Hickey<br />
There is value often overlooked in working through a problem domain, properly decomposing it, and validating your proposed solutions early.  This talk is about how to solve problems better and the steps to do it. <sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers-pt-2/#footnote_1_324" id="identifier_1_324" class="footnote-link footnote-identifier-link" title="There is a useful cheat sheet graphic.&nbsp; I will temporarily make it my desktop image when I begin working on a new problem">2</a></sup></p>
<p><a href="http://www.youtube.com/watch?v=aAb7hSCtvGw">How to design a good API and why it matters</a> &#8211; Joshua Bloch<br />
This Google Tech Talk video talks about designing, validating, and building out APIs, but the lessons here are universal to all interfaces and public-facing solutions.</p>
<h3>Honorable mentions</h3>
<p>Erich Gamma &#8211; I didn&#8217;t select any of his works, but some of his guiding principles are the most important in software engineering, namely: &#8220;Program to an interface, not an implementation&#8221; and &#8220;Favor composition over inheritance.&#8221;</p>
<p>Paul Graham &#8211; Aside from authoring great books about Common Lisp, Paul Graham has elegantly described and carefully organized works and efforts around Hacker Culture.  If you are a professional software engineer, you have to own <a href="http://www.amazon.com/s/ref=nb_sb_ss_i_0_20?url=search-alias%3Dstripbooks&amp;field-keywords=hackers+and+painters&amp;x=0&amp;y=0&amp;sprefix=hackers+and+painters">Hackers and Painters</a>.</p>
<h3>Missing from the lists</h3>
<p>Validation and verification is an essential part of the software development life cycle, but I didn&#8217;t list any books covering the topic.  The simple fact is that most software testing books are terrible.  If I had to recommend one, I&#8217;d probably offer <a href="http://www.amazon.com/Software-Testing-2nd-Ron-Patton/dp/0672327988/ref=sr_1_1?ie=UTF8&amp;qid=1309470660&amp;sr=8-1">Software Testing</a> by Ron Patton.</p>
<p>I&#8217;m also not wild about any book I&#8217;ve read on requirements elicitation and specification.  The only one I could really recommend is <a href="http://www.amazon.com/Managing-Software-Requirements-Case-Approach/dp/032112247X/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1309470815&amp;sr=1-1">Managing Software Requirements: A Use Case Approach</a> by Dean Leffingwell and Don Widrig.</p>
<h3>People&#8217;s Choice</h3>
<p>Many people sing Russ Olsen&#8217;s praises, especially his book <a href="http://www.amazon.com/Design-Patterns-Ruby-Russ-Olsen/dp/0321490452/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1309471104&amp;sr=1-1">Design Patterns in Ruby</a>.<sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers-pt-2/#footnote_2_324" id="identifier_2_324" class="footnote-link footnote-identifier-link" title="All of Russ Olsen&rsquo;s books on Amazon have 4 or 5 start ratings">3</a></sup> If you work in any OO language, this book will open your mind in how to best apply design patterns.</p>
<ol class="footnotes"><li id="footnote_0_324" class="footnote">Boehm was the author of some of the most influential papers in software engineering</li><li id="footnote_1_324" class="footnote">There is a useful <a href="http://incanter.org/images/misc/hammock-driven-dev.png">cheat sheet graphic</a>.  I will temporarily make it my desktop image when I begin working on a new problem</li><li id="footnote_2_324" class="footnote">All of Russ Olsen&#8217;s books on Amazon have 4 or 5 start ratings</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2011/a-list-for-software-engineers-pt-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A list for software engineers</title>
		<link>http://www.pauldee.org/blog/2011/a-list-for-software-engineers/</link>
		<comments>http://www.pauldee.org/blog/2011/a-list-for-software-engineers/#comments</comments>
		<pubDate>Sat, 18 Jun 2011 19:45:10 +0000</pubDate>
		<dc:creator>Paul deGrandis</dc:creator>
				<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://www.pauldee.org/blog/?p=284</guid>
		<description><![CDATA[It&#8217;s important to understand the core concepts within software engineering to better engineer systems, and produce deliverables on time, under budget, and of high quality.  Below is a list of articles that have shaped software engineering and will no doubt make you a better, more objective software engineer.1  The references cited in these papers can [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s important to understand the core concepts within software engineering to better engineer systems, and produce deliverables on time, under budget, and of high quality.  Below is a list of articles that have shaped software engineering and will no doubt make you a better, more objective software engineer.<sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers/#footnote_0_284" id="identifier_0_284" class="footnote-link footnote-identifier-link" title="I&rsquo;m using better to mean increasing the depth of one&rsquo;s skillset, focusing more on objective driven engineering, and using skills and techniques known to produce software that is more secure, scalable, manageable, maintainable, etc. ">1</a></sup>  The references cited in these papers can also serve as a jumping board into topics you wish to further read about.</p>
<p>In a follow-up post I will present a list of books and videos that I have found  useful in architecting and building software, or that sharpened my approach to software engineering.</p>
<h3>Must-read list of software engineering</h3>
<p>These are grouped by author and in no particular order.  Take your time and carefully digest each paper.  You can optionally download <a href="http://www.pauldee.org/se-must-have.zip">all the papers as a .zip file</a>.</p>
<p><a href="http://www.pauldee.org/se-must-have/parnas-se-not-cs.pdf">Software engineering programmes are not computer science programmes</a><sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers/#footnote_1_284" id="identifier_1_284" class="footnote-link footnote-identifier-link" title="This paper and the three that follow are by Parnas, considered the    grandfather of software engineering education, object orientation, data    encapsulation, and general large system design">2</a></sup><br />
If you&#8217;re going to call yourself a software engineer, you should mean it.  This paper concisely lays out the difference between the two and the importance in shaping education around the former.<sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers/#footnote_2_284" id="identifier_2_284" class="footnote-link footnote-identifier-link" title="Please note that I received my B.S. in Software Engineer, so assume some bias">3</a></sup></p>
<p><del></del><a href="http://www.pauldee.org/se-must-have/parnas-ease-of-extension.pdf">Designing software for ease of extension and contraction</a><br />
This paper discusses the importance of loosely coupled, highly cohesive modules, that only expose specific functionality.  The root goals of object oriented programming were based on this paper.</p>
<p><a href="http://www.pauldee.org/se-must-have/parnas96-sw-aging.pdf">Software aging</a><br />
Software is an evolving system.  It ages just like bridges, buildings, and cars.  This paper was the first to discuss how to approach software evolution.</p>
<p><a href="http://www.pauldee.org/se-must-have/jones-failure-success.pdf">Software project management practices: Failure versus success</a><sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers/#footnote_3_284" id="identifier_3_284" class="footnote-link footnote-identifier-link" title="This paper and the following one are by Capers Jones.&nbsp; He has   contributed well conducted case studies and publications focused on   metrics, risk management, requirements engineering, and objective   estimating.">4</a></sup><br />
This is a case study on why certain projects fail while others succeed.  There are only a few common reasons why projects succeed, but they are essential for success.</p>
<p>Software metrics: good, bad and missing (<em>I can&#8217;t find a freely available copy of this article</em>)<br />
Software and the process to create it are objective matters.  We can measure them and say whether they&#8217;re good or bad.  Metrics give us a baseline to make these statements, and this paper presents a holistic approach.</p>
<p><a href="http://www.pauldee.org/se-must-have/brooks-no-silver-bullet.pdf">No silver bullet: Essence and accidents of software engineering</a><sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers/#footnote_4_284" id="identifier_4_284" class="footnote-link footnote-identifier-link" title="This paper is by Brooks, who wrote mostly about theory vs practice and software project management">5</a></sup><br />
There is no silver bullet for software engineering, but there are core concepts that help us engineer better systems.  The details and examples in this paper are dated, but the root concepts still hold.</p>
<p><a href="http://www.pauldee.org/se-must-have/boehm-SE-Economics.pdf">Software engineering economics</a><sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers/#footnote_5_284" id="identifier_5_284" class="footnote-link footnote-identifier-link" title="This paper and those that follow are by Boehm, best known for his   contributions to estimation, risk and requirements management, the   creation of the spiral or iterative development life cycle (now widely   used in Scrum and other agile methods), and measuring and estimating the   cost of software">6</a></sup><br />
Estimation is hard and is exacerbated by our lack of understanding of a project&#8217;s remaining work.  What follows is a survey of various estimation techniques and their accuracy.  Boehm then introduces COCOMO.<sup><a href="http://www.pauldee.org/blog/2011/a-list-for-software-engineers/#footnote_6_284" id="identifier_6_284" class="footnote-link footnote-identifier-link" title="When estimating projects, I often use COCOMO (or some variation of it) as my top-down estimation technique.&nbsp; I then independently use a bottom up estimation technique, and go through a process to reconcile the two.">7</a></sup></p>
<p><a href="http://www.pauldee.org/se-must-have/boehm-PrinciplesandPractices.pdf">Software risk management: principles and practices</a><br />
This paper discusses the importance of risk management in a general software engineering process, as well as how to implement for your team or project.</p>
<p><a href="http://www.pauldee.org/se-must-have/boehm-v-and-v.pdf">Verifying and validating software requirements and design specifications</a><br />
Starting the verification and validation process at the point of doing requirements will remove more problems within the system faster, cheaper and earlier than conventional practice.</p>
<ol class="footnotes"><li id="footnote_0_284" class="footnote">I&#8217;m using <em>better</em> to mean increasing the depth of one&#8217;s skillset, focusing more on objective driven engineering, and using skills and techniques known to produce software that is more secure, scalable, manageable, maintainable, etc. </li><li id="footnote_1_284" class="footnote">This paper and the three that follow are by Parnas, considered the    grandfather of software engineering education, object orientation, data    encapsulation, and general large system design</li><li id="footnote_2_284" class="footnote">Please note that I received my B.S. in Software Engineer, so assume some bias</li><li id="footnote_3_284" class="footnote">This paper and the following one are by Capers Jones.  He has   contributed well conducted case studies and publications focused on   metrics, risk management, requirements engineering, and objective   estimating.</li><li id="footnote_4_284" class="footnote">This paper is by Brooks, who wrote mostly about theory vs practice and software project management</li><li id="footnote_5_284" class="footnote">This paper and those that follow are by Boehm, best known for his   contributions to estimation, risk and requirements management, the   creation of the spiral or iterative development life cycle (now widely   used in Scrum and other agile methods), and measuring and estimating the   cost of software</li><li id="footnote_6_284" class="footnote">When estimating projects, I often use COCOMO (or some variation of it) as my top-down estimation technique.  I then independently use a bottom up estimation technique, and go through a process to reconcile the two.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.pauldee.org/blog/2011/a-list-for-software-engineers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
