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

<channel>
	<title>Java Application Architecture</title>
	<atom:link href="http://www.kirkk.com/modularity/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kirkk.com/modularity</link>
	<description>Modularity Patterns with Examples Using OSGi</description>
	<lastBuildDate>Tue, 10 Apr 2012 14:09:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Foreword by Uncle Bob</title>
		<link>http://www.kirkk.com/modularity/2011/12/foreword-by-uncle-bob/</link>
		<comments>http://www.kirkk.com/modularity/2011/12/foreword-by-uncle-bob/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 17:29:17 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=939</guid>
		<description><![CDATA[I&#8217;m dancing!  By god I&#8217;m dancing on the walls.  I&#8217;m dancing on the ceiling.  I&#8217;m ecstatic.  I&#8217;m overjoyed.  I&#8217;m really, really pleased.
&#8220;Why?&#8221; you ask.  Well, I&#8217;ll tell you why &#8212; since you asked.  I&#8217;m happy because somebody finally read John Lakos&#8217; book!
Way back in the ‘90s, John Lakos [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m dancing!  By god I&#8217;m dancing on the walls.  I&#8217;m dancing on the ceiling.  I&#8217;m ecstatic.  I&#8217;m overjoyed.  I&#8217;m really, really pleased.</p>
<p>&#8220;Why?&#8221; you ask.  Well, I&#8217;ll tell you why &#8212; since you asked.  I&#8217;m happy because <em>somebody finally read John Lakos&#8217; book!</em></p>
<p>Way back in the ‘90s, John Lakos wrote a book entitled Large Scale C++ Software Design.  The book was brilliant.  The book was groundbreaking.  The book made the case for large scale application architecture and made it well.</p>
<p>There was just one problem with John’s book.  The book had “C++” in the title; and it was published just as the software community was leaping to Java.  And so the people who really needed to read that book &#8212; didn’t read it.</p>
<p>Ah, but then the people doing Java back then weren’t reading any books on software design, because they were all 22 years old, sitting in Herman-Miller office chairs, hacking Java, day trading, and dreaming of being billionaires by the time they were 23.  Oh god, they were such hot stuff!</p>
<p>So here we are, over a decade later.  We’ve matured a bit.  And we’ve failed a bit.  And our failures have winnowed and seasoned us.  We now look back at the wasteland of Java architectures we created and grimace.  How could we have been so naïve?  How could we have lost sight of the principles of Jacobson, Booch, Rumbaugh, Fowler, and Lakos.  Where did we go wrong?</p>
<p>I’ll tell you where we went wrong.  The web bamboozled us.  We all got twitterpated.  We thought the web was revolutionary.  We thought the web changed everything.  We thought the web made all the old rules irrelevant.  We thought the web was so new, so revolutionary, so game changing, that we ignored the rules of the game.</p>
<p>And we paid.  Oh God how we paid.  We paid with huge unmanageable designs.  We paid with tangled messy code.  We paid with misguided directionless architectures.  We paid with failed projects, bankrupt companies, and broken dreams.  We paid, and we paid, and we paid.</p>
<p>It took 15 years; and we’ve just begun to realize why.  We’ve just begun to see that the game hasn’t changed at all.  We’ve begun to see that the web is just another delivery mechanism, no different from all the others &#8212; a reincarnation of the old IBM green-screen request/response technology.  It was just plain old software after all, and we should never have abandoned the rules of the game.</p>
<p>Now we can see that we should have stuck to the wisdom of Parnas, Weinberg, Page-Jones, and DeMarco all along.  We should never have walked away from the teachings of Jacobson and Booch.  And we should have read that damned book by Lakos!</p>
<p>Well, somebody did read that book.  And he must have read a few others too because he’s written a book that states the rules of the Java Architecture game better than I’ve seen them stated before.  You’re holding that book in your hands right now.  The man who wrote it is named Kirk Knoernschild.</p>
<p>In this book Kirk has gone beyond Lakos, beyond Jacobson, beyond Booch.  He’s taken the principles of those past masters and created a brilliant new synthesis of principles, rules, guidelines and patterns.  This is how you build a Java application people.</p>
<p>Go ahead and flip through the pages.  Notice something?  Yeah: No fluff!  It’s all hard-core.  It’s all right to the point.  It’s all pragmatic, useful, necessary!  It’s all about the nuts and bolts architecture of java applications – the way it should be: Modular,  decoupled, level-ized, independently deployable, and smart.</p>
<p>If you are a java programmer; if you are a tech-lead or a team-lead; if you are an architect, if you are someone who wants and needs to make a difference on your software development team; read this book.  If you want to avoid repeating the tragedy of the last 15 years, read this book.  If you want to learn what software architecture is really all about: read    this    book!</p>
<p>Nuff said.<br />
Uncle Bob<br />
35,000 feet over the Atlantic.</p>
<p>1 October, 2011.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2011/12/foreword-by-uncle-bob/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Chapter 18 &#8211; OSGi and Groovy</title>
		<link>http://www.kirkk.com/modularity/2011/01/chapter-18-osgi-and-groovy/</link>
		<comments>http://www.kirkk.com/modularity/2011/01/chapter-18-osgi-and-groovy/#comments</comments>
		<pubDate>Mon, 24 Jan 2011 18:39:44 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=813</guid>
		<description><![CDATA[
package com.extensiblejava.calculator.groovy

import com.extensiblejava.loan.*

class MinimumPaymentScheduleCalculator implements LoanCalculator {
	def paymentFactory

	MinimumPaymentScheduleCalculator(pFactory) {
		paymentFactory = pFactory
	}

	def Loan calculateLoan(BigDecimal presentValue, BigDecimal rate, int term) {

		println(&#34;---** IN GROOVY CALCULATOR **---&#34;)

		def cumulativePrincipal = new BigDecimal(&#34;0.00&#34;)
		def cumulativeInterest = new BigDecimal(&#34;0.00&#34;)

		def paymentSchedule = paymentFactory.createPaymentSchedule()
		def adjustedRate = (rate / (new BigDecimal(&#34;1200&#34;)).setScale(2, BigDecimal.ROUND_HALF_UP))
		def calculator = new MonthlyPaymentCalculator()
		def monthlyPayment = calculator.calculatePayment(presentValue, rate, term)

		def loanBalance = new BigDecimal(presentValue)

		while (loanBalance.doubleValue() [...]]]></description>
			<content:encoded><![CDATA[<pre class="brush: java;">
package com.extensiblejava.calculator.groovy

import com.extensiblejava.loan.*

class MinimumPaymentScheduleCalculator implements LoanCalculator {
	def paymentFactory

	MinimumPaymentScheduleCalculator(pFactory) {
		paymentFactory = pFactory
	}

	def Loan calculateLoan(BigDecimal presentValue, BigDecimal rate, int term) {

		println(&quot;---** IN GROOVY CALCULATOR **---&quot;)

		def cumulativePrincipal = new BigDecimal(&quot;0.00&quot;)
		def cumulativeInterest = new BigDecimal(&quot;0.00&quot;)

		def paymentSchedule = paymentFactory.createPaymentSchedule()
		def adjustedRate = (rate / (new BigDecimal(&quot;1200&quot;)).setScale(2, BigDecimal.ROUND_HALF_UP))
		def calculator = new MonthlyPaymentCalculator()
		def monthlyPayment = calculator.calculatePayment(presentValue, rate, term)

		def loanBalance = new BigDecimal(presentValue)

		while (loanBalance.doubleValue() &gt; monthlyPayment.doubleValue()) {
			def interest = loanBalance.multiply(adjustedRate).setScale(2, BigDecimal.ROUND_HALF_UP)
			def principal = monthlyPayment.subtract(interest).setScale(2, BigDecimal.ROUND_HALF_UP)
			def payment = paymentFactory.createPayment(principal, interest)
			paymentSchedule.addPayment(payment)

			cumulativeInterest = cumulativeInterest.add(interest).setScale(2, BigDecimal.ROUND_HALF_UP)
			cumulativePrincipal = cumulativePrincipal.add(principal).setScale(2, BigDecimal.ROUND_HALF_UP)
			loanBalance = loanBalance.subtract(principal)
		}
		def interest = loanBalance.multiply(adjustedRate).setScale(2, BigDecimal.ROUND_HALF_UP)
		def principal = loanBalance.setScale(2, BigDecimal.ROUND_HALF_UP)
		cumulativeInterest = cumulativeInterest.add(interest).setScale(2, BigDecimal.ROUND_HALF_UP)
		cumulativePrincipal = cumulativePrincipal.add(principal).setScale(2, BigDecimal.ROUND_HALF_UP)
		def payment = paymentFactory.createPayment(principal, interest)
		paymentSchedule.addPayment(payment)

		def loan = paymentFactory.createLoan(paymentSchedule, cumulativeInterest, cumulativePrincipal)
		loan

	}
}
</pre>
<pre class="brush: java;">
package com.extensiblejava.calculator.groovy

class MonthlyPaymentCalculator {

	def calculatePayment(presentValue, rate, term) {

		def dPresentValue = presentValue.doubleValue()
		def dRate = rate.doubleValue() / 1200

		def revisedRate = dRate + 1;
		def dTerm = term.doubleValue()

		def powRate = Math.pow(revisedRate, dTerm)

		def left = powRate * dPresentValue
		def middle = dRate / (powRate - 1)
		def right = 1/(1);

		def payment = new BigDecimal(left * middle * right).setScale(2, BigDecimal.ROUND_HALF_UP)
	}
}
</pre>
<pre class="brush: xml;">
&lt;bean name=&quot;loanCalculator&quot; class=&quot;com.extensiblejava.calculator.groovy.MinimumPaymentScheduleCalculator&quot;&gt;
	&lt;constructor-arg ref=&quot;paymentFactory&quot;/&gt;
&lt;/bean&gt;
</pre>
<pre class="brush: xml;">
	&lt;osgi:reference id=&quot;paymentFactory&quot; interface=&quot;com.extensiblejava.loan.PaymentFactory&quot;/&gt;
	&lt;osgi:service id=&quot;LoanCalculator&quot; ref=&quot;loanCalculator&quot; interface=&quot;com.extensiblejava.loan.LoanCalculator&quot;/&gt;
</pre>
<pre class="brush: xml;">
	&lt;path id=&quot;groovy.class.path&quot;&gt;
		&lt;pathelement path=&quot;${groovy.library.jar}&quot;/&gt;
		&lt;pathelement path=&quot;${groovy.dir}/lib/commons-cli-1.2.jar&quot;/&gt;
		&lt;pathelement path=&quot;${groovy.dir}/lib/asm-3.2.jar&quot;/&gt;
		&lt;pathelement path=&quot;${groovy.dir}/lib/antlr-2.7.7.jar&quot;/&gt;
	&lt;/path&gt;

	&lt;taskdef name=&quot;groovyc&quot; classname=&quot;org.codehaus.groovy.ant.Groovyc&quot; classpathref=&quot;groovy.class.path&quot;/&gt;

	&lt;target name=&quot;clean&quot; description=&quot;clean up&quot;&gt;
		&lt;delete dir=&quot;${groovy.bin}&quot;/&gt;
		&lt;delete dir=&quot;${groovy.build}&quot;/&gt;
		&lt;delete dir=&quot;${buildstats}&quot;/&gt;
		&lt;!-- &lt;delete file=&quot;junitresults.txt&quot;/&gt; --&gt;
	&lt;/target&gt;

	&lt;target name=&quot;init&quot; depends=&quot;clean&quot;&gt;
		&lt;tstamp/&gt;
		&lt;mkdir dir=&quot;${groovy.build}&quot;/&gt;
		&lt;mkdir dir=&quot;${buildstats}&quot;/&gt;
	&lt;/target&gt;

	&lt;target name=&quot;compile&quot; depends=&quot;init&quot;&gt;
		&lt;groovyc srcdir=&quot;${groovy.src}&quot; destdir=&quot;${groovy.build}&quot;&gt;
			&lt;classpath refid=&quot;project.class.path&quot;/&gt;
		&lt;/groovyc&gt;
	&lt;/target&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2011/01/chapter-18-osgi-and-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Chapter 17 &#8211; OSGi and Scala</title>
		<link>http://www.kirkk.com/modularity/2011/01/chapter-17-osgi-and-scala/</link>
		<comments>http://www.kirkk.com/modularity/2011/01/chapter-17-osgi-and-scala/#comments</comments>
		<pubDate>Mon, 24 Jan 2011 18:26:40 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=806</guid>
		<description><![CDATA[
package com.extensiblejava.calculator.scala

import com.extensiblejava.loan._
//import MonthlyPaymentCalculator._

class MinimumPaymentScheduleCalculator(paymentFactory:PaymentFactory) extends LoanCalculator {
	def calculateLoan(value:java.math.BigDecimal, rate:java.math.BigDecimal, term:Int): Loan = {

		Console.println(&#34;---** IN SCALA CALCULATOR **---&#34;)
		val mc = new java.math.MathContext(2, java.math.RoundingMode.HALF_UP)
		val presentValue = BigDecimal(value)
		val presentRate = BigDecimal(rate).apply(mc)

		var cumulativePrincipal = BigDecimal(&#34;0.00&#34;)
		var cumulativeInterest = BigDecimal(&#34;0.00&#34;)

		val paymentSchedule = paymentFactory.createPaymentSchedule()
		val adjustedRate = (presentRate / (BigDecimal(&#34;1200&#34;)).setScale(2, BigDecimal.RoundingMode.HALF_UP))
		val calculator = new MonthlyPaymentCalculator()
		val monthlyPayment = calculator.calculatePayment(presentValue, presentRate, term)

		var loanBalance = [...]]]></description>
			<content:encoded><![CDATA[<pre class="brush: java;">
package com.extensiblejava.calculator.scala

import com.extensiblejava.loan._
//import MonthlyPaymentCalculator._

class MinimumPaymentScheduleCalculator(paymentFactory:PaymentFactory) extends LoanCalculator {
	def calculateLoan(value:java.math.BigDecimal, rate:java.math.BigDecimal, term:Int): Loan = {

		Console.println(&quot;---** IN SCALA CALCULATOR **---&quot;)
		val mc = new java.math.MathContext(2, java.math.RoundingMode.HALF_UP)
		val presentValue = BigDecimal(value)
		val presentRate = BigDecimal(rate).apply(mc)

		var cumulativePrincipal = BigDecimal(&quot;0.00&quot;)
		var cumulativeInterest = BigDecimal(&quot;0.00&quot;)

		val paymentSchedule = paymentFactory.createPaymentSchedule()
		val adjustedRate = (presentRate / (BigDecimal(&quot;1200&quot;)).setScale(2, BigDecimal.RoundingMode.HALF_UP))
		val calculator = new MonthlyPaymentCalculator()
		val monthlyPayment = calculator.calculatePayment(presentValue, presentRate, term)

		var loanBalance = BigDecimal(presentValue.bigDecimal)

		while (loanBalance.toDouble &gt; monthlyPayment.toDouble) {
			val interest = (loanBalance.*(adjustedRate)).setScale(2, BigDecimal.RoundingMode.HALF_UP)
			val principal = (monthlyPayment.-(interest)).setScale(2, BigDecimal.RoundingMode.HALF_UP);
			val payment = paymentFactory.createPayment(principal.bigDecimal, interest.bigDecimal);
			paymentSchedule.addPayment(payment);

			cumulativeInterest = cumulativeInterest.+(interest).setScale(2, BigDecimal.RoundingMode.HALF_UP);
			cumulativePrincipal = cumulativePrincipal.+(principal).setScale(2, BigDecimal.RoundingMode.HALF_UP);
			loanBalance = loanBalance.-(principal);
		}
		val interest = (loanBalance.*(adjustedRate)).setScale(2, BigDecimal.RoundingMode.HALF_UP)
		val principal = loanBalance.setScale(2, BigDecimal.RoundingMode.HALF_UP)
		cumulativeInterest = cumulativeInterest.+(interest).setScale(2, BigDecimal.RoundingMode.HALF_UP)
		cumulativePrincipal = cumulativePrincipal.+(principal).setScale(2, BigDecimal.RoundingMode.HALF_UP)
		val payment = paymentFactory.createPayment(principal.bigDecimal, interest.bigDecimal)
		paymentSchedule.addPayment(payment)

		val loan = paymentFactory.createLoan(paymentSchedule, cumulativeInterest.bigDecimal, cumulativePrincipal.bigDecimal)
		loan

	}
}
</pre>
<pre class="brush: java;">
package com.extensiblejava.calculator.scala

import scala.math._

class MonthlyPaymentCalculator {
	def calculatePayment(presentValue:BigDecimal, rate:BigDecimal, term:Int): BigDecimal = {
		val dPresentValue = presentValue.toDouble
		val dRate = rate.toDouble / 1200

		val revisedRate = dRate + 1;
		val dTerm = term.toDouble

		val powRate = pow(revisedRate, dTerm)

		val left = powRate * dPresentValue
		val middle = dRate / (powRate - 1)
		val right = 1/(1);

		val payment = BigDecimal(left * middle * right).setScale(2, BigDecimal.RoundingMode.HALF_UP)
		payment
	}
}
</pre>
<pre class="brush: xml;">
&lt;bean name=&quot;loanCalculator&quot; class=&quot;com.extensiblejava.calculator.scala.MinimumPaymentScheduleCalculator&quot;&gt;
		&lt;constructor-arg ref=&quot;paymentFactory&quot;/&gt;
	&lt;/bean&gt;
</pre>
<pre class="brush: xml;">
&lt;osgi:reference id=&quot;paymentFactory&quot; interface=&quot;com.extensiblejava.loan.PaymentFactory&quot;/&gt;
	&lt;osgi:service id=&quot;LoanCalculator&quot; ref=&quot;loanCalculator&quot; interface=&quot;com.extensiblejava.loan.LoanCalculator&quot;/&gt;
</pre>
<pre class="brush: xml;">
&lt;path id=&quot;scala.class.path&quot;&gt;
		&lt;pathelement path=&quot;${scala.library.jar}&quot;/&gt;
		&lt;pathelement path=&quot;${scala.compiler.jar}&quot;/&gt;
	&lt;/path&gt;

	&lt;taskdef resource=&quot;scala/tools/ant/antlib.xml&quot; classpathref=&quot;scala.class.path&quot;/&gt;

	&lt;target name=&quot;clean&quot; description=&quot;clean up&quot;&gt;
		&lt;delete dir=&quot;${scala.bin}&quot;/&gt;
		&lt;delete dir=&quot;${scala.build}&quot;/&gt;
		&lt;delete dir=&quot;${buildstats}&quot;/&gt;
		&lt;!-- &lt;delete file=&quot;junitresults.txt&quot;/&gt; --&gt;
	&lt;/target&gt;

	&lt;target name=&quot;init&quot; depends=&quot;clean&quot;&gt;
		&lt;tstamp/&gt;
		&lt;mkdir dir=&quot;${scala.build}&quot;/&gt;
		&lt;mkdir dir=&quot;${buildstats}&quot;/&gt;
	&lt;/target&gt;

	&lt;target name=&quot;compile&quot; depends=&quot;init&quot;&gt;
		&lt;scalac srcdir=&quot;${scala.src}&quot; destdir=&quot;${scala.build}&quot;&gt;
			&lt;classpath refid=&quot;project.class.path&quot;/&gt;
		&lt;/scalac&gt;
	&lt;/target&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2011/01/chapter-17-osgi-and-scala/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Chapter 14 &#8211; Introducing OSGi</title>
		<link>http://www.kirkk.com/modularity/2011/01/chapter-14-introducing-osgi/</link>
		<comments>http://www.kirkk.com/modularity/2011/01/chapter-14-introducing-osgi/#comments</comments>
		<pubDate>Fri, 14 Jan 2011 20:34:05 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=800</guid>
		<description><![CDATA[14.1 &#8211; Introduction
The OSGi Service Platform is a standard dynamic module system for the Java platform. The OSGi Alliance developed and now manages that standard.  The specification is mature and stable, and most application platforms now allow enterprise developers to leverage OSGi in building their own enterprise applications.
A foundation of the OSGi Service Platform is the [...]]]></description>
			<content:encoded><![CDATA[<h2 style="font-size: 1.5em;">14.1 &#8211; Introduction</h2>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding: 0px;">The OSGi Service Platform is a standard dynamic module system for the Java platform. The OSGi Alliance developed and now manages that standard.  The specification is mature and stable, and most application platforms now allow enterprise developers to leverage OSGi in building their own enterprise applications.</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding: 0px;">A foundation of the OSGi Service Platform is the OSGi framework, which defines a module management system and provides an API for interacting with the framework. OSGi modules (referred to as “bundles”) are regular JAR files packaged with a manifest file that contains metadata describing the bundle and its dependencies to the OSGi Service Platform. The OSGi framework offers the following capabilities:</p>
<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 2em; padding: 0px;">
<li style="padding-top: 0px; padding-right: 0px; padding-bottom: 4px; padding-left: 0px; margin: 0px;"><strong style="padding: 0px; margin: 0px;">Modularity:</strong> Enables a modular approach to architecture on the Java platform.</li>
</ul>
<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 2em; padding: 0px;">
<li style="padding-top: 0px; padding-right: 0px; padding-bottom: 4px; padding-left: 0px; margin: 0px;"><strong style="padding: 0px; margin: 0px;">Versioning:</strong> Supports multiple versions of the same software module deployed within the same JVM instance.</li>
</ul>
<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 2em; padding: 0px;">
<li style="padding-top: 0px; padding-right: 0px; padding-bottom: 4px; padding-left: 0px; margin: 0px;"><strong style="padding: 0px; margin: 0px;">Hot deployments:</strong> Permits modules to be deployed and updated within a running system without restarting the application or the JVM.</li>
</ul>
<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 2em; padding: 0px;">
<li style="padding-top: 0px; padding-right: 0px; padding-bottom: 4px; padding-left: 0px; margin: 0px;"><strong style="padding: 0px; margin: 0px;">Service orientation:</strong> Encourages service-oriented design principles in a more granular level within the JVM.</li>
</ul>
<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 2em; padding: 0px;">
<li style="padding-top: 0px; padding-right: 0px; padding-bottom: 4px; padding-left: 0px; margin: 0px;"><strong style="padding: 0px; margin: 0px;">Dependency management:</strong> Requires explicit declaration of dependencies between modules.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2011/01/chapter-14-introducing-osgi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Chapter 7 &#8211; Modularity and SOA</title>
		<link>http://www.kirkk.com/modularity/2010/09/modularity-and-soa/</link>
		<comments>http://www.kirkk.com/modularity/2010/09/modularity-and-soa/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 18:24:10 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Part 1]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=638</guid>
		<description><![CDATA[At this point, it&#8217;s doubtful that any of us will confuse modularity with service oriented architecture (SOA). The two appear to be distinctly different beasts. Yet, they are very similar in nature and each offers tremendous benefit to organizations. At one level, the principles behind service design apply equally to module design. Like we try [...]]]></description>
			<content:encoded><![CDATA[<p>At this point, it&#8217;s doubtful that any of us will confuse modularity with service oriented architecture (SOA). The two appear to be distinctly different beasts. Yet, they are very similar in nature and each offers tremendous benefit to organizations. At one level, the principles behind service design apply equally to module design. Like we try to create services that are loosely coupled and highly cohesive, we also try to design modules with similar goals.</p>
<p>Yet module design and service design are incredibly complementary in other ways, as well. In Chapter 2, we defined a module and illustrated how modules are excellent candidates for intra-process reuse, while service reuse crosses process boundaries. In Chapter 4, we talked about modularity in a broader architectural context, illustrating how it helps us achieve the goal of architecture. Before we progress onto the pattern discussion, it&#8217;s important to discuss modularity in the context of other architectural principles, and illustrate how modularity helps us realize many of the benefits we&#8217;ve discussed thus far.</p>
<h2>7.1 &#8211; All The Way Down, Revisited</h2>
<p><img class="alignnone" style="border: 0px initial initial;" title="TheIvoryTowerAndArcAllTheWay" src="http://www.kirkk.com/modularity/wp-content/uploads/2009/12/TheIvoryTowerAndArcAllTheWay.jpg" alt="TheIvoryTowerAndArcAllTheWay" width="755" height="376" /></p>
<p style="text-align: center;"><strong>Figure 7.1 &#8211; Social Architecture All The Way Down</strong></p>
<p>In Chapter 4, I talked about how important it is that we &#8220;architect all the way down&#8221;. It helps increase transparency and understanding between developers and architects by emphasizing a lot of the middle ground that noone ever seems to focus on. It&#8217;s just another reason why modularity is so important. I used the diagram in Figure 7.1 to illustrate the point. Look at the huge gap that exists if we don&#8217;t focus on the stuff highlighted by the gray bar in the middle.</p>
<p>One reason I like this visual is that it illustrates the social aspect of software architecture. Yet, there are other significant advantages to architecture all the way down that we haven&#8217;t explored yet. Another is structural flexibility.</p>
<h3>7.2.1 &#8211; Structural Flexibility &#8211; Different Entities, Different Purpose</h3>
<p>Another benefit of module design in filling that middle ground is that modules can offer different benefits than classes and services. The diagram in Figure 7.2 illustrates some of the capabilities of different types of entities, which is a variation of the diagram we used when defining a module in Chapter 2.</p>
<p style="text-align: center;"><img class="size-large wp-image-663 aligncenter" title="ArchitectureAllTheWayDownStructural" src="http://www.kirkk.com/modularity/wp-content/uploads/2010/09/ArchitectureAllTheWayDownStructural-1024x689.jpg" alt="ArchitectureAllTheWayDownStructural" width="819" height="551" /></p>
<p style="text-align: center;"><strong>Figure 7.2 &#8211; Structural Architecture All The Way Down</strong></p>
<p>For example, classes are pretty easily reused within an application, but because classes aren&#8217;t a unit of deployment, it&#8217;s difficult to use them across applications. Of course, intra-application reuse is a sweet spot of services, since they&#8217;re method of invocation is through some distributed protocol (SOAP, HTTP, even RMI/IIOP). Yet because services are invoked remotely, we typically like to make them coarser-grained because of the performance implications of distributed requests. So this begs the question &#8211; If a service is too coarse-grained to reuse (ie. it does more than what we want), how do I reuse some desirable behavior across applications? Well, without modules, our only other choice is the class. Since a class can&#8217;t be reused intra-process, we do one of either two things. Expose it as a service or copy the class (ie. the code). Given the circumstances, neither of these may be ideal. Another option is desirable.</p>
<p>Modules represent that other option. They are a finer level unit of granularity than services, and are a unit of deployment. Since each of these different types of entities are units of composition, we have tremendous flexibility in how we assemble applications. Possibly more important though is our increased ability to accommodate the architectural shifts that naturally occur as requirements evolve. Because one of the most difficult aspects of architecture is designing entities at the right level of granularity.</p>
<h2>7.2 &#8211; Granularity, Architecture&#8217;s Nemesis</h2>
<p>Granularity is the extent to which a system is broken down into it’s behavioral entities. Coarse-grained entities tend to be richer in behavior than fine-grained entities. Because coarse-grained entities do more, they tend to be larger than fine-grained entities, and are easier to use. In general, a fine-grained entity is more reusable than a coarse-grained entity because it does a little bit less.  If it does less, then it’s more likely to apply across a wider variety of usage scenarios. We spent some time discussing this tension in Chapter 6. Now, I&#8217;d like to go a bit deeper which will help more clearly illustrates the concept of &#8220;architecture all the way down.&#8221;</p>
<p>Unfortunately, while there are a lot of patterns, principles, and idioms that offer really good guidance surrounding many aspects of architecture and design, there isn’t a lot of guidance surrounding granularity. Let’s start with a really simple example that illustrates the challenge.</p>
<h3>7.2.1 &#8211; A Really Simple Example</h3>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">Consider the following save method:</p>
<pre class="brush: java;">
public class Person {
private String firstName;
private String lastName;
private String ssNumber;
public void save() {
ValidationErrors errors = this.validate();
      if (errors != null) {
         //handle the errors somehow
      } else {
//save to the database.
      }
}
private ValidationErrors validate() {
//perform validation
}
}</pre>
<p>As can be seen, the save method invokes the validate method before saving the information to the database. Generally speaking, this makes saving the information easier (and possibly safer) since whatever invokes save doesn’t have to worry about validating. And this seems to be a good thing.</p>
<p>Yet, what happens when a new consumer of this method wants to save the information but apply a slightly different set of rules than the current validation method provides? Here’s where the existing save method is simply too coarse-grained. It does just a little bit too much. We’ve made it easier to use, but also less reusable.</p>
<p>There are quite a few variations I could go with at this point to improve the design. One would be to make the validate method public, and have clients invoke the validate method before invoking save. Then, if validate didn’t do what it was supposed to, clients could always opt out of invoking the validate method and apply their own validation before invoking save. Certainly less safe though because validation is optional.</p>
<p>Yet another alternative might be the following:</p>
<pre class="brush: java;">
public class Person {
   private String firstName;
   private String lastName;
   private String ssNumber;
   public void save(Validator validator) {
      ValidationErrors errors = validator.validate();
      if (errors != null) {
         //handle the errors somehow
      } else {
         //save to the database.
      }
   }
}
</pre>
<p>This seems to offer the best of both worlds. I now require a Validator be passed in before I can save, and if the Validator is an interface, I can certainly allow clients to pass in the Validator they need. Of course, I could easily pass in a NOP validator.</p>
<p>Whatever…there are lots of different options, and each has their own set of tradeoffs. I’d like to avoid extensive debate surrounding which approach to save and validation is best and instead focus on the main point here, which is that achieving the right level of granularity for an entity can be very challenging.<strong> </strong>It requires more than just looking at the problem from a code level viewpoint and demands that we possess contextual information that will help us answer the question, “What’s the right level of granularity?”</p>
<h3>7.2.2 &#8211; Bring It Up A Level</h3>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">The code above was a pretty simple example that illustrates the challenges of granularity at the method level. But the same challenges exist when developing classes, packages, modules and services, and we&#8217;ll see an example of this shortly. So what I really want to know is</p>
<blockquote>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;"><strong>How do I determine the appropriate level of granularity?</strong></p>
</blockquote>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">This is the million dollar question. Because granularity is a significant inhibitor to creating reusable software that’s easy to use.<strong> </strong>(Oh, and <a style="color: #002066; font-weight: bold; text-decoration: none;" href="http://techdistrict.kirkk.com/2009/12/21/that-rotting-design/">managing dependencies</a> too.) If something does too much, it’s less reusable. If something does too little, it’s more difficult to reuse.</p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">MAKE MENTION OF ROTTING DESIGN AND DEPENDENCY MANAGEMENT.</p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">The diagram in Figure 7.1 does a good job illustrating one view of granularity. Services are more coarse-grained than modules which are more coarse-grained than packages which in turn are slightly more coarse-grained than classes. This begins to help answer the question, “What’s the right level of granularity?”</p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">If I’m concerned that a service I create is simply too coarse-grained and fails to maximize its reuse potential, I can break the behaviors of the service out into modules that are a bit finer grained and more reusable (of course, one might consider doing this in general). Then I can compose the services from the modules and reuse the modules across services. The result is different entities at different levels of granularity that lends tremendous flexibility to how I compose, use, and reuse software entities.</p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">This provides some guidance on the level of granularity at which different types of software entities should be defined. However, it still doesn’t offer enough guidance to determine the right level of granularity for the save method in our example above.</p>
<h3>7.2.3 &#8211; Another Dimension</h3>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">There’s another dimension that is relevant, and that ties in nicely (though in a rather subtle way) to the initial coding example. It has to do with the way we traditionally layer our software. The diagram in Figure 7.3 illustrates the typical architectural layers commonly found in many systems. Generally, as we move down the layered hierarchy, entities become finer grained.</p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: center; margin: 0px;"><img class="size-full wp-image-664 aligncenter" title="architectureallthewaydowngranularitylayersonly" src="http://www.kirkk.com/modularity/wp-content/uploads/2010/09/architectureallthewaydowngranularitylayersonly.jpg" alt="architectureallthewaydowngranularitylayersonly" width="844" height="258" /></p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: center; margin: 0px;"><strong>Figure 7.3 &#8211; Architectural Layers</strong></p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">While this isn’t absolute, and depends on your architectural principles and style, entities in higher level layers tend to be more coarse-grained than entities in lower level layers because they are an amalgamation of their own behavior and the behavior of entities in the lower level layers.</p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">Armed with this information, we can determine the right level of granularity for the save method as long as we understand in which layer the code containing the save method lives. If it’s in the data access layer, and we place architectural constraints on business rules living in the data access layer, then we shouldn’t have any validation code that lives in the data access layer. If the save method lives in a class in the domain layer, however, it may be suitable for the save method to contain validation code in the domain layer and invoke another method in the data access layer that actually performs the save operation.</p>
<h3>7.2.4 &#8211; The Complete Picture</h3>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">At this point we can make the following general statements:</p>
<ul style="list-style-type: none; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; padding: 0px;">
<li style="background-image: url(http://techdistrict.kirkk.com/wp-content/themes/kirk/images/arrow.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; padding-top: 0px; padding-right: 0px; padding-bottom: 5px; padding-left: 13px; background-position: 0% 0%; background-repeat: no-repeat no-repeat; margin: 0px;">Entities in higher level layers are more coarse-grained than entities in lower level layers.</li>
<li style="background-image: url(http://techdistrict.kirkk.com/wp-content/themes/kirk/images/arrow.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; padding-top: 0px; padding-right: 0px; padding-bottom: 5px; padding-left: 13px; background-position: 0% 0%; background-repeat: no-repeat no-repeat; margin: 0px;">Services are coarser than modules which are coarser than packages which are coarser than classes.</li>
</ul>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">And if we combine these two ideas into a single thought, and overlay the two diagrams, we can begin to visualize the level of granularity for different types of software entities. Figure 7.4 illustrates how entities become finer-grained as we move from both left to right and top to bottom.</p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: center; margin: 0px;"><img class="size-full wp-image-665 aligncenter" title="architectureallthewaydowngranularity" src="http://www.kirkk.com/modularity/wp-content/uploads/2010/09/architectureallthewaydowngranularity.jpg" alt="architectureallthewaydowngranularity" width="844" height="498" /></p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: center; margin: 0px;"><strong>Figure 7.4 &#8211; Granularity and Architecture All The Way Down</strong></p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">Certainly this doesn’t offer hard guidance. Realistically, there are very few architecture and design principles and patterns that are universally applicable. In fact, I’m not certain you’d ever create a “presentation service.” But certainly you might create a data service that is composed of multiple data access modules. And you might have separate data services that reuse a data access module. And you might have a business service that uses a data service and is also composed of multiple domain modules. But you definitely do not want a data access module that invokes a business service, nor a business service that references a presentation module.</p>
<p style="padding-top: 8px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin: 0px;">So this general guidance can serve as useful information to help answer our question, “How do I determine the appropriate level of granularity for a software entity?” And it can also serve as guidance when establishing architectural principles and constraints that help determine where software entities with specific behaviors should reside. Because without some scheme that will help determine the appropriate level of granularity, it’s hopeless to imagine that we’ll be able to design reusable software entities that are also easy to use.</p>
<h3>7.2.5 &#8211; A Service Example</h3>
<p>Let&#8217;s take another example. Say I have a business function called Pay Bill for which I develop a web service that can be invoked by many different consumers. That service happens to be relatively coarse-grained, and performs all the steps involved in paying the bill. These happen to include the following:</p>
<ul>
<li>audit bill &#8211; apply a discount to the bill based on payee</li>
<li>check for duplicate &#8211; ensure the bill hasn&#8217;t already been paid</li>
<li>remit payment &#8211; cut the check</li>
<li>reconcile payment &#8211; reconcile with accounts payable financials</li>
</ul>
<p>This seems reasonable. We have a nice little service that we can reuse any time we want to pay a bill. Unfortunately, the real world often gets in the way of our idealistic solutions. In fact, there are two problems that will eventually surface, and modularity benefits both scenarios. Let&#8217;s start by looking at the first scenario.</p>
<blockquote><p>What should I do when a different scenario arises that demands I follow a slightly modified Pay Bill function?</p></blockquote>
<p>As part of the remit step, I have a new payee that demands electronic payment. This is pretty easy actually. I simply modify the service to support electronic payments and then configure the service to context for that specific payee. So how does modularity help here?</p>
<p>If the service is composed of modules, it&#8217;s going to be much easier for me to <a href="http://techdistrict.kirkk.com/2009/08/13/modularity-by-example/">understand the structure</a> of the service, assess the impact of what&#8217;s it&#8217;s going to cost to change the service, and then introduce a new module (or modify the existing module) to provide the new capability. Without modules, I&#8217;m simply wading through the code trying to figure out all of these things. Now, the 2nd scenario.</p>
<blockquote><p>What should I do when I want to reuse just one step of the Pay Bill function?</p></blockquote>
<p>Let&#8217;s say another new requirement emerges. Whereas traditionally bills were entered by data entry personnel, we now have to support electronic delivery of bills. We also know that bills delivered electronically are often duplicates. It&#8217;s just one of those business things, you know? If we don&#8217;t pay the bill on the day it&#8217;s received, the billing party sends us the bill again, asking for payment. So we need to check for duplicates before we save the bill to the database and prepare it for processing. What do we do?</p>
<p>We could take the same approach as before and modify the Pay Bill service so that the duplicate check could be invoked separately from the higher level pay bill function. But that&#8217;s a bastardized design solution. Why? We are exposing behavior of the Pay Bill service that shouldn&#8217;t be exposed. The API is coarse-grained in some areas and fine-grained in others.</p>
<p>Maybe exposing the finer-grained capabilities of the Pay Bill function isn&#8217;t a severe compromise, but it is a compromise nonetheless. And we are forced to compromise because of architectural inflexibility. We don&#8217;t have architecture all the way down, and are therefore left with limited choice as to how we support the new requirement. We can either modify the service to reuse what we know is already encapsulated within the service, or copy the code to create something new. But those are the two options we have, and neither may be ideal.</p>
<p>As we continue to hack the system in this manner, with a multitude of other similar changes, the design will rot. Eventually, our Pay Bill service is transformed into a utility that performs all general-purpose bill functions. It&#8217;s API is a mix of coarse-grained and fine-grained operations. It&#8217;s become the monolith that we&#8217;re trying to avoid. While the Pay Bill service is still pretty reusable (it does everything now), it isn&#8217;t that usable. That tension between reuse and use that we discussed in Chapter 6 surfaces again.</p>
<p>Our decision to modify the Pay Bill service to expose the duplicate check was driven by one thing &#8211; ease. It was our easiest option. Really, it was our only option. But it isn&#8217;t the best option.</p>
<p>If we architect all the way down, we have another option. A Pay Bill service composed of modules that audit the bill, check for duplicates, remit payment, and reconcile the payment means we can choose the desirable solution over the easiest short term choice. We can avoid the long term compromises that degrade architectural integrity.</p>
<p>Shown in Figure 7.5, we see the service composed of modules. If we have a check for duplicates module, we can simply reuse that module in the new service or application that&#8217;s going to process electronic bills. Or we might expose the capabilities of the check for duplicates module as a separate service. We have multiple reuse entry points, as well as different levels of granularity through which our software entities can be managed, deployed, built, and much more.</p>
<p>My point here isn&#8217;t to debate the original design nor the decisions made to reuse the check for duplicates functionality in another service or application. Certainly, debating architectural and design decisions is a favorite past-time of developers. There are a variety of different ways that we can support new requirements as they emerge. Some are better than others and all are contextual.</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-666" title="NewProcessSample" src="http://www.kirkk.com/modularity/wp-content/uploads/2010/09/NewProcessSample.jpg" alt="NewProcessSample" width="434" height="485" /></p>
<p style="text-align: center;"><strong>Figure 7.5 &#8211; Service Composed of Modules</strong></p>
<h2 style="font-size: 1.5em;">7.3 &#8211; An Alternative View</h2>
<p>When designing software systems, teams often have a tendency to overemphasize service design and the aesthetics of the user experience (UX). While designing the UX and services using SOA principles are incredibly important, neglecting to pay careful attention in designing the service implementation can result in software that is difficult to change. Modularity shines in helping designing flexible service implementations. The diagram in Figure 7.6 illustrates this concept.</p>
<p><img class="alignnone size-large wp-image-674" title="ServiceImplementation" src="http://www.kirkk.com/modularity/wp-content/uploads/2010/09/ServiceImplementation-1024x736.jpg" alt="ServiceImplementation" width="717" height="515" /></p>
<p style="text-align: center;">
<p style="text-align: center;"><strong>Figure 7.6 &#8211; Designing Service Implementations</strong></p>
<p style="text-align: left;">When designing services, teams often pay careful attention to designing the service interface and devote time to understanding and adopting the appropriate interface style, such as REST, POX, SOAP, or messaging. A great benefit of SOA is that individual services can be autonomously reused and evolve independent of other services. Unfortunately, if careful attention isn&#8217;t given to how the service implementation is structured, the service loses it&#8217;s ability to evolve and survive.</p>
<p style="text-align: left;">
<h2>7.6 &#8211; Summary</h2>
<p>The notion of architecture all the way down gives us options, and these options help maintain architectural integrity. They increase our options when making decisions and allow our system to accommodate unforeseen architectural shifts. I can modify an existing application or service to give me what I need. Or I can reuse an existing module that&#8217;s already available for me. Or I can compose a new service from an existing set of modules. Or I can break apart existing modules to create new modules that result in new services. And I can do a lot of this refactoring without significant impact on the existing code. We&#8217;ll see this idea in action in the next chapter, as well as throughout the pattern discussions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2010/09/modularity-and-soa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Default Implementation</title>
		<link>http://www.kirkk.com/modularity/2010/08/defaultimplementation/</link>
		<comments>http://www.kirkk.com/modularity/2010/08/defaultimplementation/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 18:38:34 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=597</guid>
		<description><![CDATA[For the full description, implementation variations, consequences, and detailed sample, see Page 206 in Java Application Architecture.
Statement
Provide modules with a default implementation.
Description
To maximize reuse, a module must be flexible enough so that it can function in variety of different operating environments. Yet, for a module to be usable, it must be independently deployable. To address [...]]]></description>
			<content:encoded><![CDATA[<p><i>For the full description, implementation variations, consequences, and detailed sample, see Page 206 in Java Application Architecture.</i></p>
<h2 style="font-size: 1.5em;">Statement</h2>
<p>Provide modules with a default implementation.</p>
<h2 style="font-size: 1.5em;">Description</h2>
<p>To maximize reuse, a module must be flexible enough so that it can function in variety of different operating environments. Yet, for a module to be usable, it must be independently deployable. To address this tension, a module can be given a Default Implementation with well-defined extension points so that the module can be extended when necessary.<br />
<img style="border: 0pt none;" title="DefaultImplementation" src="http://www.kirkk.com/modularity/wp-content/uploads/2010/08/DefaultImplementation-1024x438.jpg" alt="DefaultImplementation" width="737" height="315" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2010/08/defaultimplementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Future of Modularity: OSGi</title>
		<link>http://www.kirkk.com/modularity/2010/04/the-future-of-modularity-osgi/</link>
		<comments>http://www.kirkk.com/modularity/2010/04/the-future-of-modularity-osgi/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 16:09:15 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Appendix]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=553</guid>
		<description><![CDATA[Recently, I questioned whether OSGi and modularity would succeed in penetrating the enterprise. But what I really meant to question is whether OSGi will have the disruptive impact of which it’s capable. I asserted that if OSGi does succeed, it won’t be based on the technical merits of OSGi. It’ll be because of something else. [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Recently, I questioned whether OSGi and modularity would succeed in penetrating the enterprise. But what I really meant to question is whether OSGi will have the disruptive impact of which it’s capable. I asserted that if OSGi does succeed, it won’t be based on the technical merits of OSGi. It’ll be because of something else. Something trendy. Something fashionable.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Now, I could be wrong. OSGi adoption is certainly increasing, albeit slowly. And as case studies begin to emerge that tout the cost reduction, improved responsiveness, and time-to-market advantages of OSGi, adoption will likely continue to rise.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">But adoption is one thing, disruption another, and I still have this nagging sensation that serves as cause for pause. What if something trendier, more fashionable surfaces, and OSGi is pushed into the backwaters? Will it really have the impact it’s capable of? You know…an “iPhone-esque” impact that raises the bar and redefines an industry. Not just evolutionary, but truly disruptive.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">OSGi As Enabler</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">For OSGi to cross the chasm, it must enable something big that a business wants to buy.Maybe cost reduction, improved responsiveness and time-to-market benefits will be enough. But that’s easily perceived by many as a rather evolutionary impact. Not really disruptive.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Quite possibly OSGi will flourish in the data center, as organizations seek more adaptable platforms that lend them these benefits. But this doesn’t necessarily guarantee that development teams will leverage OSGi to build systems with a modular architecture. Because leveraging a platform built atop OSGi is separate from building modular software systems, even thoughOSGi enables both.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Without something trendy that promises real benefits, it’ll get brushed under the carpet like what has happened to many technologically superior solutions. Perhaps it’s already happening, with all of the hype surrounding the cloud. Or maybe it’ll be the cloud that helps OSGi cross the chasm. OSGi doesn’t obviously enable the cloud, but OSGi can enable the dynamic and adaptive runtime benefits of the cloud.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">But again, this doesn’t mean that teams will begin leveraging OSGi to design modular software. It only means that the platform itself is adaptable. Of course, there is benefit in that. But if that’s the route that is taken, teams will still continue to develop monolithic applications that lack architecturally resiliency, and the full benefit of OSGi (and modularity) will not be realized.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The Disruption</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">OSGi has the potential to have have a much broader impact, affecting everyone from the developer to those working in the data center.  So what might this trend be that will propel OSGi to stardom?</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">OSGi enables ecosystems!</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Now, you’re thinking I’ve gone on the deep end, perhaps? But give me a chance…let me explain.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">A Bit of [Recent] Platform History</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">To start, I want to take a brief walk down memory lane. Not too far back though, but far enough so that we can see how important the ecosystem is in today’s most successful platforms. And these platforms span a range of markets, from mobile to social media. But each are successful in large part due to a thriving ecosystem.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Apple</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">In 2007, Apple released their first generation iPhone. Without question, the device revolutionized the mobile phone industry. While the device offers a great user experience that has certainly played a role in its surging popularity, people flock to the iPhone today because of the wealth of applications available. Yeah, “there’s an app for that.”</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Apple, recognizing the power of this ecosystem, now delivers the iPad. With fewer preinstalled applications than the iPhone, Apple is counting on the ecosystem to drive adoption. The more consumers who flock to the device, the more developers who flock to the platform to deliver applications. As more applications become available, consumers will buy more iPads. The ecosystem fuels itself. Apple has simply provided the environment for the ecosystem to thrive.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Eclipse</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">In 2003, the Eclipse team was thinking of ways to make Eclipse more dynamic. Their decision to use OSGi to create a rich client platform that supports plug-in architecture was the first step toward the resulting ecosystem we know today. One of the reasons developers use Eclipse is because there are an abundance of plug-ins available that allow them to do their jobs more effectively. Other developers create Eclipse plug-ins because Eclipse is a popular IDE used by many developers. Again, the ecosystem fuels itself. The Eclipse team provided the environment that allows today’s Eclipse ecosystem to thrive.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">If you’re interested, you can read more about the history of Eclipse and OSGi.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Hudson</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Arguably, Hudson is today’s most popular continuous integration server. But it hasn’t always been. Before Hudson was CruiseControl. And while CruiseControl did help development teams get started on their path toward continuous integration, it was also unwieldy to use in many ways. With Hudson’s plug-in architecture, developers have the ability to extend the tool in ways the original creator couldn’t imagine or couldn’t find the time to do himself. Kohsuke created Hudson and gave the development community a new platform for continuous integration. With its plug-in architecture though, he also provided an environment that allows the Hudson ecosystem to thrive.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Social Media</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Facebook. MySpace. Twitter. Each are examples of social media tools with a strong developer community that creates extensions to the platform that users can leverage to enhance the experience. Facebook Developers. MySpace Developer Platform. Twitter API. Each allows the ecosystem to thrive.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">And Others</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">These are just a few examples. It’s easy to find other platforms with similar ecosystems, as well. The ease with which Wordpress themes and plug-ins can be developed and used to enhance a Wordpress website is another example. In fact, many content management systems provide similar capabilities. A large reason why the Firefox web browser has emerged as the preferred web browser is the ease with which add-ons can be installed that extend the capabilities of the browser. The Atlassian Plugin Framework is another example that uses OSGi, and platforms such as Force.com and SharePoint have built (or are trying to build) similar ecosystems.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The Power of Ecosystems</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Aside from Eclipse (and Atlassian), none of these other platforms leverage OSGi. Yet each are wildly successful because of two reasons:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">An environment was created that allowed an ecosystem to form and flourish. This environment includes a platform and a marketplace.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">A group of customers and developers converged on the marketplace and fueled growth of the platform. The result is a self-sustaining ecosystem.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">If you look at many of the more popular platforms that have emerged over the past decade, they tend to possess a similar characteristic &#8211; a community of individuals dedicated to providing great solutions leveraging the foundation of the platform. OSGi and modularity enables ecosystems on the Java platform.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Ecosystems and the Two Faces</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">I’ve already talked about the two faces of OSGi &#8211; the runtime model and the development model. I’ve also explained how one could possibly see widespread adoption while the other has little impact. A strong ecosystem surrounding OSGi and modularity must leverage both. Developers would create reusable modules, implying they are designing modular software. For development teams to leverage these modules, they must be using a platform that supports the runtime model.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">CBD Has Already Had Its Day, You Say?</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Now some of you might be arguing that this sounds a lot like the component based development (CBD) fad of the 1990’s. True…to an extent. Certainly these ideas are not new. But there are also some striking differences between that which OSGi enables and the CBD fad that has come and largely gone, or whose promise was never fully realized.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Foremost, the CBD fad was focused almost exclusively on visual components, such as ActiveX. While some attempted to create components for the Java platform, the movement largely failed to go mainstream. Instead, Java EE grew in popularity and for a number of years, garnered everyone’s attention. Why did this  happen?</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">IMHO, the answer is fairly simple. Even though numerous marketplaces emerged that allowed the consumer and producer to come together to buy and sell components, there was never a suitable component execution environment. That is, an environment that would support dynamic deployment, support for multiple versions, dependency management, and, in general, complete control over all components currently executing within the environment. ActiveX components did have an execution environment (though did not support each of these capabilities), but Java did not. Today, in OSGi, Java has the requisite execution environment!</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The Ecosystem</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">It’s easy find holes in this idea. To explain why it cannot work. Yet, it’s happening elsewhere, so why not on the server…in the enterprise? Certainly there are a variety of different ways such an ecosystem could manifest itself. Possibly multiple ecosystems emerge like what we see in the mobile market today.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">But for a moment, imagine the world where you have the ability to easily assemble a platform from pre-built infrastructure modules that exactly meet the demands of your application. You might purchase these modules, you might choose to use open source modules, or you might build them yourself. For those you don’t build, you obtain from a module marketplace, possibly deploying them to your [cloud] environment.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">And when you choose to use a module, it’s dynamically deployed to your environment. The modules it depends upon? You’re given the option to purchase and deploy them, as well. You develop your software modules using the sound principles and patterns of modular design to ensure loose coupling and high cohesion. As you roll out your business solution modules, you simultaneously deploy the additional infrastructure modules that are needed.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">In this marketplace, modules are sourced by multiple vendors. Some large. Some small. Neither the stack, nor your applications, are monolithic beasts. Instead, they are a composition of collaborating software modules. Your infrastructure isn’t necessarily tied to a specific vendor solution. The option always exists for organizations to purchase modules from different providers, easily swapping one provider module out with another.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The ecosystem flourishes. Developers flock to sell their latest creation. Organizations seek to add amazing capabilities to their rightsized environment at a fraction of the cost compared to what they are accustomed to today. The business benefits are real. The technical advantages are real. And the resulting ecosystem is sustainable.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">A successful ecosystem demands both the runtime model and development model. And today, OSGi is the only standard technology that will allow this type of successful ecosystem to form on the Java platform. But will it happen? We may have a ways to go, but it sure would be cool! And it would be a shame if we lost this opportunity.</div>
<p>OSGi is not new. It has been around since the late 1990&#8217;s. Unfortunately, while OSGi is the only dynamic module system for the Java platform, adoption is not widespread. However, traction within the industry is building. Many products continue to emerge that leverage OSGi internally, and more are beginning to expose the virtues of OSGi to the developer community. But there is concern that OSGi will not have the disruptive impact of which it’s capable. I assert that if OSGi does succeed, it won’t be based on the technical merits of OSGi. It’ll be because of something else. Something trendy. Something fashionable.</p>
<p>Now, I could be wrong. OSGi adoption is certainly increasing, albeit slowly. And as case studies begin to emerge that tout the cost reduction, improved responsiveness, and time-to-market advantages of OSGi, adoption will likely continue to rise.</p>
<p>But adoption is one thing, disruption another, and I still have this nagging sensation that serves as cause for pause. What if something trendier, more fashionable surfaces, and OSGi is pushed into the backwaters? Will it really have the impact it’s capable of? You know…an “iPhone-esque” impact that raises the bar and redefines an industry. Not just evolutionary, but truly disruptive.</p>
<h2 style="font-size: 1.5em;">OSGi as Enabler</h2>
<p>For OSGi to cross the chasm, it must enable something big that a business wants to buy.Maybe cost reduction, improved responsiveness and time-to-market benefits will be enough. But that’s easily perceived by many as a rather evolutionary impact. Not really disruptive.</p>
<p>Quite possibly OSGi will flourish in the data center, as organizations seek more adaptable platforms that lend them these benefits. But this doesn’t necessarily guarantee that development teams will leverage OSGi to build systems with a modular architecture. Because leveraging a platform built atop OSGi is separate from building modular software systems, even thoughOSGi enables both.</p>
<p>Without something trendy that promises real benefits, it’ll get brushed under the carpet like what has happened to many technologically superior solutions. Perhaps it’s already happening, with all of the hype surrounding the cloud. Or maybe it’ll be the cloud that helps OSGi cross the chasm. OSGi doesn’t obviously enable the cloud, but OSGi can enable the dynamic and adaptive runtime benefits of the cloud.</p>
<p>But again, this doesn’t mean that teams will begin leveraging OSGi to design modular software. It only means that the platform itself is adaptable. Of course, there is benefit in that. But if that’s the route that is taken, teams will still continue to develop monolithic applications that lack architecturally resiliency, and the full benefit of OSGi (and modularity) will not be realized.</p>
<h2 style="font-size: 1.5em;">The Disruption</h2>
<p>OSGi has the potential to have have a much broader impact, affecting everyone from the developer to those working in the data center.  So what might this trend be that will propel OSGi to stardom?</p>
<blockquote><p>OSGi enables ecosystems!</p></blockquote>
<p>Now, you’re thinking I’ve gone on the deep end, perhaps? But give me a chance…let me explain.</p>
<h2 style="font-size: 1.5em;">A Bit of [Recent] Platform History</h2>
<p>To start, I want to take a brief walk down memory lane. Not too far back though, but far enough so that we can see how important the ecosystem is in today’s most successful platforms. And these platforms span a range of markets, from mobile to social media. But each are successful in large part due to a thriving ecosystem.</p>
<p><strong>Apple</strong></p>
<p>In 2007, Apple released their first generation iPhone. Without question, the device revolutionized the mobile phone industry. While the device offers a great user experience that has certainly played a role in its surging popularity, people flock to the iPhone today because of the wealth of applications available. Yeah, “there’s an app for that.”</p>
<p>Apple, recognizing the power of this ecosystem, now delivers the iPad. With fewer preinstalled applications than the iPhone, Apple is counting on the ecosystem to drive adoption. The more consumers who flock to the device, the more developers who flock to the platform to deliver applications. As more applications become available, consumers will buy more iPads. The ecosystem fuels itself. Apple has simply provided the environment for the ecosystem to thrive.</p>
<p><strong>Eclipse</strong></p>
<p>In 2003, the Eclipse team was thinking of ways to make Eclipse more dynamic. Their decision to use OSGi to create a rich client platform that supports plug-in architecture was the first step toward the resulting ecosystem we know today. One of the reasons developers use Eclipse is because there are an abundance of plug-ins available that allow them to do their jobs more effectively. Other developers create Eclipse plug-ins because Eclipse is a popular IDE used by many developers. Again, the ecosystem fuels itself. The Eclipse team provided the environment that allows today’s Eclipse ecosystem to thrive.</p>
<p>If you’re interested, you can read more about the history of Eclipse and OSGi.</p>
<p><strong>Hudson</strong></p>
<p>Arguably, Hudson is today’s most popular continuous integration server. But it hasn’t always been. Before Hudson was CruiseControl. And while CruiseControl did help development teams get started on their path toward continuous integration, it was also unwieldy to use in many ways. With Hudson’s plug-in architecture, developers have the ability to extend the tool in ways the original creator couldn’t imagine or couldn’t find the time to do himself. Kohsuke created Hudson and gave the development community a new platform for continuous integration. With its plug-in architecture though, he also provided an environment that allows the Hudson ecosystem to thrive.</p>
<p><strong>Social Media</strong></p>
<p>Facebook. MySpace. Twitter. Each are examples of social media tools with a strong developer community that creates extensions to the platform that users can leverage to enhance the experience. Facebook Developers. MySpace Developer Platform. Twitter API. Each allows the ecosystem to thrive.</p>
<p><strong>And Others</strong></p>
<p>These are just a few examples. It’s easy to find other platforms with similar ecosystems, as well. The ease with which Wordpress themes and plug-ins can be developed and used to enhance a Wordpress website is another example. In fact, many content management systems provide similar capabilities. A large reason why the Firefox web browser has emerged as the preferred web browser is the ease with which add-ons can be installed that extend the capabilities of the browser. The Atlassian Plugin Framework is another example that uses OSGi, and platforms such as Force.com and SharePoint have built (or are trying to build) similar ecosystems.</p>
<h2 style="font-size: 1.5em;">The Power of Ecosystems</h2>
<p>Aside from Eclipse (and Atlassian), none of these other platforms leverage OSGi. Yet each are wildly successful because of two reasons:</p>
<p>An environment was created that allowed an ecosystem to form and flourish. This environment includes a platform and a marketplace.</p>
<p>A group of customers and developers converged on the marketplace and fueled growth of the platform. The result is a self-sustaining ecosystem.</p>
<p>If you look at many of the more popular platforms that have emerged over the past decade, they tend to possess a similar characteristic &#8211; a community of individuals dedicated to providing great solutions leveraging the foundation of the platform. OSGi and modularity enables ecosystems on the Java platform.</p>
<h2 style="font-size: 1.5em;">Ecosystem and the Two Faces of Modularity</h2>
<p>In Chapter XX, we talked about the two faces of OSGi &#8211; the runtime model and the development model. I’ve also explained how one could possibly see widespread adoption while the other has little impact. A strong ecosystem surrounding OSGi and modularity must leverage both. Developers would create reusable modules, implying they are designing modular software. For development teams to leverage these modules, they must be using a platform that supports the runtime model.</p>
<h2 style="font-size: 1.5em;">CBD Has Already Had It&#8217;s Day, You Say?</h2>
<p>Now some of you might be arguing that this sounds a lot like the component based development (CBD) fad of the 1990’s. True…to an extent. Certainly these ideas are not new. But there are also some striking differences between that which OSGi enables and the CBD fad that has come and largely gone, or whose promise was never fully realized.</p>
<p>Foremost, the CBD fad was focused almost exclusively on visual components, such as ActiveX. While some attempted to create components for the Java platform, the movement largely failed to go mainstream. Instead, Java EE grew in popularity and for a number of years, garnered everyone’s attention. Why did this  happen?</p>
<p>IMHO, the answer is fairly simple. Even though numerous marketplaces emerged that allowed the consumer and producer to come together to buy and sell components, there was never a suitable component execution environment. That is, an environment that would support dynamic deployment, support for multiple versions, dependency management, and, in general, complete control over all components currently executing within the environment. ActiveX components did have an execution environment (though did not support each of these capabilities), but Java did not. Today, in OSGi, Java has the requisite execution environment!</p>
<h2 style="font-size: 1.5em;">The Ecosystem</h2>
<p>It’s easy find holes in this idea. To explain why it cannot work. Yet, it’s happening elsewhere, so why not on the server…in the enterprise? Certainly there are a variety of different ways such an ecosystem could manifest itself. Possibly multiple ecosystems emerge like what we see in the mobile market today.</p>
<p>But for a moment, imagine the world where you have the ability to easily assemble a platform from pre-built infrastructure modules that exactly meet the demands of your application. You might purchase these modules, you might choose to use open source modules, or you might build them yourself. For those you don’t build, you obtain from a module marketplace, possibly deploying them to your [cloud] environment.</p>
<p>And when you choose to use a module, it’s dynamically deployed to your environment. The modules it depends upon? You’re given the option to purchase and deploy them, as well. You develop your software modules using the sound principles and patterns of modular design to ensure loose coupling and high cohesion. As you roll out your business solution modules, you simultaneously deploy the additional infrastructure modules that are needed.</p>
<p>In this marketplace, modules are sourced by multiple vendors. Some large. Some small. Neither the stack, nor your applications, are monolithic beasts. Instead, they are a composition of collaborating software modules. Your infrastructure isn’t necessarily tied to a specific vendor solution. The option always exists for organizations to purchase modules from different providers, easily swapping one provider module out with another.</p>
<p>The ecosystem flourishes. Developers flock to sell their latest creation. Organizations seek to add amazing capabilities to their rightsized environment at a fraction of the cost compared to what they are accustomed to today. The business benefits are real. The technical advantages are real. And the resulting ecosystem is sustainable.</p>
<p>A successful ecosystem demands both the runtime model and development model. And today, OSGi is the only standard technology that will allow this type of successful ecosystem to form on the Java platform. But will it happen? We may have a ways to go, but it sure would be cool! And it would be a shame if we lost this opportunity.</p>
<p>Additional Notes</p>
<p>Discuss the future of modularity and the impact OSGi will have on enabling and enforcing modularity, as well as how these patterns will be implemented and supported by OSGi.</p>
<p>For instance, PublishedInterface is directly enabled by OSGi export packages.</p>
<p>Note the increasing platform support and that development teams will be able to use it soon.</p>
<p>Note the impact, not just on the developer and how applications are created, but also in how they are managed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2010/04/the-future-of-modularity-osgi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SOLID Principles of Class Design</title>
		<link>http://www.kirkk.com/modularity/2009/12/solid-principles-of-class-design/</link>
		<comments>http://www.kirkk.com/modularity/2009/12/solid-principles-of-class-design/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 20:15:47 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=453</guid>
		<description><![CDATA[The SOLID principles lie at the heart of the object-oriented paradigm. Many of the principles presented here first appeared in Robert Martin’s Design Principles and Design Principles [MARTIN2000], which serves as an excellent complement to this discussion. These principles help you manage dependencies between classes and encourage class cohesion. They are also critical to effective [...]]]></description>
			<content:encoded><![CDATA[<p>The SOLID principles lie at the heart of the object-oriented paradigm. Many of the principles presented here first appeared in Robert Martin’s Design Principles and Design Principles [MARTIN2000], which serves as an excellent complement to this discussion. These principles help you manage dependencies between classes and encourage class cohesion. They are also critical to effective module design using object oriented techniques.</p>
<h2>Single Responsibility Principle (SRP)</h2>
<blockquote><p>Classes should change for only a single reason.</p></blockquote>
<p>The basis for this principle is cohesion. Cohesion represents the measure to which a class performs a single function. Classes that are highly cohesive are easier to understand. But they are also easier to maintain. This is the motivating force behind SRP. If a class has more than one reason to change, then it stands to reason that the responsibilities of that class that are the cause of change should be separated into multiple classes.</p>
<p>Cohesion is not a concept new to objects. In fact, the concept is taught in most introductory programming courses. Ironically, I&#8217;ve found that while most developers can easily define cohesion and explain it&#8217;s benefits, few developers actually apply it. Cohesion measures the degree to which an entity does a single thing. Given this definition, it&#8217;s no surprise that if some entity is responsible for performing only a single thing, most of our entities should be fairly small. Yet I commonly come across methods that run well over 100 lines of code, and classes that run orders of magnitudes larger than that. I struggle to convince myself that either are very cohesive. When you&#8217;re designing a highly cohesive system, you have to think small.</p>
<h2>Open Closed Principle (OCP)</h2>
<blockquote><p>Classes should be open for extension, but closed for modification.</p></blockquote>
<p>The Open Closed Principle (OCP) is undoubtedly the most important of all the class category principles. In fact, each of the remaining class principles are derived from OCP. It originated from the work of Bertrand Meyer who is recognized as an authority on the object-oriented paradigm. OCP is states that we should have the ability to add new features to our system without having to modify our set of preexisting classes. As stated previously, one of the benefits of the object-oriented paradigm is to enable us to add new data structures to our system without having to modify the existing system’s code base.</p>
<p>Let’s look at an example to see how this can be done. Consider a financial institution where we have to accommodate different types of accounts to which individuals can make deposits. Figure 4.1 shows a class diagram, with accompanying descriptions of some of the elements and how we might structure a portion of our system. For the purposes of our discussion in this chapter, we will focus on how the OCP can be used to extend the system.</p>
<p>Our Account class has a relationship to our AccountType abstract class. In other words, our Account class is coupled at the abstract level to the AccountType inheritance hierarchy. Because our Savings and Checking classes each inherit from the AccountType class, we know that through dynamic binding, we can substitute instances of either of these classes wherever the AccountType class is referenced. Subsequently, Savings and Checking can be freely substituted for AccountType within the Account class. This is the intent of an abstract class and enables us to effectively adhere to OCP by creating a contract between the Account class and the AccountType descendents. Because our Account is not directly coupled to either of the concrete Savings or Checking classes, we can extend the AccountType class, creating a new class such as MoneyMarket, without having to modify our Account class. We have achieved OCP and can now extend our system without modify its existing code base.</p>
<p>Figure 4.1<br />
Therefore, one of the tenets of OCP is to reduce the coupling between classes to the abstract level. Instead of creating relationships between two concrete classes, we create relationships between a concrete class and an abstract class or, in Java, between a concrete class and an interface. When we create an extension of our base class, assuming we adhere to the public methods and their respective signatures defined on the abstract class, we have essentially achieved OCP. Let’s take a look at a simplified version of the Java code for this example, focusing on how we achieve OCP, instead of on the actual method implementations.</p>
<pre class="brush: java;">
public class Account {
   private AccountType _act;
   public Account(String act) {
      try {
         Class c = Class.forName(act);
         this._act = (AccountType) c.newInstance();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   public void deposit(int amt) {
      this._act.deposit(amt);
   }
}
</pre>
<p>Here, our Account class accepts as an argument to its constructor a String representing the class we wish to instantiate. It then uses the Class class to dynamically create an instance of the appropriate AccountType subclass. Note that we don’t explicitly refer to either the Savings or Checking class directly.</p>
<pre class="brush: java;">
public abstract class AccountType  {
   public abstract void deposit(int amt);
}</pre>
<p>This is the abstract AccountType class that serves as the contract between our Account class and AccountType descendents. The deposit method is the contract.</p>
<pre class="brush: java;">
public class CheckingAccount extends AccountType {
   public void deposit(int amt) {
      System.out.println();
      System.out.println();
      System.out.println(&quot;Amount deposited in checking account: &quot; + amt);
      System.out.println();
      System.out.println();
   }
}
</pre>
<pre class="brush: java;">
public class SavingsAccount extends AccountType {
   public void deposit(int amt)  {
      System.out.println();
      System.out.println();
      System.out.println(&quot;Amount deposited in savings account: &quot; + amt);
      System.out.println();
      System.out.println();
   }
}
</pre>
<p>Each of our AccountType descendents satisfies the contract by providing an implementation for the deposit method. In the real world, the behaviors of the individual deposit methods would be more interesting and, given the preceding design, would be algorithmically different.</p>
<h2>Liskov Substitution Principle (LSP)</h2>
<blockquote><p>Subclasses should be substitutable for their base classes.</p></blockquote>
<p>We mentioned in our previous discussion that OCP is the most important of the class category principles. We can think of the Liskov Substitution Principle (LSP) as an extension to OCP. In order to take advantage of LSP, we must adhere to OCP because violations of LSP are also a violation of OCP, but not vice versa. LSP is the work of Barbara Liskov and is derived from Bertrand Meyer’s Design by Contract. In its simplest form, it is difficult to differentiate OCP and LSP, but a subtle difference does exist. OCP is centered around abstract coupling. LSP, while also heavily dependent on abstract coupling, is also heavily dependent on preconditions and postconditions, which is LSP’s relation to Design by Contract, where the concept of preconditions and postconditions was formalized.</p>
<p>A precondition is a contract that must be satisfied before a method can be invoked. A postcondition, on the other hand, must be true upon method completion. If the precondition is not met, the method should not be invoked, and if the postcondition is not met, the method should not return. The relation of preconditions and postconditions has meaning embedded within an inheritance relationship that is not supported within Java, outside of some manual assertions or nonexecutable comments. Because of this, violations of LSP can be difficult to find.</p>
<p>To illustrate LSP and the interrelationship of preconditions and postconditions, we need only consider how Java’s exception handling mechanism works. Consider a method on an abstract class that has the following signature:</p>
<pre class="brush: java;">
public abstract deposit(int amt) throws InvalidAmountException
</pre>
<p>Assume in this situation, that our InvalidAmountException is an exception defined by our application, is inherited from Java’s base Exception class, and can be thrown if the amount we try to deposit is less than zero. By rule, when overriding this method in a subclass, we cannot throw an exception that exists at a higher level of abstraction than InvalidAmountException. Therefore, a method declaration such as the following is not allowed:</p>
<pre class="brush: java;">
public void deposit(int amt) throws Exception
</pre>
<p>This method declaration is not allowed because the Exception class thrown in this method is the ancestor of the InvalidAmountException thrown previously. Again, we cannot throw an exception in a method on a subclass that exists at a higher level of abstraction than the exception thrown by the base class method we are overriding. On the other hand, reversing these two method signatures would have been perfectly acceptable to the Java compiler. We can throw an exception in an overridden subclass method that is at a lower level of abstraction than the exception thrown in the ancestor. While this does not correspond directly to the concept of preconditions and postconditions, it does capture the essence. Therefore, we can state that any precondition stipulated by a subclass method cannot be stronger than the base class method.Therefore, any postcondition stipulated by a subclass method cannot be weaker than the base class method.</p>
<p>To adhere to LSP in Java, we must make sure that developers define preconditions and postconditions for each of the methods on an abstract class. When defining our subclasses, we must adhere to these preconditions and postconditions. If we do not define preconditions and postconditions for our methods, it becomes virtually impossible to find violations of LSP. Suffice it to say, in the majority of cases, OCP will be our guiding principle.</p>
<h2>Dependency Inversion Principle (DIP)</h2>
<blockquote><p>Depend upon abstractions. Do not depend upon concretions.</p></blockquote>
<p>The Dependency Inversion Principle (DIP) formalizes the concept of abstract coupling and clearly states that we should couple at the abstract level, not at the concrete level. Abstract coupling is the notion that a class is not coupled to another concrete class, or class that can be instantiated. Instead, the class is coupled to other base, or abstract, classes. In Java, this abstract class can be either a class with the abstract modifier or a Java interface data type. Regardless, this concept is actually the means through which LSP achieves its flexibility, the mechanism required for DIP, and the heart of OCP.</p>
<p>In our own designs, attempting to couple at the abstract level can at times seem like overkill. Pragmatically, we should apply this principle in any situation where we are unsure whether the implementation of a class may change in the future. We have encountered situations during development where we know exactly what needs to be done. Requirements state this very clearly, and the probability of change or extension is quite low. In these situations, adherence to DIP may be more work than the benefit realized.<br />
At this point, there exists a striking similarity between DIP and OCP. In fact, these two principles are closely related. Fundamentally, DIP tells us how we can adhere to OCP. Or, stated differently, if OCP is the desired end, DIP is the means through which we achieve that end. While this statement may seem obvious, we commonly violate DIP in a certain situation and don’t even realize it.</p>
<p>When we create an instance of a class in Java, we typically must explicitly reference that object. Only after the instance has been created can we flexibly reference that object via its ancestors or implemented interfaces. Therefore, the moment we reference a class to create it, we have violated DIP and, subsequently, OCP. Recall that in order to adhere to OCP, we must first take advantage of DIP. There are a couple of different ways to resolve this.</p>
<p>The first way to resolve this impasse is to dynamically load the object using the Class class and its newInstance method. However, this solution can be problematic and somewhat inflexible. Because DIP doesn’t allow us to refer to the concrete class explicitly, we must use a String representation of the concrete class. For instance, consider the following:</p>
<pre class="brush: java;">
Class c = Class.forName(&quot;SomeDescendent&quot;); SomeAncestor sa = (SomeAncestor) c.newInstance();
</pre>
<p>In this example, we wish to create an instance of the class SomeDescendent in the first line, but reference it as type SomeAncestor in the second line. This was also illustrated in the code samples in the section “Open Closed Principle (OCP),” earlier in this chapter. This is perfectly acceptable, as long as the SomeDescendent class is inherited, either directly or indirectly, from the SomeAncestor class. If it is not, our application will throw an exception at runtime. Another more obvious problem occurs when we misspell the class of which we want an instance. Yet another, less apparent, obstacle eventually is encountered when taking this approach. Because we reference the class name as a string, there isn’t any way to pass parameters into the constructor of this class. Java does provides a solution to this problem, but it quickly becomes complex, unwieldy, and error prone.</p>
<p>Another approach to resolving the object creation challenge is to use an object factory. Here, we create a separate class whose only responsibility is to create instances. This way, our original class, where the instance would have previously been created, stays clear of any references to concrete classes, which have been removed and placed in this factory. The only references contained within this class are to abstract, or base, classes. The factory does, however, reference the concrete classes, which is, in fact, a blatant violation of DIP. However, it is an isolated and carefully thought through violation and is therefore acceptable.</p>
<p>Keep in mind that we may not always need to use an object factory. Along with the flexibility of a factory comes the complexity of a more dynamic collaboration of objects. Concrete references are not always a bad thing. If the class to which we are referring is a stable class, not likely to undergo many changes, using a factory adds unwarranted complexity to our system. If a factory is deemed necessary, the design of the factory itself should be given careful consideration.</p>
<h2>Interface Segregation Principle</h2>
<blockquote><p>Many specific interfaces are better than a single, general interface.</p></blockquote>
<p>Put simply, any interface we define should be highly cohesive. In Java, we know that an interface is a reference data type that can have method declarations, but no implementation. In essence, an interface is an abstract class with all abstract methods. As we define our interfaces, it becomes important that we clearly understand the role the interface plays within the context of our application. In fact, interfaces provide flexibility: They allow objects to assume the data type of the interface. Subsequently, an interface is simply a role that an object plays at some point throughout its lifetime. It follows, rather logically, that when defining the operation on an interface, we should do so in a manner that does not accommodate multiple roles. Therefore, an interface should be responsible for allowing an object to assume a single role, assuming the class of which that object is an instance implements that interface.</p>
<p>While working on a project recently, an ongoing discussion took place as to how we would implement our data access mechanism. Quite a bit of time was spent designing a flexible framework that would allow uniform access to a variety of different data sources. These back-end data sources might come in the form of a relational database, a flat file, or possibly even another proprietary database. Therefore, our goal was not only to provide a common data access mechanism, but also to present data to any class acting as a data client in a consistent manner. Doing so would clearly decouple our data clients from the back-end data source, making it much easier to port our back-end data sources to different platforms without impacting our data clients. Therefore, we decided that all data clients would depend on a single Java interface, depicted in Figure 4.3, with the associated methods.</p>
<p>Figure 4.3</p>
<p>At first glance, the design depicted in Figure 4.3 seemed plausible. After further investigation, however, questions were raised as to the cohesion of the RowSetManager interface. What if classes implementing this interface were read-only and didn’t need insert and update functionality? Also, what if the data client were not interested in retrieving the data, but only in iterating its already retrieved internal data set? Exploring these questions a bit further, and carefully considering ISP, we found that it was meaningful to have a data structure that wasn’t even dependent on a retrieve action at all. For instance, we may wish to use a data set that was cached in memory and wasn’t dependent on an underlying physical data source. This led us to the design in Figure 4.4.</p>
<p>Figure 4.4</p>
<p>In Figure 4.4, we see that we have segregated the reponsibilities of our RowSetManager into multiple interfaces. Each interface is responsible for allowing a class to adhere to a cohesive set of responsibilities. Now, our application can implement the interfaces necessary to provide the desired set of functionality. We are no longer forced to provide data update behavior if our class is read-only.</p>
<h2>Composite Reuse Principle (CRP)</h2>
<blockquote><p>Favor polymorphic composition of objects over inheritance.</p></blockquote>
<p>The Composite Reuse Principle (CRP) prevents us from making one of the most catastrophic mistakes that contribute to the demise of an object-oriented system: using inheritance as the primary reuse mechanism. The first reference to this principle was in [GOF94]. For example, let’s turn back to a section of our diagram in Figure 4.1. In Figure 4.5, we see the AccountType hierarchy with a few additional attributes and methods added. In this example, we have added an additional method that calculates the interest for each of our accounts. We have added this method to the ancestor AccountType class. This seems to be a good approach, because our Savings and MoneyMarket classes are each interest bearing accounts. Our Checking class is representative of an account that is not interest bearing. Regardless, we justify this by convincing ourselves that it’s better to define some default behavior on an ancestor and override it on descendents instead of duplicating the behavior across descendents. We know that we can simply define a null operation  on our Checking class that doesn’t actually calculate interest, and our problem is solved. While we do want to reuse our code, and we can prevent the Checking class from calculating interest, our implementation contains a tragic flaw. First, let’s discuss the flaw and when it will surface. Then we’ll discuss why this problem has occurred.</p>
<p>Let’s consider a couple of new requirements. We need to support the addition of a new account type, called Stock. A Stock does calculate interest, but the algorithm for doing so is different than the default defined in our ancestor AccountType. That’s easy to solve. All we have to do is override the calculateInterest in our new Stock class, just as we did in the Checking class, but instead of implementing a null operation , we can implement the appropriate algorithm. This works fine until our business realizes that the Stock class is doing extremely well, primarily because of its generous interest calculation mechanism. It’s been decided that MoneyMarket should calculate interest using the same algorithm as Stock, but Savings remains the same. How do we solve this problem? We have three choices. First, redefine the calculateInterest method on our AccountType to implement this new algorithm and define a new method on Savings that implements the older method. This option is not ideal because it involves modifying at least two of our existing system classes, which is a blatant violation of OCP. Second, we could simply override calculateInterest on our MoneyMarket class, copy the code from our Stock class, and paste it in our MoneyMarket calculateInterest method. Obviously, this option is not a very flexible solution. Our goal in reuse is not copy and paste. Third, we can define a new class called InterestCalculator, define a calculateInterest method on this class that implements our new algorithm, and then delegate the calculation of interest from our Stock and MoneyMarket classes to this new class. So, which option is best?</p>
<p>The third solution is the one we should have used up front. Because we realized that the calculation of interest was not common to all classes, we should not have defined any default behavior in our ancestor class. Doing so in any situation inevitably results in the previously described outcome. Let’s now resolve this problem using CRP.</p>
<p>Figure 4.5</p>
<p>In Figure 4.6, we see a depiction of our class structure utilizing CRP. In this example, we have no default behavior defined for calculateInterest in our AccountType hierarchy. Instead, in our calculateInterest methods on both our MoneyMarket and Savings classes, we defer the calcuation of interest to a class that implements the InterestCalculator interface. Now, when we add our Stock class, we simply choose the InterestCalculator that is applicable for this new class or define a new one if it’s needed. If any of our other classes need to redefine their algorithms, we have the ability to do so because we are abstractly coupled to our interface and can substitute any of the classes that implement the interface anywhere the interface is referenced. Therefore, this solution is ultimately flexible in how it enables us to calculate interest. This is an example of CRP. Each of our MoneyMarket and Savings classes are composed of our InterestCalculator, which is the composite. Because we are abstractly coupled, we easily see we can receive polymorphic behavior. Hence, we have used polymorphic composition instead of inheritance to achieve reuse.</p>
<p>Figure 4.6</p>
<p>You might say at this point, however, that we still have to duplicate some code across the Stock and MoneyMarket classes. While this is true, the solution still solves our initial problem, which is how to easily accommodate new interest calculation algorithms.Yet an even more flexible solution is available, and one that will enable us to be even more dynamic in how we configure our objects with an instance of InterestCalculator.</p>
<p>In Figure 4.7, we have moved the relationship to InterestCalculator up the inheritance hierarchy into our AccountType class. In fact, in this scenario, we are back to using inheritance for reuse, though a bit differently. Our AccountType knows that it needs to calculate interest, but it does not know how actually to do it. Therefore, we see a relationship from AccountType to our InterestCalculator. Because of this relationship, all accounts calculate interest. However, if one of our algorithms is a null object [PLOP98] (that is, it’s an instance of a class that implements the interface and defines the methods, but the methods have no implementation), and we use the null object with the Savings class, we can now state that all of our accounts need to calculate interest. This substantiates our use of implementation inheritance. Because each account calculates it differently, we configure each account with the appropriate InterestCalculator.</p>
<p>Figure 4.7</p>
<p>So how did we fall into the original trap depicted in Figure 4.5? The problem lies within the inheritance relationship. Inheritance can be thought of as a generalization over a specialization relationship—that is, a class higher in the inheritance hierarchy is a more general version of those inherited from it. In other words, any ancestor class is a partial descriptor that should define some default characteristics that will be applicable to any class inherited from it. Violating this convention almost always results in the situation described previously. In fact, any time we have to override default behavior defined in an ancestor class, we are saying that the ancestor class is not a more general version of all of its descendents but actually contains descriptor characteristics that make it too specialized to serve as the ancestor of the class in question. Therefore, if we choose to define default behavior on an ancestor, it should be general enough to apply to all of its descendents.</p>
<p>In practice, CRP is applied a bit differently. In fact, it’s not uncommon to define a default behavior in an ancestor class. However, we should still accommodate CRP in our relationships. This is easy to see in Figure 4.6. We could have easily defined default behavior in our calcuateInterest method on the AccountType class. We still have the flexibility, using CRP, to alter the behaviors of any of our AccountType classes because of the relationship to InterestCalculator. In this situation, we may even choose to create a null op InterestCalculator class that our Checking class uses. This way, we even accommodate the likelihood that Savings accounts can someday calculate interest. We have ultimate flexibility.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2009/12/solid-principles-of-class-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>External Configuration</title>
		<link>http://www.kirkk.com/modularity/2009/12/external-configuration/</link>
		<comments>http://www.kirkk.com/modularity/2009/12/external-configuration/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 20:22:54 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Part 2]]></category>
		<category><![CDATA[Usability Pattern]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=378</guid>
		<description><![CDATA[For the full description, implementation variations, consequences, and detailed sample, see Page 200 in Java Application Architecture.
Statement
Modules should be externally configurable.
Description
The ability to configure a module to it&#8217;s usage context increases our ability to reuse the module across contexts, whereas tightly coupling configuration to the module prohibits reuse. External configuration allows a module to be [...]]]></description>
			<content:encoded><![CDATA[<p><em>For the full description, implementation variations, consequences, and detailed sample, see Page 200 in Java Application Architecture.</em></p>
<h2>Statement</h2>
<p>Modules should be externally configurable.</p>
<h2>Description</h2>
<p>The ability to configure a module to it&#8217;s usage context increases our ability to reuse the module across contexts, whereas tightly coupling configuration to the module prohibits reuse. External configuration allows a module to be reconfigured across environments, and even within it&#8217;s existing environment, without demanding redeploying the module.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-381" style="border: 0pt none;" title="ExternalConfiguration" src="http://www.kirkk.com/modularity/wp-content/uploads/2009/12/ExternalConfiguration.jpg" alt="ExternalConfiguration" width="557" height="99" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2009/12/external-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Module Facade</title>
		<link>http://www.kirkk.com/modularity/2009/12/module-facade/</link>
		<comments>http://www.kirkk.com/modularity/2009/12/module-facade/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 20:08:52 +0000</pubDate>
		<dc:creator>kirk knoernschild</dc:creator>
				<category><![CDATA[Part 2]]></category>
		<category><![CDATA[Usability Pattern]]></category>

		<guid isPermaLink="false">http://www.kirkk.com/modularity/?p=373</guid>
		<description><![CDATA[For the full description, implementation variations, consequences, and detailed sample, see Page 212 in Java Application Architecture.
Statement
Create a facade serving as a coarse-grained entry point to the modules underlying implementation.
Description
We create fine-grained and lightweight modules to increase module reuse. Unfortunately, fine-grained modules can also be difficult to use because the user must understand the API [...]]]></description>
			<content:encoded><![CDATA[<p><em>For the full description, implementation variations, consequences, and detailed sample, see Page 212 in Java Application Architecture.</em></p>
<h2>Statement</h2>
<p>Create a facade serving as a coarse-grained entry point to the modules underlying implementation.</p>
<h2>Description</h2>
<p>We create fine-grained and lightweight modules to increase module reuse. Unfortunately, fine-grained modules can also be difficult to use because the user must understand the API of several different modules and use them in conjunction with each other to accomplish a particular task. Additionally, lightweight modules must also be configured to an environmental context. Because of this, fine-grained and lightweight modules are generally more difficult to use. A Module Facade is useful to provide a higher level API that coordinates the work of a set of fine-grained modules.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-374" style="border: 0pt none;" title="ModuleFacade" src="http://www.kirkk.com/modularity/wp-content/uploads/2009/12/ModuleFacade.jpg" alt="ModuleFacade" width="699" height="572" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kirkk.com/modularity/2009/12/module-facade/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

