<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Random Thoughts]]></title><description><![CDATA[About business and information technology]]></description><link>https://christoffer.soop.ch/</link><image><url>https://christoffer.soop.ch/favicon.png</url><title>Random Thoughts</title><link>https://christoffer.soop.ch/</link></image><generator>Ghost 5.46</generator><lastBuildDate>Thu, 23 Apr 2026 10:07:49 GMT</lastBuildDate><atom:link href="https://christoffer.soop.ch/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Replacing Agile with the Studio Model?]]></title><description><![CDATA[The Agile Manifesto was written over 20 years ago and according to some it's age is starting to show. After all, 20 years in IT should be a good approximation of eternity given the rate of change in the industry...]]></description><link>https://christoffer.soop.ch/replacing-agile-with-the-studio-model/</link><guid isPermaLink="false">645818765c4dcc000153cb67</guid><category><![CDATA[Agile]]></category><category><![CDATA[Development]]></category><category><![CDATA[Methodology]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Sun, 15 Nov 2020 22:36:09 GMT</pubDate><media:content url="https://christoffer.soop.ch/content/images/2020/11/hockey-stick-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://christoffer.soop.ch/content/images/2020/11/hockey-stick-1.jpg" alt="Replacing Agile with the Studio Model?"><p>The Agile Manifesto was written over 20 years ago and according to some it&apos;s age is starting to show. After all, 20 years in IT should be a good approximation of eternity given the rate of change in the industry...</p>
<p>In 2017 <a href="https://www.linkedin.com/in/kurtcagle/?ref=christoffer.soop.ch">Kurt Cagle</a>, a veteran IT expert, Forbes Innovation columnist and self-proclaimed &quot;Futurist, Technologist, Information Architect, Blogger&quot;, wrote an article <a href="https://www.forbes.com/sites/cognitiveworld/2019/08/23/the-end-of-agile/?ref=christoffer.soop.ch#647e0ac52071">The End of Agile</a> that sparked quite a bit of controversy and a massive feedback on social media. In the article he comically compares a daily scrum session to a religious cult where members confess their sins while passing on the holy hockey stick from one to another:</p>
<blockquote>
<p>I knew the end of Agile was coming when we started using hockey sticks. Every morning, at precisely eight o&apos;clock, the team of developers and architects would stand around a room paneled in white boards and would begin passing around a toy hockey stick. When you received the hockey stick, you were supposed to launch into the litany: Forgive me, Father, for I have sinned. I only wrote two modules yesterday, for it was a day of meetings and fasting, and I had a dependency upon Joe, who&apos;s out sick this week with pneumonia.</p>
<p>The scrum master, the one sitting down while we were standing, would duly note this in Rally or Jira (I forget which), then would intone, &quot;You are three modules behind. Do you anticipate that you will get these done today?&quot;</p>
<p>&quot;I will do the three modules as you request, scrum master, for I have brought down the team average and am now unworthy.&quot;</p>
<p>&quot;See that you do, my child, for the sprint endeth on Tuesday next, and <em>management is watching</em>.&quot;</p>
</blockquote>
<p>The hyperbole goes a long way to prove the point that Agile and Scrum has a strong resemblance to religion with its own dogmatic &quot;truth&quot;. Defendants may argue that the way Agile is taught and practiced is not always true to the tenets of the <a href="https://agilemanifesto.org/?ref=christoffer.soop.ch">Agile Manifesto</a> but this just further drives home the point.</p>
<p>In the deluge of comments a few were constructive and Cagle chose to publish one made by Scott Heffield (VP of <a href="https://www.veracitysolutions.com/?ref=christoffer.soop.ch">Veracity Solutions</a>) on his own blog: <a href="https://www.forbes.com/sites/cognitiveworld/2019/08/28/the-end-of-agile-a-rebuttal/?ref=christoffer.soop.ch">The End of Agile: A Rebuttal</a>. This rebuttal from Scott does not really go into the details of contradicting the argument Cagle puts forth. Instead it only says that what Cagle describes is not what he has experienced, goes on to quote experts of the Agile pantheon like Martin Fowler and Alistair Cockburn explaining why Agile is great, and the he concludes by pointing out that Cagle was not there to sign the manifesto like said experts, which somehow should be construed as a reason for his argument to be false.</p>
<p>Right. By appealing to personal experience, experts and not actually addressing the argument <em>per se</em>, Heffield just helped kill Agile himself and even buried the corpse by sounding like a religious zealot.</p>
<p>Cagle does not say that everything with Agile is wrong. His main point is that Agile was created in a different context where developers where struggling with a different set of problems from today. Most projects at the time when Agile was conceived dealt with vertically integrated projects where the final, end-user facing application was responsible from everything from the UI to the database. Also they were typically short with a duration up to six months or so. There are entire classes of projects where Agile does not work well.</p>
<p>In particular he highlights enterprise data projects that he sees reflecting a paradigm change in mainstream application development. Projects in this space are typically not time boxed but ongoing, they have an emphasis on data modeling, are not client facing and require minimal custom development. Instead of the vertically integrated projects of yore, applications today are more and more a conduit of a stream of data with mainly a thin presentation layer.</p>
<p>Cagle concludes the original article with</p>
<blockquote>
<p>While aspects of Agile will remain, the post-Agile world has different priorities and requirements, and we should expect whatever paradigm finally succeeds it to deal with the information stream as the fundamental unit of information.</p>
<p>So, Agile is not &quot;dead&quot;, but it is becoming ever less relevant. There&apos;s something new forming (topic for another article, perhaps), but all I can say today is that it likely won&apos;t have hockey sticks.</p>
</blockquote>
<p>In a <a href="https://www.forbes.com/sites/cognitiveworld/2019/08/28/agile-and-the-studio-model/?ref=christoffer.soop.ch#31b6963178de">follow-up article</a> posted a week later he expands on just what could replace Agile as the next big thing in software development: the Studio Model. He even proposes his own manifesto.</p>
<p>While the manifesto does not read as well as the original it strives to replace, it still makes some good points about the short comings of Agile.</p>
<blockquote>
<p>Yet, there are two key sets of problems that the Agile community faces. The first, and foremost, is that it decentralizes responsibility too much - it essentially punts on the whole issue of governance or editorial guidance. This is that whole vision thing all over again. Most people see editors as quality control people, but editors are actually stewards - they are people who serve to establish, preserve and modify a particular vision, and their role in that regard is roughly analogous to the movie director or software architect as given above.</p>
</blockquote>
<p>In the Studio Model he sets movie production and other IP rights development as an example for software development. Here the creative vision is key and is used to guide developers across teams, thus addressing some of the challenges when doing Agile development. Instead of the Agile catch phrase of &quot;fail fast&quot; he emphasizes flexibility and the minimal viable product is not considered something good as the value is an emergent property that comes from the larger ecosystem.</p>
<p>Since the origianl posts in 2017 Cagle has written a follow up article on the Studio Model: <a href="https://www.forbes.com/sites/cognitiveworld/2019/09/03/when-does-the-creativity-happen-design-agile-and-the-studio-model/?ref=christoffer.soop.ch#28a49b4d6755">When Does The Creativity Happen? Design, Agile and the Studio Model</a></p>
<p><strong>TL;DR</strong></p>
<ul>
<li>Agile is often equated with Scrum and has started to become a religion in the enterprise context.</li>
<li>While Agile has benefits some of the basic ideas of adapting the frameworks and methodologies to the task at hand has been replaced by dogma.</li>
<li>The context of main stream software development has changed and some of the Agile tenets may have to be revisited and adapted to our times.</li>
<li>Modern development requires curation and people with a strong vision such as software architect.</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[How to stay DRY doing Microservices]]></title><description><![CDATA[Using the Dockerfile ONBUILD instruction boilerplate code and repetition can be avoided effectively creating abstractive based images for your Microservices]]></description><link>https://christoffer.soop.ch/how-stay-dry-doing-microservices/</link><guid isPermaLink="false">645818765c4dcc000153cb66</guid><category><![CDATA[Architecture]]></category><category><![CDATA[Development]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Microservices]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Sat, 04 May 2019 15:08:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><em>This post is <a href="https://github.com/chrsoo/microservices/?ref=christoffer.soop.ch">also avaialble on GitHub</a> together with all the source files!</em></p>
<p>When using <code>Jenkinsfile</code> and <code>Dockerfile</code> with Microservices you are typically repeating the same boilerplate code over and over again. Initially this is not a problem but as the number of Microservices - and Git branches - start to increase it can become quite painful.</p>
<p>In order to stay <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself?ref=christoffer.soop.ch">DRY</a> you can leverage the <code>ONBUILD</code> Dockerfile keyword in a custom base image and a <a href="https://jenkins.io/doc/book/pipeline/shared-libraries/?ref=christoffer.soop.ch#defining-global-variablesME">global var</a> to define a reusable Jenkins pipeline.</p>
<p>With this solution each Microservice has a <a href="https://github.com/chrsoo/microservices/blob/master/Jenkinsfile?ref=christoffer.soop.ch">Jenkinsfile</a> similar to</p>
<pre><code>@Library(&quot;mylib@latest&quot;) _
mavenPipeline(java: &apos;8&apos;)
</code></pre>
<p>... and a <a href="https://github.com/chrsoo/microservices/blob/master/Dockerfile.microservice?ref=christoffer.soop.ch">Dockerfile</a> as simple as</p>
<pre><code>FROM mybase:latest
</code></pre>
<p>See <a href="https://github.com/chrsoo/microservices/blob/master/Dockerfile?ref=christoffer.soop.ch">Dockerfile</a> for an example on how the custom base image can look like and the <a href="https://github.com/chrsoo/microservices/blob/master/pom.xml?ref=christoffer.soop.ch">project pom</a> on how build both the base image and the Microservices using it!</p>
<p>Read the rest of the article if you are interested in the details or  if the above does not make much sense.</p>
<ul>
<li><a href="#context">Context</a></li>
<li><a href="#theproblem">The Problem</a></li>
<li><a href="#asolution">A Solution</a></li>
<li><a href="#anexample">An Example</a></li>
<li><a href="#lastwords">Last Words</a></li>
</ul>
<h1 id="context">Context</h1>
<p>Let&apos;s say you are using Microservices. Following best practices, each Microservice has its own source code repository. You start out with a few but this rapidly grows to a few dozen and with time you are managing a few hundred, perhaps more.</p>
<p>Each Microservice is built as a Docker image that defines a few labels, variables and some bootstrap code. A <code>Dockerfile</code> might look something like:</p>
<pre><code>FROM openjdk:8-jdk-alpine

ENV SVC_HOME=/opt/microservice
ENV SVC_ETC=${SVC_HOME}/etc SVC_LIB=${SVC_HOME}/lib SVC_CACHE=/var/cache/microservice BOOTSTRAP=${SVC_HOME}/bootstrap.sh

RUN addgroup --system microservice \
    &amp;&amp; adduser --system --ingroup microservice --home $SVC_HOME microservice

ADD src/files ${SVC_ETC}/
ADD bootstrap.sh ${BOOTSTRAP}

RUN mkdir -p $SVC_LOG $SVC_CACHE $SVC_ETC \
    &amp;&amp; chown -R microservice:microservice $SVC_LOG $SVC_CACHE $SVC_HOME \
    &amp;&amp; chmod +x ${BOOTSTRAP}

USER microservice

ARG JAR_FILE

ARG ARTIFACT_ID
ARG GROUP_ID
ARG VERSION

LABEL org.label-schema.vendor=&quot;My Company&quot; \
    org.label-schema.name=$ARTIFACT_ID \
    org.label-schema.description=&quot;Yet another Microservice&quot; \
    org.label-schema.usage=&quot;/README.md&quot; \
    org.label-schema.version=$VERSION \
    org.label-schema.schema-version=&quot;1.0&quot; \
    java.version=${JAVA_VERSION} \
    java.alpine.version=${JAVA_ALPINE_VERSION}

ENV \
    ARTIFACT_ID=${ARTIFACT_ID} \
    GROUP_ID=${GROUP_ID} \
    VERSION=${VERSION} \
    LOG_LEVEL=INFO \
    CACHE_DIR=${SVC_CACHE}/${ARTIFACT_ID} \
    ETC_DIR=${SVC_ETC}/${ARTIFACT_ID} \
    MICROSERVICE=${SVC_HOME}/${JAR_FILE}

ADD target/lib ${SVC_LIB}/
ADD target/${JAR_FILE} ${MICROSERVICE}

# HTTP
EXPOSE 9000
# JMX
EXPOSE 8181

ENTRYPOINT [&quot;/opt/microservice/bootstrap.sh&quot;]
</code></pre>
<p>Having fully bought into the whole DevOps and automation concept you have CI/CD pipelines to build and deploy your Microservices.</p>
<p>Jenkins you use out of habit, because this is what you know or because it seems to be a very popular choice. Who really knows why, but Jenkins is what you are currently stuck with.</p>
<p>Jenkins is configured to automatically detect new Git repositories and manage pipelines for each Git branch. A <code>Jenkinsfile</code> in your Git repository defines the steps for building a Microservice and pushing code automatically triggers the build.</p>
<pre><code>pipeline {
    agent docker
    stage (&apos;Build&apos;) {
        steps {
            ...
        }
    }
    stage (&apos;Test&apos;) {
        steps {
            ...
        }
    }
    stage (&apos;Verify&apos;) {
        steps {
            ...
        }
    }
    stage (&apos;Publish&apos;) {
        steps {
            ...
        }
    }
}
</code></pre>
<p>Thus the Git repository root contains two boilerplate files, one for Docker and one for Jenkins:</p>
<pre><code>Dockerfile
Jenkinsfile
</code></pre>
<p>In most cases these files are almost identical apart from label and environment values. In order to facilitate for developers these they are automatically generated using a template mechanism of some sorts. Perhaps the nifty <a href="https://blog.docker.com/2018/12/introducing-desktop-enterprise/?ref=christoffer.soop.ch">Docker Enterprise Desktop</a> shipping as a part of Docker EE 3.0</p>
<h1 id="theproblem">The Problem</h1>
<p>Requirements change or perhaps there is a bug but for whatever reason either the standard Jenkins pipeline and or Dockerfile change over time.</p>
<p>With a large number of Microservices that each has its own version of the <code>Jenkinsfile</code> and <code>Dockerfile</code>, multiple branches for handling the master line, development, features and bugs the relevance of the <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself?ref=christoffer.soop.ch">DRY</a> principle starts to sink in and you realize you have a <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself?ref=christoffer.soop.ch">WET</a> solution...</p>
<p><strong>For every change that comes along you now have to check out the code make the same edit for all branches.</strong></p>
<p>Cheery-picking and merging helps but still there is a lot of typing, committing and pushing going on. This increases the risk of typos and other inconsistencies, in particular if done by multiple teams and developers.</p>
<p>Of course, nothing prevents you from automating changes like this, but it would throwing code at a symptom instead of resolving the root cause.</p>
<h1 id="asolution">A Solution</h1>
<p>A solution that addresses the WET root cause comes in two parts:</p>
<ul>
<li>Use a custom base image in your Dockerfiles</li>
<li>Use pipeline DSL in your Jenkinsfiles</li>
</ul>
<h2 id="usingacustombaseimage">Using a Custom Base Image</h2>
<p>A custom base image should contain all things common to your downstream Microservices, things like</p>
<ul>
<li>standard image labels</li>
<li>log configuration files</li>
<li>common bootstrap shell scripts</li>
<li>runtime users</li>
<li>...</li>
</ul>
<p>The custom base image in itself uses a more standard upstream image, such as the alpine version for your language.</p>
<p>Some things depend on the <em>downstream</em> Microservice, however. What if you have a label containing the name or version of the Microservice? These are only known at build time of the Microservice itself, not when we are building the base image.</p>
<p>The key here is Docker&apos;s <code>ONBUILD</code> keyword which allows you to customize your base image to your Microservice using build time arguments.</p>
<p>For example we can set a <code>version</code> container label on the downstream Microservice with</p>
<pre><code>ONBUILD ARG VERSION
ONBUILD LABEL version=${VERSION}
</code></pre>
<p>Given that the base image is called <code>mybase</code> we then use a <code>Dockerfile</code> in Microservice repository with the following content:</p>
<pre><code>FROM mybase:latest
</code></pre>
<p><strong>That&apos;s it. That is the entire Dockefile.</strong></p>
<p>To build it we have to supply a build argument to the docker command, something along the lines of</p>
<pre><code>docker build --arg VERSION=1.3.9 .
</code></pre>
<p>The resulting image will then contain the container label <code>version: 1.3.9</code> (surprise!).</p>
<p><strong>If the we want to change something, perhaps adding another standard label, update the logic to the bootstrap script, change the log configuration or perhaps just update the to the latest alpine for Java, we only change it in one place, i.e. in the custom base image <code>mybase</code>.</strong></p>
<p>Of course, we still need to trigger the rebuild and redeployment of all our Microservices but the DRY principle is respected.</p>
<p>The beauty of this approach is that we still have our <code>Dockerfile</code> in each Git repository which can be customized if there is a real need. Just because there is a default base image does not mean that we force everybody to use it all the time. All our CI/CD tools will still work exactly the same and the only drawback is that we now have one exception to manage separately from the rest.</p>
<p>If you find yourself making a lot of similar exceptions, refactoring of the base image might be in place. Or perhaps there is a need for two different types of base images? In any case, try to keep it as simple and stupid as possible (cf. <a href="https://en.wikipedia.org/wiki/KISS_principle?ref=christoffer.soop.ch">KISS</a>).</p>
<p>Please see <a href="https://github.com/chrsoo/microservices/blob/master/Dockerfile?ref=christoffer.soop.ch">Dockerfile</a> for a more complete example of how a custom base image can look like!</p>
<h2 id="usepipelinedslinyourjenkinsfiles">Use pipeline DSL in your Jenkinsfiles</h2>
<p>Jenkins has support for building custom <a href="https://jenkins.io/doc/book/pipeline/syntax/?ref=christoffer.soop.ch">pipeline DSL</a> in Groovy.</p>
<p>This can be quite complicated given that Jenkins Groovy flavor is not 100% vanilla and it has a sour twist - not all Groovy features are available and you need follow certain conventions. If you stick to existing steps and very simple groovy code you should be good though.</p>
<p>Here we will not go into details on how to develop a Pipeline DSL but the basic idea is that you define a global variable for the entire pipeline and use it in your Jenkinsfiles.</p>
<p>Given a DSL library called <code>mylib</code> and a <a href="https://jenkins.io/doc/book/pipeline/shared-libraries/?ref=christoffer.soop.ch#defining-global-variables">global var</a> called <code>mavenPipeline</code> the Microservice <code>Jenkinsfile</code> could be as simple as this:</p>
<pre><code>@Library(&quot;mylib@latest&quot;) _
mavenPipeline(java: &apos;8&apos;)
</code></pre>
<p><em>Note the trailing underscore which is a package placeholder to which the annotation is attached!</em></p>
<p>Here we assume that <code>mavenPipeline</code> has parameter support for the java version to use. You can have others as well, if you like, but be careful not to repeat too many boilerplate settings!</p>
<p>Now, if there is a change to how the Microservice is built, how continuous delivery is done or perhaps if a new quality gate is added as a separate step, there is no need to change any of the Microservices. You just change the definition of the <code>mavenPipeline</code>.</p>
<p>Similar to how we handle the <code>Dockerfile</code> we can manage a custom <code>Jenkinsfile</code> if needed.</p>
<h1 id="anexample">An Example</h1>
<p>This Git repository contains a more complete example of a custom base image. It assumes Java based Microservices built by Maven but the concept should be easily adaptable to any language or platform.</p>
<ul>
<li><a href="https://github.com/chrsoo/microservices/blob/master/pom.xml?ref=christoffer.soop.ch">pom.xml</a> for building the image</li>
<li><a href="https://github.com/chrsoo/microservices/blob/master/bootstrap.sh?ref=christoffer.soop.ch">bootstrap.sh</a> docker entrypoint for launching the microservice</li>
<li><a href="https://github.com/chrsoo/microservices/blob/master/src/files/jmxremote.access?ref=christoffer.soop.ch">jmxremote.access</a> for configuring remote Java JMX access</li>
<li><a href="https://github.com/chrsoo/microservices/blob/master/src/files/logback.xml?ref=christoffer.soop.ch">logback.xml</a> for log configuration</li>
</ul>
<p>To build the base image you can launch</p>
<pre><code>mvn clean package
</code></pre>
<p>If you want to deploy the base image you need to</p>
<ul>
<li>Configure Maven <code>distributionManagement</code> settings; and</li>
<li>Make sure to change the <code>docker.namespace</code> to you Docker Hub account.</li>
</ul>
<p>If you are using a private registry you also need to update the <code>docker.registry</code> property and probably add credentials in Maven&apos;s <code>settings.xml</code> - YMMV!</p>
<p>Once Maven is properly configured you can then run...</p>
<pre><code>mvn clean deploy
</code></pre>
<p>... and Maven will happily deploy the (empty) JAR to your Maven registry and Docker image to Docker Hub or whatever you have configured.</p>
<p>Your Microservices should use <code>Dockerfile</code> along the lines of <a href="https://github.com/chrsoo/microservices/blob/master/Dockerfile.microservice?ref=christoffer.soop.ch">Dockerfile.microservice</a> in the root of each Microservice repository branch.</p>
<p><strong>(!) Note that the example requires Java 8 and Maven 3.5 to run!</strong></p>
<h2 id="jenkinsfile">Jenkinsfile</h2>
<p>The <a href="https://github.com/chrsoo/microservices/blob/master/Jenkinsfile?ref=christoffer.soop.ch">Jenkinsfile</a> will not work without you writing a custom DSL and adding the <code>mavenPipeline</code> global variable to your Jenkins instance.</p>
<p>Using a <code>Jenkinsfile</code> works best with a plugin like <a href="https://go.cloudbees.com/docs/plugins/bitbucket/?ref=christoffer.soop.ch">Bitbucket Branch Source Plugin</a> or similar so that all new repositories and branches are automagically discovered by Jenkins.</p>
<h2 id="pom">POM</h2>
<p>The Maven POM builds the Docker image using Spotify&apos;s  <a href="https://github.com/spotify/dockerfile-maven?ref=christoffer.soop.ch">dockerfile-maven-plugin</a>.</p>
<p>The POM is configured to</p>
<ul>
<li>Download all dependencies which are then added to the image</li>
<li>Create an executable JAR file which is also added to the image</li>
<li>Build the image if a Dockerfile is present using a Maven <code>docker</code> profile</li>
</ul>
<p>The base image pom.xml has two dependencies: the <a href="https://logback.qos.ch/?ref=christoffer.soop.ch">logback-classic</a> and <a href="https://github.com/logstash/logstash-logback-encoder?ref=christoffer.soop.ch">logstash-logback-encoder</a> libraries. These are shared by all our Microservices and are required for the  <a href="https://github.com/chrsoo/microservices/blob/master/src/files/logback.xml?ref=christoffer.soop.ch">logback.xml</a> configuration file.</p>
<p>The configuration found in the POM can be used both for building the base image and for building the Microservices, indeed given the use of a Maven <code>docker</code> <em>profile</em> it can be used for any Maven project with or without Dockerfiles.</p>
<p>In order to stay DRY the plugin configuration in the POM should be put in a parent pom shared by all Microservice projects. Or you will again end up with a WET solution...</p>
<h2 id="entrypoint">Entrypoint</h2>
<p>The <code>bootstrap.sh</code> shell script that serves as the docker image entry point.</p>
<p>It sets a few variables used for configuring the Microsevice and launches the microservice itself with a number of standard JVM arguments, including configuration of logback and JMX.</p>
<p>A nifty feature is that it will pass along all docker command line arguments to the Java runtime.</p>
<h1 id="lastwords">Last Words</h1>
<p>There are of course other solutions that still respect the DRY principle.</p>
<p>For example it might be preferable to get rid of the Dockerfile altogether. If you are building with Maven a good candidate is to use <a href="https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin?ref=christoffer.soop.ch">JIB</a>.</p>
<p>You could also get rid of the Jenkinsfile and implement auto discovery for Jenkins pipelines yourself but this seems like a rather cumbersome approach though. I would opt for an out-of-the-box solution that provisions build pipelines automatically.</p>
<p>I am not aware of any alternatives that do not use a Jenkinsfile, so it may be a good reason to look beyond Jenkins. Using another tool also has the benefit of not having to deal with Jenkins flavor of Groovy...</p>
<p>Any pointers on good alternatives that stay DRY for managing a large number of Git repositories and Dockerfiles are welcome!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Exception handling using enumerations in Java (II)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In the <a href="https://christoffer.soop.ch/java-enumerated-fault-exceptions">first part</a> of this blog post I discussed how Java Enumerations can be conveniently used as</p>
<ol>
<li>Fault codes in exceptions; and</li>
<li>Provide formatted and localized error messages</li>
</ol>
<p>The major drawback with the approach is that the fault codes make exception handling more complicated for cases when the same</p>]]></description><link>https://christoffer.soop.ch/exception-handling-using-enumerations-in-java-ii/</link><guid isPermaLink="false">645818765c4dcc000153cb5f</guid><category><![CDATA[Development]]></category><category><![CDATA[enumeration]]></category><category><![CDATA[exceptions]]></category><category><![CDATA[java]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Tue, 26 Apr 2016 21:56:19 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In the <a href="https://christoffer.soop.ch/java-enumerated-fault-exceptions">first part</a> of this blog post I discussed how Java Enumerations can be conveniently used as</p>
<ol>
<li>Fault codes in exceptions; and</li>
<li>Provide formatted and localized error messages</li>
</ol>
<p>The major drawback with the approach is that the fault codes make exception handling more complicated for cases when the same logic should be applied to different enumeration types.</p>
<p>This part of the blog post discusses a possible <strong>extension of Java Syntax</strong> for better exception handling when using enumeration fault codes.</p>
<p>First we need a way to distinguish the exceptions that support fault code enumerations from those that do not. We also need to indicate what type of fault code is supported by the exception. We therefore introduce a a new <code>Fault</code> interface from which all fault code exceptions must inherit:</p>
<pre><code>public interface Fault&lt;C extends Enum&lt;C&gt;&gt; {
    C code();
}
</code></pre>
<p>If we for a given application assume an <code>ApplicationFault</code> Exception class defined as</p>
<pre><code>public class ApplicationFault
extends RuntimeException
implements Fault&lt;ApplicationFault.Code&gt; {

    public enum Code {
        A1, A2, A3, A4
    }

    private final Code code;

    public ApplicationFault(Code code) {
            this.code = code;
    }

    @Override
    public Code code() {
        return code;
    }
}
</code></pre>
<p>&#x2026; we can then specify the fault code as constant values for the exception, i.e. something like</p>
<pre><code>try {
    // do something
} catch(ApplicationFault{A1, A2} | IOException e) {
    // handle ApplicationFault A1, A2 faults and IO Exceptions
} catch(ApplicationFault{A3} | IOException e) {
    // handle A3 faults
}
</code></pre>
<p>This new syntax should be interpreted as</p>
<ul>
<li>Handle all <code>ApplicationException</code>s for fault codes <code>Code.A1</code> and <code>A2</code> and<br>
<code>IOExceptions</code> in the same way</li>
<li>Handle <code>ApplicationException</code>s for <code>Code.A3</code> faults separately</li>
<li>Allow all <code>ApplicationException</code>s for <code>Code.A4</code> faults to propagate up the<br>
call chain</li>
</ul>
<p>(The <code>Code</code> enumeration type can be deduced from the <code>ApplicationException</code>.)</p>
<p>In addition, compile time errors would occur if</p>
<ul>
<li>Non-existing or the wrong enumeration fault codes for the class are referenced</li>
<li><code>ApplicationFault</code> does not implement <code>Fault</code></li>
<li><code>ApplicationFault</code> is a checked exception and not all fault codes are caught</li>
</ul>
<p>We could even take it one step further if Java would allow generic type parameters for Exception classes. (Exceptions in Java do not support generic type parameters as there is no evident use for them, but if we introduce fault codes they would start making sense.)</p>
<p>Let us assume that the JDK defines a generic <code>RuntimeFault</code>:</p>
<pre><code>public class RuntimeFault&lt;C extends Enum&lt;C&gt;&gt;
extends RuntimeException
implements Fault&lt;C&gt; {

    public RuntimeFault(C code, Object... args)  {
        ...
    }

    @Override
    public Code code() {
        ...
    }
}
</code></pre>
<p>We would then only need to define our fault codes in an enumeration (Localized or not), throw them as follows:</p>
<pre><code>throw new RuntimeFault&lt;CodeA&gt;(A1, arg0, arg1);
</code></pre>
<p>&#x2026; and catch them like so</p>
<pre><code>try {
    // do something
} catch(RuntimeFault&lt;CodeA&gt;{A1, A2} | RuntimeFault&lt;CodeB&gt; | IOException e) {
    // handle RuntimeFault for Code.A1 and A2 together with all CodeB faults and IO Exceptions
}
</code></pre>
<p>The main motivation for allowing generics in this way would be to have fewer exceptions. Instead of defining a new exception for each application or module with its own set of fault codes we would only define the fault codes and in most or all cases use the default <code>RutimeFault</code> exception class.</p>
<p>While this might be tempting we need to answer a number of questions introduced by the additional complication of allowing generics in exceptons:</p>
<ul>
<li>Would other exceptions besides <code>RuntimeFault</code> be allowed to be generic in the<br>
same way?</li>
<li>Would the generic type parameters be limited to enums? If not, what would that<br>
mean?</li>
<li>Should we perhaps allowing catching the interface <code>Fault</code> as well? What class<br>
object would be assumed in the catch clause?</li>
</ul>
<p>There are probably limitations related to type erasure and how the catch clause is implemented in Java that would answer these and other questions. Unfortunately I lack the insight to provide a good answer on the feasibility of any of the extensions suggested above.</p>
<p>In a <a href="http://tri-katch.blogspot.ch/2015/05/catch-code-proposal-to-expand-catch-in.html?m=1&amp;ref=christoffer.soop.ch">blog post from last year</a> the author proposes changes to Java 9 that pretty much attempts to solve the same problems as discussed in this post, but instead of using enum codes the solution is based on Strings. He actually goes as far as making a forked JDK to test the the new feature!</p>
<p>To catch the codes the author introduces a new syntax:</p>
<pre><code>} catch (CodedException | IOException ex, &quot;code4&quot;, &quot;code5&quot;) {
    ...
}
</code></pre>
<p>The <code>CodedException</code> class is required to be part of the catch clause for the codes to be caught.</p>
<p>To me the syntax is a bit clumsy as the <code>CodedException</code> is not kept together with the codes and using String constants is error prone. How do we known the fault code is ever thrown? With enumerations you get type safety and all codes has at least to be defined somewhere.</p>
<p>Last defining a single code is a bit more verbose, compare:</p>
<pre><code>public static final String CODE_A = &quot;error.code.a&quot;;
public static final FaultCode FAULT_CODE_A = new FaultCode(CODE_A, 1, &quot;error message: {0}&quot;);
</code></pre>
<p>&#x2026; as opposed to</p>
<pre><code>CODE_A(&quot;error message: {0}&quot;)
</code></pre>
<p>Granted, there is a little bit of overhead not shown where we store the <code>MessageFormat</code> in the enumeration but this is quickly regained when there are more than a few codes.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Exception handling using enumerations in Java (I)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>When I first read about Swift I quite liked its <a href="https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html?ref=christoffer.soop.ch">error handling</a>.</p>
<p>In Java checked exceptions have gotten quite a bad rep but instead of throwing out the baby with the bathwater and getting rid of checked exceptions altogether, the way they do it in Swift seems to strike a</p>]]></description><link>https://christoffer.soop.ch/java-enumerated-fault-exceptions/</link><guid isPermaLink="false">645818765c4dcc000153cb5e</guid><category><![CDATA[design]]></category><category><![CDATA[Development]]></category><category><![CDATA[enumeration]]></category><category><![CDATA[exception]]></category><category><![CDATA[java]]></category><category><![CDATA[pattern]]></category><category><![CDATA[swift]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Sun, 24 Apr 2016 15:56:51 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>When I first read about Swift I quite liked its <a href="https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html?ref=christoffer.soop.ch">error handling</a>.</p>
<p>In Java checked exceptions have gotten quite a bad rep but instead of throwing out the baby with the bathwater and getting rid of checked exceptions altogether, the way they do it in Swift seems to strike a good balance.</p>
<p>The thing that caught my eye however, was the use of <em>enumerations</em> instead of exception classes.</p>
<p>Using an enumeration as an error means that</p>
<ul>
<li>Errors have a natural code (the enum value)</li>
<li>Errors are grouped together in a single place (the enum type)</li>
<li>There is no need to create contrieved exception hierarchies to differentiate between different types of errors</li>
</ul>
<p>Fortunately Java has had enumerations since Java 5, an example exception using an enumeration fault code could look something like</p>
<pre><code>public final class ExampleException1 extends RuntimeException {

    public enum Code {
        ERROR_1,
        ERROR_2,
        ERROR_3;
    }

    public ExampleException1(Code code) {
            super(code.name());
    }
}
</code></pre>
<p>The exception message above will just be the name of the enumeration value (<code>ERROR_1</code> etc) which can work fine if the codes clearly indicate what the problem is. We can do better, however, by adding support for formatted messages and localization.</p>
<p>If we introduce an interface with default implementations for using <code>MessageFormat</code> and <code>ResourceBundle</code> we get more expressive messages without development overhead for creating new fault enumerations.</p>
<pre><code>public interface LocalizedFaultCode {

    // implementation provided &quot;for free&quot; by all enums
    public String name();

    // default Java 8 implementations do the &quot;heavy lifting&quot;
    default String getMessageKey() { ... }
    default String getDefaultFormat() { ... }
    default String getResourceBundleBaseName() { ... }
    default ResourceBundle lookupResourceBundle(Locale locale) { ... }
    default String getMessage(Object... args) { ... }
    default String getMessage(Locale locale, Object... args) { ... }
}
</code></pre>
<p>To use the interface our Exception example now becomes</p>
<pre><code>public final class ExampleException2 extends RuntimeException {

    public enum Code implements LocalizedFaultCode {
        ERROR_1,
        ERROR_2,
        ERROR_3;
    }

    public ExampleException2(Code code, Object... args) {
        super(code.getMessage(args));
    }

}
</code></pre>
<p>The default implementation would simply create error messages similar to <code>ERROR_1 [arg0, arg1, ...]</code>. In order to get formatted messages we would also need to create the corresponding <code>ResourceBundle</code> property files. The base name can be customized but defaults to the fully qualified class name of the enumeration code type.</p>
<p>ExampleException2$Code.properties:</p>
<pre><code>ERROR_1     = Error with one argument: {0}
ERROR_2     = Error with two arguments: {0}, {1}
ERROR_3     = Error with thre arguments: {0}, {1}, {2}
</code></pre>
<p>If message formats sound tempting but we would rather not define the required <code>ResourceBundle</code> property files that go with, we can opt to implement the method <code>default String getDefaultFormat() { ... }</code>:</p>
<pre><code>public enum Code implements LocalizedFaultCode {

    ERROR_1(&quot;Error with one argument: {0}&quot;),
    ERROR_2(&quot;Error with two arguments: {0}, {1}&quot;),
    ERROR_3(&quot;Error with three arguments: {0}, {1}, {2}&quot;);

    private String format;

    private Code(String format) {
        this.format = format;
    }

    @Override
    public String getDefaultFormat() {
        return format;
    }
}
</code></pre>
<p>We now have nicely formatted and potentially localized error messages all in one place.</p>
<p>Source code available in <a href="https://github.com/chrsoo/enum-exceptions?ref=christoffer.soop.ch">enum-exceptions</a> on GitHub.</p>
<p>While this is nice, what about exception handling? If we retrieve the fault code from the exception when we catch it, we can of course implement branching logic based on the value, e.g. something like:</p>
<pre><code>} catch(ExampleException1 e) {
    switch(e.code()) {
    case ERROR_1:
    case ERROR_2:
        // do something for error 2
        break;
    default:
        // else let it propagate up the call chain
        throw e;
    }
}
</code></pre>
<p>In some cases this will work just fine but if we want to handle different fault codes or ordinary exceptions the same way we are in a bit of a bind as the fault code approach effectively breaks the multicatch feature introduced in Java 7. The switch case above does for the fault code what the catch statement is already doing at the exception level.</p>
<p>Would it not be great if we could catch the code instead of the exception?</p>
<p>To do this we need to extend the Java syntax which is discussed in the <a href="https://christoffer.soop.ch/exception-handling-using-enumerations-in-java-ii">next post</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[What is Strategy?]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>As an assignment in the Strategy and Marketing course of my ongoing MBA studies we were required to give our personal view of what strategy is and I thought I should publish the result here. Part of the reading for the assignment included five articles from Harvard Business Review, three</p>]]></description><link>https://christoffer.soop.ch/what-is-strategy/</link><guid isPermaLink="false">645818765c4dcc000153cb5d</guid><category><![CDATA[mba]]></category><category><![CDATA[patching]]></category><category><![CDATA[rules]]></category><category><![CDATA[strategy]]></category><category><![CDATA[tactic]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Tue, 22 Feb 2011 21:30:28 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>As an assignment in the Strategy and Marketing course of my ongoing MBA studies we were required to give our personal view of what strategy is and I thought I should publish the result here. Part of the reading for the assignment included five articles from Harvard Business Review, three by Michel Porter and two by Kathleen Eisenhardt.</p>
<p>The three articles by Porter takes a high level perspective, defining strategy in terms of the nation state, the industry as a whole and strategy at the highest level of the enterprise. Essentially this is a top-down perspective, or perhaps one could call it outside-in. For Porter strategy is about making conscious trade-offs (what not to do), supported by a unique set of activities that reinforce each other and are difficult to reproduce, all in all creating a unique strategic position giving a sustainable competitive advantage (<em>What is Strategy</em>, p 70).</p>
<p>In the two articles by Eisenhardt et al strategy is something emergent, arising from the pattern of activities (patching and the application of simple rules). It is more about the internal strategy process than finding a strategic position. Essentially this is more of a bottoms-up perspective on strategy, or perhaps one could say inside-out.</p>
<p>Porter and Eisenhardt also differ in the time scale of strategy. Strategy in the eyes of Porter is long term; if a strategy does not lead to a sustainable advantage with a high performance outcome, it is not strategy or at least not <em>successful</em> strategy. As a counter point, the two articles by Eisenhardt et al discuss strategy with a shorter horizon (&#x201C;internet time&#x201D;).</p>
<p>The two following quotes make the differences particularly evident. In *Strategy as Simple Rules *(p 116), Eisenhardt says:</p>
<blockquote>
<p>Like all effective strategies, strategy as simple rules is about being different. But that difference does not arise from tightly linked activity systems or leveraged core competencies, as in traditional strategies. It arises from focusing on key strategic processes and developing simple rules that shape those processes. When a pattern emerges from the processes-a pattern that creates network effects or economies of scale or scope &#x2013; the result can be a long-term competitive advantage like the ones Intel and Microsoft achieved for over a decade. More often, the competitive advantage is short term.</p>
</blockquote>
<p>This is the exact opposite of what Porter says in *What is Strategy *(p 75):</p>
<blockquote>
<p>Strategy is creating fit among a company&#x2019;s activities. The success of a strategy depends on doing many things well-not just a few- and integrating among them. If there is no fit among activities, there is no distinctive strategy and little sustainability.</p>
</blockquote>
<p>Personally I tend to think about strategy in military terms: strategy is about winning the war; tactics however is about winning a battle. To me it seems like Eisenhardt&#x2019;s patching and simple rules are more about tactics and less about strategies. They tell you how to maneuver in everyday business but they do not tell you much about how competitive advantage can be sustained. For Eisenhardt, sustainable competitive advantage is reached more by accident than deliberate choice. Another way to look at it is that she discusses two strategies in particular, strategies that both serve well in a volatile business environment. By continuously reconfiguring the business to fit the current business environment (patching) and by creating simple rules allows an organization to maneuver with agility in the short term. It does not say anything about what the right direction or what business the company should be in. It is in effect, giving up strategy and focusing only on tactics. In Eisenhardt&#x2019;s view, this is the right choice since finding a sustainable strategic position is very difficult or even near impossible in todays accelerating business context.</p>
<p>An interesting, and I would say even somewhat damaging fact about <em>Strategy as Simple Rules</em>, is that several of the provided examples that in hindsight really should be considered strategic failures: Enron&#x2019;s simple rules were certainly not right since it eventually led the company to bankruptcy in 2001; Yahoo though being one of the dot-com stars have not done so great after the dot-com bubble burst and Dell is struggling with the competition that has imitated its business model with an innovative supply and channel management. Dell really is a case in point of Porter&#x2019;s argument on Operational Efficiency from <em>What is Strategy</em>. Although these examples do not invalidate her argument about the benefit of using simple rules, I believe it does illustrate rules more tactical than strategic nature.</p>
<p>The business impact of a more &#x201C;Porteresque&#x201D;, long term view of strategy is really that business should be clear on what business it is in. Trying to do things better or be more nimble is not a sustainable position; in the long term the pack will always catch up. Both Porter and Eisenhardt agree that strategy is about being different (<em>What is Strategy</em>, p 62 and the Eisenhardt quote above). This is something I believe to be almost trivially true: you will not be long term competitive by doing the same thing in the same way as everybody else. Thus a business has to think seriously on what it is doing, how it is doing it, who it is doing it for etc and make sure defends this position vigorously. To close with a another military analogy: a company has to choose its battles wisely.</p>
<p><em>Primary reference sources</em>:</p>
<p>Porter, M. (1996). What is strategy? *Harvard Business Review. *(November-December) p. 61-78.</p>
<p>Eisenhardt, K &amp; Sull, D. (2001). Strategy as simple rules. <em>Harvard Business Review</em>. (January) p. 106-116.</p>
<p><em>Secondary reference sources</em>:</p>
<p>Porter, M. (2008). The Five Competitive Forces that Shape Strategy. <em>Harvard Business Review</em>. (January) p. 78-93.</p>
<p>Porter, M. (1990). The Competitive Advantage of Nations. <em>Harvard Business Review</em>. (March-April) p. 73-93.</p>
<p>Eisenhardt, K. &amp; Brown, S. (1999). Patching. Restitch Business Portfolios in Dynamic Markets. <em>Harvard Business Review</em>. (May-June) p.72-82.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Diaspora Seeds]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Recently a couple of New York college students made a stir when they announced that they would write an open source and <strong>distributed</strong> social network server as an alternative to Facebook. This is really in the true spirit of the internet, where everyone can set up his or her own</p>]]></description><link>https://christoffer.soop.ch/diaspora-seeds/</link><guid isPermaLink="false">645818765c4dcc000153cb5c</guid><category><![CDATA[Architecture]]></category><category><![CDATA[internet]]></category><category><![CDATA[social network]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Mon, 17 May 2010 16:17:14 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Recently a couple of New York college students made a stir when they announced that they would write an open source and <strong>distributed</strong> social network server as an alternative to Facebook. This is really in the true spirit of the internet, where everyone can set up his or her own server and have them commicate, compare e.g. how email works. Incidentally, this is the way Instant Messaging should work but only SIP and Jabber (used by e.g. Google Talk) actually implement.<a href="http://www.kickstarter.com/projects/196017994/diaspora-the-personally-controlled-do-it-all-distr?ref=christoffer.soop.ch" title="Diaspora on Kickstarter"> Evidently they have raised about $170 000 in three weeks using Kickstarter, their initial target was $10 000</a>.</p>
<p>I sympathize 100% with their stated goals and will make sure I set up a Diaspora Seed once they make their first release.</p>
<p>More information on the <a href="http://joindiaspora.com/?ref=christoffer.soop.ch" title="Diaspora blog">Diaspora blog</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Toyota and Waterfall methdology for developing software]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>As you may know Agile software development is inspired by the principles of <a href="http://en.wikipedia.org/wiki/Lean_manufacturing?ref=christoffer.soop.ch" title="Lean Manufacturing">Lean Manufacturing</a> which in turn is derived from the <a href="http://en.wikipedia.org/wiki/Toyota_Production_System?ref=christoffer.soop.ch" title="Toyota Production System">Toyota Production System (TPS)</a>. One Agile methodology, <a href="http://en.wikipedia.org/wiki/Lean_software_development?ref=christoffer.soop.ch" title="Lean Software Development">Lean Software Development</a> even borrows the name Lean to make the connection explicit. Since the principles in Lean and TPS have</p>]]></description><link>https://christoffer.soop.ch/toyota-and-waterfall-methdology-for-developing-software/</link><guid isPermaLink="false">645818765c4dcc000153cb5b</guid><category><![CDATA[Agile]]></category><category><![CDATA[Development]]></category><category><![CDATA[Lean]]></category><category><![CDATA[Methodology]]></category><category><![CDATA[Toyota]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Wed, 17 Mar 2010 08:57:55 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>As you may know Agile software development is inspired by the principles of <a href="http://en.wikipedia.org/wiki/Lean_manufacturing?ref=christoffer.soop.ch" title="Lean Manufacturing">Lean Manufacturing</a> which in turn is derived from the <a href="http://en.wikipedia.org/wiki/Toyota_Production_System?ref=christoffer.soop.ch" title="Toyota Production System">Toyota Production System (TPS)</a>. One Agile methodology, <a href="http://en.wikipedia.org/wiki/Lean_software_development?ref=christoffer.soop.ch" title="Lean Software Development">Lean Software Development</a> even borrows the name Lean to make the connection explicit. Since the principles in Lean and TPS have much in common with how Japanese always have approached manufacturing and that TPS supposedly permeates the whole of Toyota, it comes as a real surprise that <a href="http://blog.crisp.se/henrikkniberg/2010/03/16/1268757660000.html?ref=christoffer.soop.ch#" title="Toyota&#x2019;s journey from Waterfall to Lean software development">Toyota uses a waterfall process for software development</a>!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[REST for Scott]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><em>At the thanksgiving dinner of a friend from work I tried to explain REST-ful applications &#x2013; and I think I failed miserably. Even though there are plenty of good introductions out there I felt I needed to organize my thoughts a bit. Having some spare time on the train on</em></p>]]></description><link>https://christoffer.soop.ch/rest-for-scott/</link><guid isPermaLink="false">645818765c4dcc000153cb5a</guid><category><![CDATA[Architecture]]></category><category><![CDATA[REST]]></category><category><![CDATA[Web]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Sat, 28 Nov 2009 08:07:22 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><em>At the thanksgiving dinner of a friend from work I tried to explain REST-ful applications &#x2013; and I think I failed miserably. Even though there are plenty of good introductions out there I felt I needed to organize my thoughts a bit. Having some spare time on the train on the way home I made a second, more structured attempt in the form of this blog post.</em></p>
<p>Imagine you are a web developer and is asked by a friend with a travel agency to help out create a web site for his company. Among the services on the site is a small web application for searching for hotels recommended by the agency. These hotels have been carefully vetted for the agency&#x2019;s customer segment and useful hotel information is stored in a database.</p>
<p>Let us assume the web application manages the namespace under the URL</p>
<blockquote>
<p><a href="http://qualitytravel.com/hotel?ref=christoffer.soop.ch">http://qualitytravel.com/hotel</a></p>
</blockquote>
<p>One way to construct the application is by storing e.g. navigation state in a server side session or as post parameters in the HTTP requests. Or maybe use an AJAX user interface where parts of the page is updated asynchronously in the background. These approaches are, however, incompatible with the basic requirement of you friend the the travel agent, who frequently copies the URL of a particular hotel and sends it per email to potential customers. He would also like his customers and all other users of the web site to be able to send URLs, create bookmarks etc. Only by creating stable, re-usable URL&#x2019;s is this easily accomplished. Thus you decide on a basic categorization scheme where each hotel is listed under</p>
<blockquote>
<p><a href="http://qualitytravel.com/hotel/?ref=christoffer.soop.ch">http://qualitytravel.com/hotel/</a><country-code>/<city>/<hotel-name></hotel-name></city></country-code></p>
</blockquote>
<p>Where <country-code> is the two letter ISO code for the country, <city> the city name in english using only ascii characters and <hotel-name> is a unique name of the hotel (unique at least within the country). By typing in a URL like</hotel-name></city></country-code></p>
<blockquote>
<p><a href="http://qualitytravel.com/hotel/se/stockholm/grand-hotel?ref=christoffer.soop.ch">http://qualitytravel.com/hotel/se/stockholm/grand-hotel</a></p>
</blockquote>
<p>&#x2026; in a web browser you would end up with the HTML page describing the Grand Hotel in Stockholm, Sweden.</p>
<p>Your friend is very ambitious but would like to start out small. Uptime is of course important but not critical and you offer to host the site on your server at your place for a minor fee per month. (This would help pay the electricity and internet connection bills.)</p>
<p>Now, your friend has a business partner who organizes conferences in different countries around the globe. The business partner would like to link to specific hotels on your site, hotels your friend has arranged special deals and have pre-booked a number of rooms for. Since you are using stable and predictable URLs this is no big deal, for any particular conference the business partner can easily add the reference on a web page, add them in emails sent out to the participants and even in printed hard copy.</p>
<p>As the partnership between your friend and his business partner deepens, the business partner would like tighter integration between the two web sites. In particular he would like to create a mashup application where each conference has a map with all the hotels printed at the correct geographic location. Since your friend has stored the exact geo location of each hotel in his database it should not be too difficult to achieve.</p>
<p>Being well versed in XML and enterprise standards you now ponder a bit on web services. You could of course create a web service with a method which would accept a list of hotel identifiers and return a list coordinates&#x2026; After some deliberation you come to the conclusion it would be easiest to use the URLs as identifiers. They are unambiguous and you do not have to expose the primary keys of the database to the internet and there is no need to create new unique external identifiers. On top of that adding the identifiers to the mashup will be easy since the URLs are already used on the conference web page.</p>
<p>Thinking a bit further you realize that in the future there potentially is&#xA0; more information which could be useful, not just the coordinates. Right now you do not know exactly what information that would be, but if you return a list of XML documents containing basic information on each hotel and with geo-coordinates, you can always expend the XML document format to include additional information at a later stage. At least as long you are careful to keep the format backwards compatible. This you do by not changing the meaning and syntax of the existing XML and make sure the XML elements have the same position relative to the root element (i.e. that the XPath for the elements is stable).</p>
<p>Finally, you realize that instead of taking the pain of having to create a web service with SOAP, WSDLs etc you decide that each hotel URL should return the corresponding XML if the client asks to get the hotel information in XML format instead of HTML. This can easily be accomplished by using the standard HTTP content negotiation, i.e. the client sends a list of desired formats and the server responds with a document in one of the formats if it can.</p>
<p>The changes to the existing application are relatively minor, you only need to implement the content negotiation feature and in addition to render HTML you will need a mechanism to render XML. (In Java, using servlets, servlet filters and a templateing mechanism sounds like a good approach.)</p>
<p>The result is a huge success. Business is booming for your friend and traffic to your server is increasing at an alarming rate. You are sure that any minute your ISP will knock on the door telling you you are violating the fair use clause of your contract. In addition, uptime is becoming more of a concern. If not for the load so at least for redundancy you need two servers. You decide to move the web site to a hosting facility. Since state is not kept in a server side session you realize that clustering will be trivial. Each request is independent of the previous meaning it can land on either server without complication. This also means adding more servers to handle a larger load will be a breeze.</p>
<p>Some time later your friend has found an additional business partner &#x2013; this guy for some reason wants to create an AJAX client which uses the hotel information. The AJAX guys, programming in client side Java script, do not really like XML and prefer something called JSON. Would it be possible to add JSON support? In addition it would be nice if you could create a downloadable PDF for each hotel&#x2026;</p>
<p>Having the infrastructure already set up, all is needed is to add two new rendering templates, one for JSON and one for PDF&#x2019;s and add the two new formats to the lists served by the server.</p>
<p>&#x2013;</p>
<p>*The above scenario describes using REST &#x2013; <strong>RE</strong>presentational <strong>S</strong>tate <strong>T</strong>ransfer &#x2013; for building a web application. The text strives to illustrate the fundamental REST-ful principle of decoupling the reference of an object from its actual representation. It can also be said that in REST you take a resource or document oriented approach to software development, i.e. development is data-driven. This is opposed to service orientation with an RPC style of defining interfaces where focus is not on the data but rather on what you do with data; the focus is on the verbs instead of the nouns. In REST the actions are a well defined minimum like the four most well known HTTP verbs: GET, POST, PUT and DELETE. Above, only the implied use of GET is shown.<br>
*</p>
<p><em>Using REST principles is not constrained to web applications. It has been suggested that REST should be used instead of SOAP based web services in a SOA architecture, thus imbuing some of the webs scalability and robustness in an Enterprise Integraion scenario. Gartner has termed it <a href="http://hinchcliffe.org/archive/2008/02/27/16617.aspx?ref=christoffer.soop.ch" title="Web Oriented Architecture">WOA</a> for Web Oriented Architecture. WOA can be seen as a more constrained version of SOA.</em></p>
<p><em>It has even been suggested that REST is useful within applications. How this can be done is described in <a href="http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart1&amp;ref=christoffer.soop.ch" title="A Restful Core">four articles</a> on <a href="http://www.theserverside.com/?ref=christoffer.soop.ch" title="The Server Side">The Server Side</a>. Beware though, although well written they end up being a plug for <a href="http://1060.org/?ref=christoffer.soop.ch" title="1060 Net Kernel">NetKernel</a>, a REST-ful application server built on something they call ROC &#x2013; Resource Oriented Computing. I would say the jury is still out on question whether using REST internally in an application is a good alternative or not.</em></p>
<p><em><strong>References</strong></em></p>
<p><em>Wikipedia has a well written article on REST:</em></p>
<p><em><a href="http://en.wikipedia.org/wiki/REST?ref=christoffer.soop.ch" title="Wikipedia on REST">http://en.wikipedia.org/wiki/REST</a></em></p>
<p><em>Web Oriented Architecture</em></p>
<p>*<a href="http://hinchcliffe.org/archive/2008/02/27/16617.aspx?ref=christoffer.soop.ch" title="What is WOA?">http://hinchcliffe.org/archive/2008/02/27/16617.aspx</a><br>
*</p>
<p>*The Server Side, A Restful Core:<br>
*</p>
<p><em><a href="http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart1&amp;ref=christoffer.soop.ch" title="A Restful Core, part 1">http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart1</a> <a href="http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart2&amp;ref=christoffer.soop.ch" title="A Restful Core, part 2"></a></em></p>
<p><a href="http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart2&amp;ref=christoffer.soop.ch">http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart2</a></p>
<p><a href="http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart3&amp;ref=christoffer.soop.ch" title="A Restful Core, part 3">http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart3</a><br>
<a href="http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart3&amp;ref=christoffer.soop.ch" title="A Restful Core, part 4">http://www.theserverside.com/tt/articles/article.tss?l=ARESTfulCorePart4</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[SOA is Dead (but the corpse is still kicking)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In a famous post from January this year (which I missed) Ann Thomas Manes declares SOA dead. She is a Reasearch Director within the Burton Group, has worked with SOA in the Burton Group and elsewhere, and is a co-author of the WS-* specifications.</p>
<p>The post has sparked fierce defense</p>]]></description><link>https://christoffer.soop.ch/soa-is-dead-but-the-corpse-is-still-kicking/</link><guid isPermaLink="false">645818765c4dcc000153cb58</guid><category><![CDATA[Architecture]]></category><category><![CDATA[REST]]></category><category><![CDATA[SOA]]></category><category><![CDATA[WOA]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Thu, 23 Apr 2009 11:03:06 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In a famous post from January this year (which I missed) Ann Thomas Manes declares SOA dead. She is a Reasearch Director within the Burton Group, has worked with SOA in the Burton Group and elsewhere, and is a co-author of the WS-* specifications.</p>
<p>The post has sparked fierce defense from vendors like Oracle. During the half day <a href="http://www.oracle.com/webapps/events/EventsDetail.jsp?p_eventId=90347&amp;src=6640143&amp;src=6640143&amp;Act=575&amp;ref=christoffer.soop.ch">SOA Architect forum in Geneva</a> this Tuesday, Oracle spent the first seminar repeating that &#x201C;SOA is not dead&#x201D; like a mantra, I guess in order to reinforce the message. It seemed to be one of the mayor points they wanted to get across.</p>
<p>Excerpt from Ann Thomas Manes post <a href="http://apsblog.burtongroup.com/2009/01/soa-is-dead-long-live-services.html?ref=christoffer.soop.ch">SOA is Dead; Long Live Services</a></p>
<blockquote>
<p>Successful SOA (i.e., application re-architecture) requires disruption to the status quo. SOA is not simply a matter of deploying new technology and building service interfaces to existing applications; it requires redesign of the application portfolio. And it requires a massive shift in the way IT operates. The small select group of organizations that has seen spectacular gains from SOA did so by treating it as an agent of transformation. In each of these success stories, SOA was just one aspect of the transformation effort. And here&#x2019;s the secret to success: SOA needs to be part of something bigger. If it isn&#x2019;t, then you need to ask yourself why you&#x2019;ve been doing it.</p>
<p>The latest shiny new technology will not make things better. Incremental integration projects will not lead to significantly reduced costs and increased agility. If you want spectacular gains, then you need to make a spectacular commitment to change. Like Bechtel. It&#x2019;s interesting that the Bechtel story doesn&#x2019;t even use the term &#x201C;SOA&#x201D;&#x2014;it just talks about services.</p>
<p>And that&#x2019;s where we need to concentrate from this point forward: Services.</p>
</blockquote>
<p>This falls in line with my understanding that SOA without BPR/BPM/Transformation really does not amount to much. You need the entire organization to support a process and service view on business and IT in order to see real benefit.</p>
<p>In another post <a href="http://broadcast.oreilly.com/2009/01/soa-is-dead-its-about-time.html?ref=christoffer.soop.ch">SOA is Dead? It&#x2019;s About Time</a> by Kurt Cagle acknowledges Ann Thomas Manes view but complements the picture with adding that</p>
<blockquote>
<p>Perhaps my biggest reservation about SOA had to be the fact that, at the end of the day, it was still an RPC model that concentrated primarily on calling APIs that differed from one provider to the next. The result of this thinking is the sea of APIs, where there are now tens of thousands of APIs, each of which doing things a little (or in some cases, a lot) differently from one another, with very little cohesion, and with little thought to the semantic complexity that comes when you have that many microlanguages all competing for programmer attention.</p>
<p>Purists may argue that over time the SOA model (especially the SOAP/WSDL model) had been moving towards a more messaging-oriented architecture, but I&#x2019;d counter that all that a messaging queue does is to decouple the receipt of the message from the response &#x2013; if the message processor invokes a service, it is still an RPC, especially when transactions are involved.</p>
<p>This is one of the reasons that I think that resource oriented services &#x2013; RESTful services &#x2013; are beginning to gain real traction even as the big-box SOA projects are falling to the accountant&#x2019;s axe. The publish/subscribe model in which what you&#x2019;re publishing are not blogs but data documents (think XBRL or HL7) performs the same type of decoupling that message-oriented SOA did, but completely abstracts the intent from the process of communication.</p>
</blockquote>
<p>This is consistent with my view that SOA, which if done correctly, should be document or data driven and should rely on messaging. As an alternative to an ESB used mainly for RPC over SOAP Web Services, I think that an REST-ful approach should be seriously considered when attempting SOA. Some thinkers at Gartner have started talking about a WOA &#x2013; Web Oriented Architecture &#x2013; as further constrained subset of the SOA approach based on REST principles.</p>
<p>I believe the change will be heavily resisted by companies like Oracle and IBM since there is less money to be made on the simpler and less tool/platform-intensive REST-ful approach to enterprise computing. Also they all have invested heavily in the WS-* and RPC-style SOA corner and thus are reluctant to change. But change will come sooner or later and the ongoing economical crisis will be a strong driver.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Universal Assembly Cache - Dependency Management for Mono and Microsoft.NET]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In the Java world there are several ways of handling dependencies between project components in a shared development environment. <strong>Maven</strong> is a generic build tool that creates a standardized way of creating, building and publishing component artifacts. Dependencies between the different components are declared in a Maven build file and</p>]]></description><link>https://christoffer.soop.ch/distributed-gac-dependency-management-for-mono-and-microsoftnet/</link><guid isPermaLink="false">645818765c4dcc000153cb57</guid><category><![CDATA[.NET]]></category><category><![CDATA[Build]]></category><category><![CDATA[Development]]></category><category><![CDATA[Tool]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Tue, 24 Feb 2009 13:40:16 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In the Java world there are several ways of handling dependencies between project components in a shared development environment. <strong>Maven</strong> is a generic build tool that creates a standardized way of creating, building and publishing component artifacts. Dependencies between the different components are declared in a Maven build file and Maven automatically downloads the dependencies and all transient dependencies recursively from local or public repositories. Repositories can be local to a particular developer, department or enterprise; or they can be public, available to the development community at large. <strong>Ivy</strong> is another utility which focus solely on dependency management. It is positioned as the lean and simple alternative to Maven which focus only on the dependency aspects and that integrates well with Ant (the generic java build tool).</p>
<p>For .NET based solutions there does not seem to be neither a Maven nor Ivy style dependency management system for development. This article outlines a solution to dependency management in the .NET world that has been inspired by the Maven and Ivy.</p>
<p><strong>Outline</strong></p>
<p>The Global Assembly Cache (GAC) is where .NET dependencies are handled. Assemblies installed in the GAC are made available for fulfilling the dependencies of DLL&#x2019;s inside or outside of the GAC. The GAC does not, however, reach outside one machine (real or virtual). In order to handle dependencies in a team development environment, where dependencies are shared, a distributed version of the GAC is envisioned, the Universal Assembly Cache or UAC.</p>
<p>The UAC is a repository with layout identical to the GAC but where dependencies can be downloaded using HTTP or FTP protocols and published using FTP or Web DAV. Repositories can be chained and when retrieving dependencies, chained repositories are searched in sequence one after another.</p>
<p><strong>Command line tools</strong></p>
<p>As for the GAC the UAC should have command line tools to manage the UAC. The command line tools would be used to download a DLL and all its dependencies not fulfilled by what is already installed in the GAC and then install the downloaded libraries. Likewise a DLL found in the file system or in the GAC could be published to the UAC and thus made available to other parties.</p>
<p>In addition MS DOS and command line tools the same functionality should be available as .NET PowerShell cmdlets. For mono on Linux, commands in a suitable script langue should be considered.</p>
<p><strong>Visual studio Add-On</strong></p>
<p>To facilitate dependency management during development a Visual studio add-on is used to check the references of each project in the solution. At startup, on demand or optionally for each build, unresolved references are searched for in the UAC and if found, installed in the GAC or put in a common solution folder. Ideally the Add-On is integrated as an additional tab in the Add Reference dialogue.</p>
<p>Similarly to Ivy and Maven, Visual Studio references to a given DLL can be to a specific version of a DLL or they can be according to some kind of dependency resolving strategy (Ivy latest strategy). As an example, the latest minor version of a component for a given major version can always be looked for. Switching to a new major version should be done manually since it is assumed this would nearly always break the build.</p>
<p>Publishing a DLL should not be possible through the add-on since publishing should be done in a more controlled environment than a developer desktop . Instead publishing should be done as part of an automated build system</p>
<p><strong>Build Tools</strong></p>
<p>In order to accommodate build engines all functionality required for a build should be replicated in NAnt and MS Build tasks. In addition there should be tasks for publishing DLL&#x2019;s to the repository.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Self programming language]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>A while ago I reflected on Object Oriented Programming and the fact that it really is more about classes than objects. Reading up on <a href="http://newspeaklanguage.org/?ref=christoffer.soop.ch" title="Newspeak">Newspeak</a>, the new langugage proposed by <a href="http://bracha.org/Site/Home.html?ref=christoffer.soop.ch">Gilad Bracha</a> I came across <a href="http://research.sun.com/self/language.html?ref=christoffer.soop.ch">Self</a>, one of the language on which Newspeak is indebted to. In Self no classes</p>]]></description><link>https://christoffer.soop.ch/self-programming-language/</link><guid isPermaLink="false">645818765c4dcc000153cb56</guid><category><![CDATA[Development]]></category><category><![CDATA[IT]]></category><category><![CDATA[language]]></category><category><![CDATA[oop]]></category><category><![CDATA[programming]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Wed, 01 Oct 2008 20:34:17 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>A while ago I reflected on Object Oriented Programming and the fact that it really is more about classes than objects. Reading up on <a href="http://newspeaklanguage.org/?ref=christoffer.soop.ch" title="Newspeak">Newspeak</a>, the new langugage proposed by <a href="http://bracha.org/Site/Home.html?ref=christoffer.soop.ch">Gilad Bracha</a> I came across <a href="http://research.sun.com/self/language.html?ref=christoffer.soop.ch">Self</a>, one of the language on which Newspeak is indebted to. In Self no classes exists, only objects. More on this later.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Crystal Clear - by Alistair Cockburn]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Crystal Clear is the smallest of a series of methodologies for software development, all created by Alistair Cockburn. It is smallest in the sense of the project size it addresses (up to eight developers) and in the number of things it prescribes. Other Methodologies, deriving their names from the colors</p>]]></description><link>https://christoffer.soop.ch/crystal-clear-by-alistair-cockburn/</link><guid isPermaLink="false">645818765c4dcc000153cb55</guid><category><![CDATA[Agile]]></category><category><![CDATA[Development]]></category><category><![CDATA[Lean]]></category><category><![CDATA[Method]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Wed, 09 Apr 2008 22:18:29 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Crystal Clear is the smallest of a series of methodologies for software development, all created by Alistair Cockburn. It is smallest in the sense of the project size it addresses (up to eight developers) and in the number of things it prescribes. Other Methodologies, deriving their names from the colors of crystal, are increasingly heavier. They all share the same &#x201C;DNA&#x201D; though, which is &#x201C;expressed&#x201D; differently with increasing project size and criticality, the latter meaning the higher cost in terms of money or at the extreme human life.</p>
<p>The book in itself has an interesting setup where each chapter addresses an aspect of Crystal Clear in a different format, tone and style. The purpose of this setup is to appeal to a large audience where each reader can find at least one chapter that conveys the essence of Crystal Clear to her clearly. The most peculiar chapter is probably the one where an ignorant Alistair queries a fictive Crystal character over a series of letters about the inner workings of a successful software development team; thus mimicking a Socratic dialogue. I am not sure this stunt works in practice, but at least true to the intent some chapters work better for me than others&#x2026; All chapters are, however, still written in an easy and personal prose.</p>
<p>In the first chapter Cockburn discusses methodologies in the context of the skill set of the practitioner &#x2013; somebody who masters software development probably need not pay too close attention to the exact steps in any given methodology since she understands the deeper principles and is able to derive what actions are needed from the principles in any given context. True to this the book&#x2019;s reading instructions call readers experienced in Agile development methods to read the last chapter first and then (after they stop smirking) go back to read certain key chapters. Knowing something about Scrum and XP this is exactly what I did, including the smirking part&#x2026;</p>
<blockquote>
<p>Chapter 9</p>
<p>Distilled (The Short Version)</p>
<p>At the end it is time to roll it all back up again: What is the core of Crystal Clear, and what puts the team farther into the safety zone? This chapter is very short.</p>
<p>Crystal Clear is a highly optimized way to use a small, co-located team, prioritizing for efficiency, habitability, and safety in delivering a satisfactory outcome. The brief description of Crystal Clear for level-3 practitioners is just this:</p>
<p>The lead designer and two to seven other developers<br>
in a large room or adjacent rooms,<br>
using information radiators such as whiteboards and flip charts,<br>
having easy access to expert users,<br>
distractions kept away,<br>
deliver running, tested, usable code to the users<br>
every month or two (quarterly at worst)<br>
reflecting and adjusting their working conventions periodically.</p>
<p>The team members establish the safety properties below using the techniques they consider appropriate. The first three properties are required in Crystal Clear, the next four get the team further into the safety zone.</p>
<p>1.Frequent Delivery<br>
2.Reflective Improvement<br>
3.Osmotic Communication<br>
4.Personal Safety<br>
5.Focus<br>
6.Easy Access to Expert Users<br>
7.A Technical Environment with Automtaded Tests, Configuration Management, and Frequent Integration</p>
<p>All the other pages in this book only expand on this page.</p>
</blockquote>
<p>The above is the entire chapter and it really does succeed in summarizing Crystal Clear.</p>
<p><strong>Patterns</strong></p>
<p>Crystal Clear does not require any particular techniques but Cockburn still mentions a number of patterns of particular importance or not often seen elsewhere (according to the author). The patterns are divided in Strategies and Techniques. I find the Exploratory 360&#x2DA;, Early Victory, Blitz Planning, Process Miniature and Side-by-Side Programming the most novel and interesting. Others like Walking Skeleton (aka Tracer Bullet or Spanning Application), Incremental Rearchitecture, Information Radiators, Methodology Shaping, Reflection Workshop, Daily Stand-Up Meetings and Burn Charts are, at least to me, well known from other Methodologies such as Scrum and may be considered standard practice; i.e. they are good patterns but hardly novel or unique in Crystal. The two remaining techniques Delphi Planning Using Expert Rankings and Essential Interaction Design are a bit too involved to my taste but may serve their purpose in some circumstances.</p>
<p><em>Exploratory 360&#x2DA;</em><br>
Simply put the Exploratory 360&#x2DA; strategy means that the project team should perform a gap analysis on all that is required to run a project successfully. In particular it also means to cover topics that really are the responsibility of others outside the development team, like the fact that there is proper funding and that the proposed project really has a clear recipient who wants the project to succeed. Cockburn supplies a list of the most common things to check for but there may be additional things particular to the organization or the project&#x2019;s circumstances. If the gaps revealed are too wide or many the project can (and probably should) be terminated early and if nobody else have brought this to management&#x2019;s attention it is the responsibility of the development team.<br>
The Exploratory 360&#x2DA; strategy is something that is close to being self evident but I would guess often forgotten when starting a new project.</p>
<p><em>Early Victory</em><br>
Many projects start out with the most difficult tasks first in order to minimize the risks. While this may be sound in theory, giving the team members an easy task to start with will boost morale when the team succeeds in it as well as show the sponsor(s) that the team is performant. Addressing the most difficult task first and then failing can be catastrophic for the team&#x2019;s spirits and very late first delivery may erode the team&#x2019;s credibility.<br>
While I have given team&#x2019;s easier tasks to start with in order to get things going I have never thought of it in terms of an Early Victory and as a reason to celebrate.</p>
<p><em>Blitz Planning</em><br>
The Blitz Planning technique is similar to XP&#x2019;s planning game or Scrum&#x2019;s Sprint Planning but Blitz Planning uses index cards in a new, creative way. The project sponsor, developers and end users gather together and brainstorm on all the tasks that need to be done to deliver the system. Cards are collated and duplicates removed. The developer most likely to perform a task should make estimate on how long it will take to perform it. The tasks are then arranged in sequence on a large table parallel tasks are placed side-by-side and sequential tasks top to bottom. The sequence is divided in iterations and releases and cards are moved around to optimize development, to fit the sponsor&#x2019;s priorities, make an Early Victory or a Walking Skeleton and so on. The planning may very well reveal the need for additional resources, change in scope etc. The outcome of the Blitz planning is a draft project plan.<br>
What I like with the Blitz Planning is the simple and cooperative fashion in which the project plan is derived. Using index cards on a table makes changes easy and the result is very graphical.</p>
<p><em>Process Miniature</em><br>
In order to learn a lengthy and/or complicated process a miniature version of the process may be run in a few minutes to a few days depending on the process being learned. If it is a development process, only trivial functionality may be developed or what is being built may simply be faked. Using Process Miniature is a variation of learning by doing but where the learning is substantially accelerated.</p>
<p><em>Side-by-Side Programming</em><br>
In Pair Programming is a controversial technique in Extreme Programming. Some people find Pair Programming wasteful though proponents of XP claims it saves time in the end due to the lesser number of defects found in the final product. While this may be true some people simply do not like to program in pairs. An alternative to Pair Programming is Side-by-Side Programming where two developers sitting side-by-side with workstation of their own, helping out and reviewing code continuously. A similar effect as with Pair Programming is achieved but possibly with less wasted time.</p>
<p><strong>Summary</strong></p>
<p>What is interesting about the Crystal series of Methodologies (Clear, Yellow, Orange, Red) for software development is that they are founded on Alistair Cockburn&#x2019;s interviews of people in successful software development projects, often in a fixed price, fixed scope contract situation. Agile methods are adaptive and often at their best in an explorative situation where the neither the scope nor the resources required are known beforehand. Thus Agile Methodologies are difficult to handle with a fixed price and scope. This begs the question as exactly what makes Crystal different. After reading the Crystal Clear I am still not clear on exactly why it should work better in fixed price and scope situation &#x2013; the only reason seems to be developer participation in making estimates and a focus on always producing a workable system. And this is something that Crystal shares with all Agile methods.<br>
Crystal Clear is probably the lightest of the Agile Methodologies I have come in contact with so far (mostly Scrum and XP) and this makes it true to its intent &#x2013; it really is the minimum set of rules that could possibly work.</p>
<p>Since Clear only is applicable for projects up to eight developers due to its requirement of Osmotic Communication and many projects are substantially larger, it would be interesting to see how the &#x2018;genetic code&#x2019; is adapted to fit larger projects. I guess I must read Cockburn&#x2019;s other books as well&#x2026;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[100 sidor för dig som hellre käkar taggtråd än kontaktar en kund]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I <em>100 sidor f&#xF6;r dig som hellre k&#xE4;kar taggtr&#xE5;d &#xE4;n kontaktar kunder</em> ger Carola Forshell en grundl&#xE4;ggande lektion i hur en s&#xE4;ljprocess f&#xF6;r f&#xF6;rs&#xE4;ljning till f&#xF6;retag b&#xF6;r l&#xE4;</p>]]></description><link>https://christoffer.soop.ch/100-sidor-for-dig-som-hellre-kakar-taggtrad-an-kontaktar-en-kund/</link><guid isPermaLink="false">645818765c4dcc000153cb54</guid><category><![CDATA[Business]]></category><category><![CDATA[Sales]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Tue, 25 Mar 2008 11:18:07 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I <em>100 sidor f&#xF6;r dig som hellre k&#xE4;kar taggtr&#xE5;d &#xE4;n kontaktar kunder</em> ger Carola Forshell en grundl&#xE4;ggande lektion i hur en s&#xE4;ljprocess f&#xF6;r f&#xF6;rs&#xE4;ljning till f&#xF6;retag b&#xF6;r l&#xE4;ggas upp. Boken &#xE4;r baserad p&#xE5; hennes personliga resa, fr&#xE5;n n&#xE5;gon som avskyr s&#xE4;lj till en som arbetar som s&#xE4;ljare p&#xE5; heltid och dessutom utbildar andra i konsten att s&#xE4;lja.</p>
<p>Uppl&#xE4;gget utg&#xE5;r fr&#xE5;n en rekommenderad s&#xE4;ljprocess med b&#xF6;rjan i identifiering av potentiella kunder (prospekts) till avslutande faktura med p&#xE5;f&#xF6;ljande merf&#xF6;rs&#xE4;ljning. Varje steg hanteras i ett eget kapitel och i appendix &#xE5;terfinns mallar och checklistor. Som motvikt till denna idealt strukturerade process kryddar f&#xF6;rfattaren boken med anekdoter fr&#xE5;n egna misslyckanden inom s&#xE4;lj. Vad man m&#xF6;jligen kan sakna &#xE4;r mer en ing&#xE5;ende diskussion om de problem som kan uppst&#xE5; l&#xE4;ngs v&#xE4;gen och hur man b&#xE4;st kan hantera dessa, men kanske det med r&#xE4;tta faller utanf&#xF6;r denna f&#xF6;rsta introduktion.</p>
<p>Bokens titel &#xE4;r dessv&#xE4;rre, om &#xE4;n fyndig, n&#xE5;got missvisande. Alla som &#xE4;r intresserade av att l&#xE4;ra sig en mer strukturerad s&#xE4;ljprocess har nytta av boken, inte bara de som hellre k&#xE4;kar taggtr&#xE5;d &#xE4;n kontaktar kunder. De som faktiskt r&#xE5;kar ha en fobisk inst&#xE4;llning har inte mer hj&#xE4;lp av boken &#xE4;n det exempel f&#xF6;rfattaren sj&#xE4;lv utg&#xF6;r p&#xE5; att det faktiskt g&#xE5;r att &#xF6;vervinna sin egen r&#xE4;dsla och ett par grundl&#xE4;ggande tips. Tips som exempelvis det st&#xF6;d man har i att vara v&#xE4;l f&#xF6;rberedd inf&#xF6;r ett m&#xF6;te och att skapa en enkel ritual kring kalla samtal f&#xF6;r att inte f&#xF6;rhala processen.<br>
Detta till trots &#xE4;r boken mycket l&#xE4;sv&#xE4;rd &#x2013; b&#xE5;de l&#xE4;rorik och underh&#xE5;llande. Jag rekommenderar den varmt till andra tekniker likt mig sj&#xE4;lv eller andra som s&#xF6;ker en introduktion till s&#xE4;lj.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Beyond Software Architecture - Creating and Sustaining Winning Solutions - by Luke Hohmann]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In <em>Beyond Software Architecture</em>, Luke Hohmann addresses all things paramount to software product development that are usually not covered in books on software development. These things include licensing, software protection, branding, marketing and business plans and how they relate to the technical architecture and more. Every developer or architect that</p>]]></description><link>https://christoffer.soop.ch/beyond-software-architecture-creating-and-sustaining-winning-solutions-by-luke-hohmann/</link><guid isPermaLink="false">645818765c4dcc000153cb53</guid><category><![CDATA[Business]]></category><category><![CDATA[Development]]></category><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Mon, 24 Mar 2008 00:17:23 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In <em>Beyond Software Architecture</em>, Luke Hohmann addresses all things paramount to software product development that are usually not covered in books on software development. These things include licensing, software protection, branding, marketing and business plans and how they relate to the technical architecture and more. Every developer or architect that has been around a few projects probably will probably recognize the importance of some, if not all of these areas, in relation to creating and sustaining a winning solution.</p>
<p>The first and probably most important topic covered is the relation between the business model and the technical architecture. It is really an understatement to claim that the chosen business model has a serious and real impact on the technical architecture &#x2013; it should be self evident that there the architecture will look quite different in an ASP scenario and a single user desktop application&#x2026; Less self evident is the relation between the business plan and the technical architecture. What business segments are being targeted and in which order really does bear on the architecture. Each business segment will have its particular needs to be addressed as features in the software solution. The order is important since it will help spell out the technical roadmap for future releases.</p>
<p>The book covers a large number of topics and gives advice on a number of specific issues, too many to cover here. I have chosen but a few that have stuck after finishing the book.</p>
<p><strong>Marketecture</strong></p>
<p>The relation between development and business is generally acknowledged to be difficult and fraught with miscommunication and misalignment of goals. There are many books and methods addressing this gap between IT and business. Hohmann contribution to closing this gap is to distinguish between what he refers to as the Marketecture and the Tarchitecture. The Tarchitecture is short for technical architecture and its definition is similar to what other refer to as system or application architecture, i.e. it covers things like components and their relations, which patterns are used for what parts of the application, technologies, platforms and so forth. The Marketecture should contain all things related to the business side of the system or application. This includes business segments, the business model and plan, user manuals, marketing materials etc.</p>
<p>Closely related to the two architectures are the corresponding roles, the Marketect and the Tarchitect. The Marketect role is usually shouldered by the product owner, business manager or similar whereas the Tarchitect is the traditional systems or application architect or perhaps in some cases an IT-manager. It is rare for the two roles to be handled by the same person since the two perspectives can be difficult for one person to manage simultaneously.</p>
<p>The Marketect and Tarchitect should work closely together to create the Marketecture and the Tarchitecture. This is of course easier said than done, but to me the value of Hohmann&#x2019;s definitions is primary in making the Marketecture needs visible. Coming from the IT-side, I believe this too often be neglected by the business side and often poorly understood by development.</p>
<p><strong>Capabilities versus features</strong></p>
<p>A minor point made by Hohmann (and perhaps trivial to many architects but enlightening to me) is the difference between a systems capabilities and features. The system&#x2019;s capabilities are all the functionality made possible by a certain technical architecture whereas the systems features are the features actually implemented. Implementing a feature where the system lacks the capability means changing the underlying architecture. To me this seems different from the anti-pattern designing for the future. A good architecture has relevant capabilities making implementing the desired features easy, but this does not mean that a lot of time has been spent on implementing features that are not needed. It simply means that sound architectural choices have been made creating a sound system. This could be a fine line, however, since making constraining choices that limits the system&#x2019;s capability, are sometimes necessary.</p>
<p><strong>Release checklist</strong></p>
<p>In appendix 1 a release checklist is found, summarizing the many of the core concepts in the book. This checklist seems like a sound thing to run through not only before each release, but also at the start of a development effort. Running through the list just prior to a release it may be too late to take care of things missed i.e. it will incur what can be referred to as a technological debt (a term used in the book but first defined by Ward Cunningham). Incurring a technological debt means that the development team will have to work harder in the next release to fix the things missed in the previous release and that quality suffers.</p>
<p><strong>Patterns</strong></p>
<p>The book sports A Pattern Language for Strategic Product Management found in the appendix. This pattern language defines common problems related to product development and proposes simple solutions. More thorough descriptions of the problems and the proposed solutions can be found in the beginning of the book.</p>
<table><tr><th>Pattern</th><th>Problem</th><th>Solution</th></tr><tr><td>Market Map</td><td>How do you segment your market?</td><td>Create a visual representation of the market(s) you are targeting</td></tr><tr><td>Market Events or Market Rhythms</td><td>What is the right frame of reference for time in your problem domain?</td><td>Identify the events and rhythms of your market/markets segments</td></tr><tr><td>Feature/Benefits map</td><td>How do you ensure that the right features and benefits are being created for your target market(s)?</td><td>Create a map of the proposed features and their benefits. Tie these to the market(s) you are targeting.</td></tr><tr><td>Tarchitecture Roadmap</td><td>How do you manage the evolution of your technical architecture?</td><td>Create a roadmap of know technology trends. Include specific and well-known changes you want to make to your architecture so that everyone can plan for them</td></tr></table>As a pattern language it is quite small and it can probably be expanded with additional patterns.
<p><strong>Usability</strong></p>
<p>Hohmann addresses usability in a chapter of its own. Usability in this context goes beyond user interface design and has a deeper, structural meaning. He stresses the need of a good metaphor that should permeate the whole architecture. This is reminiscent of the thoughts behind Domain Driven Design, though this is not mentioned in the book. A usable application or system should cater to the real users as found in each market segment. An application sold to two different segments may be very usable to one, but not to another. Consider for example an application that targets both an expert and amateur segment. Helpful wizards that guides the user through difficult steps may be very useful to the amateur but not to the expert or power user.</p>
<p><strong>Summary</strong></p>
<p>Beyond Software Architecture is a good read for architects and developers who wish to expand their view on Software architecture and development. It succeeds in addressing issues often neglected elsewhere in literature on software development. As with many more high level books, however, I believe the business side to benefit most from this book. A better understanding on the business choices and their technical consequences is often needed and the need for seriously addressing the business and technological should be recognized.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Map Reduce, Grid Computing and Next Generation Application Servers]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>While browsing the <a href="http://theserverside.com/?ref=christoffer.soop.ch">The Server Side&#x2019;s</a> list of <a href="http://www.theserverside.com/news/thread.tss?thread_id=47967&amp;ref=christoffer.soop.ch">Most Requested Content for 2007</a> I ended up reading about Google&#x2019;s algorithm MapReduce, Grid Computing and Giga Spaces. For the (admittedly rare) cases where the applications really have to scale to huge loads (read Google, eBay etc) JEE</p>]]></description><link>https://christoffer.soop.ch/map-reduce-grid-computing-and-next-generation-application-servers/</link><guid isPermaLink="false">645818765c4dcc000153cb52</guid><dc:creator><![CDATA[Christoffer Soop]]></dc:creator><pubDate>Thu, 03 Jan 2008 21:30:32 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>While browsing the <a href="http://theserverside.com/?ref=christoffer.soop.ch">The Server Side&#x2019;s</a> list of <a href="http://www.theserverside.com/news/thread.tss?thread_id=47967&amp;ref=christoffer.soop.ch">Most Requested Content for 2007</a> I ended up reading about Google&#x2019;s algorithm MapReduce, Grid Computing and Giga Spaces. For the (admittedly rare) cases where the applications really have to scale to huge loads (read Google, eBay etc) JEE app servers do not seem to cut it. This is probably because there is no support for Grid Computing /massive parallellization.</p>
<p>Being a Spring advocate I am not at all surprised to read that there are some people that feels the time is ripe to replace JEE application servers with something new. <a href="http://www.kimchy.org/scalability-mythbusters/?ref=christoffer.soop.ch">Kimchy</a> believes the <a href="http://www.gigaspaces.com/?ref=christoffer.soop.ch">Giga Spaces</a> /<a href="http://gigaspaces.com/wiki/display/GS6/Open+Spaces?ref=christoffer.soop.ch">Open Spaces</a> is a precursor to such a next generation application server, much like Hibernate was to JPA.</p>
<p>I am not sure whether something like Open Spaces will replace JEE App Severs anytime soon (I need to read up on these, for me, new enterprise patterns in general and the Open Spaces project in particular) but I do agree in his thoughts there is a need to simplify and coordinate many of the services needed to develop a truly scalable application in a new app server like container. A container where something resembling JEE packaging can be used to deploy and manage applications.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>