Domain Specific Reference Architectures

Many big vendors have invested a lot on blue print or reference architectures.  I came across another in recent months.  I witnessed a vendor team moving from client to client implementing this reference architecture as part of their SOA solution.
What were they actually doing? They were mapping the client’s domain to the reference architecture domain and thereby identified reference architecture services that supported the client’s needs.  This most probably works for some people.   But I feel uncomfortable with it because…

  • It means translating from one domain to another and back again.  It’s like having one massive bounded context around the reference architecture with a gigantic set of adaptors and transformers.
  • There is a very real possibility of semantic impedance on the boundary of the two domains.
  • There is likely to be two domain vocabularies or one large polluted vocabulary with synonyms, etc.

There are other reasons but these few are just old problems and habits coming back again.  Things that we accepted as dangerous and limits success in creating good software.

So, are reference architectures bad? Yes and no.  Maybe you should consider adopting its domain vocabulary as a first step.  A reference architecture with a rich metamodel is more likely to be more valuable than one without a metamodel.

And the moment you start thinking at a meta level, then you’re moving into a higher level of abstraction.  In this higher level, you will have a greater opportunity to describe your intentions agnostic of the reference architecture and the vendor’s technology stack.

The way I see it, services are defined at a meta level.  They describe your intentions and are independent of a reference architecture.  However, if you chose a reference architecture up front, then describe your intentions in the vocabulary of the reference architecture.

Does this make sense?  Because I’m just hypothesising here.

Learning Rules for Noobs

The unfortunate human characteristic in all of us is that we like rules when we’re in a new and unfamiliar situation, and hate them the moment we think we are experts.  The problem is that rules are great for creating concrete things.  If you want to build this then: do a, then b, if you have a c then do d otherwise do e.  But it does not work with creating abstract things.  And software development is all about building abstractions.
In the past few weeks, I’ve had a few instances where I realized that some people were,  basically, asking me for DDD rules – steps for building an aggregate, when and how to use the specification pattern, etc.  There are no rules for the noobs for these things.  But I think I can constrain the environment so that the noobs can focus a bit more intimately with these aggregates and specifications.    One rule I put down was “When working with the following … don’t work outside of this Java package”

Essentially, my proposition is that rules for noobs should constrain the learning environment, not the subject being studied.

The Reincarnation of SOA

Anne Thomas Manes wrote a farewall for SOA in her blog post SOA is Dead, Long Live ServicesInfoQ asked for comment from SOA thought leaders and architects on this matter which created quite a stir and the usual amount of noise as well.  One of the most interesting responses I read was from Stefan Tilkov in his blog post Defending SOA.  Now I cannot resist, but give my perspective.
SOA is an attempt to create an architectural style that embodies the heart of the business – the domain.  In any business the domain is vast and so there are many subdomains or even very distinct domains.  In my workshop on Bootstrapping Your SOA Project, I defined a service very traditionally as providers and consumers connected by some execution context that hides implementation.  Now, I like to abstract it a bit more and think of services as business intentions.  These intentions cut right through the fat and get very close to the bone which is all about the domain.  That’s why I think DDD is at the heart of SOA.

Is SOA dead? Not yet but the vendors are doing a great job of killing it with implementations.

Should SOA die? No.  it’s an architectural style worth cherishing since it deals with legacy and new software at the same time, hence spanning multiple systems (like Stefan Tilkov nicely explains).

Does SOA need an ESB? Not necessarily. I think the ESB is just a pattern that happens to have an implementation called the ESB (vocabulary that sucks!).  I have seen some some really complex solutions with an ESB that would have worked just fine with, for example, a simple RMI call instead.

Is it about Business Process Management? Partially.  When you span multiple systems then you will likely do so with processes.  But it’s all about managing state across multiple systems and what nicer way is there than transferring state, i.e. being RESTful (and I am not talking about REST over HTTP).  This also suggests that you should think asynchronously as well.

Is SOA heavyweight? No.  But the vendors make it very, very heavyweight because that is the core of their economic model.  I like to think about all the little Unix command line tools that you can string together to solve a particular problem, like the FindAndDeleteAllOldLogs capability that is part of the FileManagementService 🙂

What is killing SOA? The lack of readiness for existing systems that comes from existing software development thinking in most teams.  SOA demands that you think about state, scalability, ownership, backward compatibility, testability … things that go towards creating decent API’s for your systems.  And the more vendor swagger we have, the less development teams think about API’s.

Is SOA Dead? Yes.  It was still born.  But it will be reincarnated as SOA when vendors focus on tools to help people discover domains and increase automation, and not creating heavyweight obstructions;  and when developers figure out that domain understanding is vital and writing good API’s  still count – more than ever before.

Measuring the Clarity of Requirements

The last two geeky conversations I had, stumbled upon the same thing – how do you measure the effectiveness of requirements in describing the business to the business and describing the specification to the developer?
So, I posed the question “How far away are you from executing your requirements?”. If you are going to go through various steps and stages to get to compilation and then execution, then every step is an opportunity for valuable information being lost in translation. If you can compile your requirements immediately then nothing will be lost.

Each additional step between requirements description and compilation and execution is an opportunity to confuse the user and the developer and everyone in between.  That’s why fully dressed use cases are not so effective as fully dressed behavior driven stories.  And that’s why BDD is very agile and a great asset in DDD and use cases just don’t cut it anymore.

Right now, my favorite tool is Cucumber.  I can execute the requirements and that raises the clarity ranking of my requirements super high.

Discovering Language and Context

Last night, I attended the 43rd Cape Town SPIN meeting that turned out to be a fun, interactive exercise with John Gloor. John introduced a system of analysis which focused on modeling a domain – but not from and object oriented paradigm. It was more about “things” and “influences”. I am really doing a bad job of using the right terms, but let’s just try something out.

  1. As a group define (frame?) your problem domain (We chose “How to be a successful team”)
  2. Then individually…
    • write down as many thoughts about the domain as possible – short snippets of 3-8 words each.  The recommendation was to aim for about 70 thoughts.
    • Color code (or group) these based on some notion of similarity.
    • Give each group a name or label on a post-it
  3. Then as a group …
    • the first person sticks their post-its on the wall
    • each other person, in turn, then sticks their post-its up and aligns it with whatever else is already on the board (or creates a new spot altogether)
    • Optimize the emerging clusters and give them names
  4. Finally, put directed lines between the named clusters using the guide of “A influences B” and give the line a label as well.

We never had the time to get to complete step 6.  But the really interesting angle for me was that a language for the domain was emerging.  It was not perfect, but it was a nice start.  Secondly, some of the clusters felt a lot like strategic contexts.  Sure, it was a conceptual decomposition of sorts, but it may well be a nice starting point for discovering bounded contexts.

And those influence lines felt like dependencies and interactions between contexts.  The use of the word “influence” is a really nice alternative to the traditionally naive terms like “uses”, “has”, “is like”.  It naturally focuses on behavioural interactions.

So, this simple exercise may be a nice technique for discovering language and contexts within a domain.  And it proves to me, yet again, that language is most critical.  This is not just about maintaining a lifeless glossary of terms – but the energy surrounding the vocabulary and terms need to be depicted and felt as well.  And if we combine all of this with an agile mindset, we can adjust this “language model” with each iteration and gain deeper domain understanding continuously.  Hmmm, this notion of “language model” is intriguing!

.NET Rocks! Podcast

Yesterday I had a telephonic chat with Richard Campbell and Carl Franklin from .NET Rocks! I tried to talk about modularity, but it kind of veered off into design in general and how an agile runtime is really important to being really agile.  A lot revolved around getting the domain understanding right before diving into object oriented design.  We touched on SOA, SaaS, UML, tools.  That’s a heck of a mess for less than an hour!
You can listen to the podcast here.  I think I just rambled on a lot about anything and everything and it felt like a wayward discussion to me at the time.  Have a listen and tell me what you think.  I really would like to improve myself for these kinds of events.

So, thanks a lot to the kind folk at .NET Rocks! for having me on their awesome show.  And for persisting with trying to get hold of me at the hotel in Lech, Austria.  I am deeply priviledged and humbled.  I hope I helped someone with my ramblings.

Oh, and many thanks to Jimmy Nilsson for all his help (again!).

Aural Ambiguous Assumptions

One of the nicest ways to learn or understand a new domain is to understand it’s vocabulary.  If you can have intelligent, unambiguous domain conversations using this vocabulary, then you are likely to immerse yourself in the domain quite deeply.  You see, it’s all about ubiquitous language.
But when do we start building our domain vocabulary?  Most likely when we hear domain terms for the first time in conversation.  But when we listen, we should not assume meaning.  And we should clear ambiguity by establishing the context.

I had a fun moment yesterday filled with aural ambiguous assumptions.  I was talking to a group involved in diamond trading and the one person said “… diamond sales at all our sites are …”.  Hmmm, that’s not hard to understand – site:  the place or location where diamonds are sold.

But what the person actually said was “… diamond sales at all our sights are …”.  Ooops, it turns out that the place of sale is actually the location when a cut and polished diamond is first seen by the buyer.  Ambiguous – yes,  Assumed – definitely, Contextual – absolutely.

Øredev Presentations

My presentations from Oredev are finally available.  After working through almost all the export options on Keynote, I have settled on QuickTime as the distro format.  The “flying code” in the aspects presentation worked out best with QuickTime.  Note that it’s not a continuous playback and you have to click-through each frame.

Concepts and Types

Last week, while working in a domain that was entirely new to me, I found myself using the word concept in domain conversations more often than I expected.  For example, I said something like “So, you mentioned forward exposure cover, which I understand a bit.  It seems to be about covering financial risks? Explain this concept of covering risk a bit more”. When I realised that “forward exposure cover” was a type in the domain (i.e. a class of sorts), I thought about “risk cover” again.  Is risk cover and forward exposure cover of the same type?
I like (want?) to think not.  I have spent a lot of time in recent months working with metadata and modeling of data itself.  In that time, I came across the concept of “concept”.  A concept is an abstract thing.  It cannot be manifest in anyway and is the metadata of concrete things.  It is not part of the type hierarchy but information about the type itself.  Concepts are part of an abstract general domain, perhaps not tied to any domain at all. But types are part of a specific domain.

So risk exposure is the metadata concept of the type forward exposure cover (in the domain of foreign exchange).  At the same time, risk exposure is the metadata concept of the type loss coverage (in the short term insurance domain).  Both types model vastly different things in vastly different domains but share the same purpose, i.e. have the same concept.  The concept risk exposure (in my layman’s terms) deals with danger or possibility of financial loss which holds true of loss coverage and forward exposure cover.

Subconsciously, I was looking for something that I was familiar with to understand something that was completely new.  Sometimes, finding the concept for a type may be better than finding a metaphor in our quest for gaining deeper insight.  This may be more valuable if the concept is the metadata for another type in a domain in which we already have deep(er) insight.

Factories, Builders and Fluent Interfaces

Last week I started working on very short proof of concept with a team that I am currently coaching at a short term insurance company.  We hit a very common design decision: when do we use a factory pattern and when do we use a builder pattern.
In the problem at hand, we needed to describe an item that will appear in an insurance policy that must be covered for fire damage.  It turns out that these items are not trivial in their structure, and many things influence the premium that will paid by the policy holder for fire insurance.  So, the first bit of code (in Java) in the test looked something like this.

FireItem fireItem = new FireItem();
fireItem.setIndustry("Building Construction");
fireItem.setOccupationCode("Workshop");
// the postal/zip code for the location of the insured item
fireItem.setAreaCode(7800);
// ignore the number, we actually created a Money class
fireItem.setSumInsured(200000.00);
fireItem.setRoofing("Non-Standard");

 

After the test passed, we refactored and I sneaked in a factory method which will be used to honor default values and at the same time threw in a fluent interface (the term coined by Eric Evans and Martin Fowler.  After all, I was also quietly introducing Domain Driven Design without actually saying that).

The code looked like this.

FireItem fireItem = FireItem.create()
                      .inIndustry("Building Construction")
                      .withOccupation("Workshop")
                      .InAreaWithPostalCode(7800)
                      .forSumInsured(200000.00)
                      .havingRoofing("Non-Standard");

The FireItem class looked like this:

public class FireItem {
    String industry;
    String occupation;
    // other properties ...

   private FireItem() { }
   public static FireItem create() {
       return new FireItem();
   }
   public FireItem inIndustry(String industry) {
      this.industry = industry;
      return this;
   }
   // other chained methods follow a similar style returning "this" ...
}

Nice! Much more readable. But, we then realised that it’s easy for someone to miss one of the methods in the chain.  That will result in the item having an incomplete structure.  Not good!  

One of the things I tend to do as a coach, is to let the team I am working with, experience the problem, solution and any rewards and smells as well.  Sometimes I even throw in red herring for sake of experience ;-).  So, the third pass at refactoring was to introduce a validate() method on the item which throws an exception if everything was not in place.

try {
  FireItem fireItem = FireItem.create()
                       .inIndustry("Building Construction")
                       .withOccupation("Workshop")
                       .InAreaWithPostalCode(7800)
                       .forSumInsured(200000.00)
                       .havingRoofing("Non-Standard")
                       .validate();
} catch (FireItemException e) {
  // handle the exception
}

Now the user of this class needs to know that the validate() method must be called before they really want to use an item object.  Yuck, that’s smelly!  So, for the fourth design refactoring, I introduced a builder and moved the fluent interface to the builder, still using method chaining but introduced a build() method that did the work of the previous validate() method before returning the well structured item.  The FireItem class now needs the traditional bunch of getters and setters (rant – the framework goodies need them anyway!!)

import static insurance.FireItemBuilder.fireItem;
// ...
try {
  FireItem fireItem = fireItem().inIndustry("Building Construction")
                         .withOccupation("Workshop")
                         .InAreaWithPostalCode(7800)
                         .forSumInsured(200000)
                         .havingRoofing("Non-Standard")
                         .build();
} catch (FireItemException e) {
   // handle the exception
}

Much better!  Note the use of the static import which gives us the liberty to use the static method without specifying the class in code body.  The FireItemBuilder class looked like this.

public class FireItemBuilder {
   private final FireItem fireItem;
   private FireItemBuilder() { 
      fireItem = new FireItem();
   }
   public static FireItemBuilder fireItem() {
       return new FireItemBuilder();
   }
   public FireItemBuilder inIndustry(String industry) {
      fireItem.setIndustry(industry);
      return this;
   }
   // other chained methods follow a similar style returning "this" ...
   public FireItem build() throws FireItemBuilderException {
      validate();
      return fireItem;
   }
   private void validate() throws FireItemBuilderException {
     // do all validations on the fire item itself and throw an exception if something fails
   }
}

Sure, we can improve the bubbling of the exception from validate() to build() and we could do with a better name for validate().  And perhaps, validate() should be on the FireItem class.  But let’s stick to factories and builders and fluent interfaces.  I think these three things work nicely “together”, when used for the right purpose.

In a nutshell, factories are great for creating objects where defaults and invariants are easily honored during the simple call to the factory.  However, if the structure of the object is more complex which makes long argument lists ugly, and some form of validation is necessary  before we can use an object then a builder works beautifully.

Also, note that the fluent interface was used to improve readability and kick off a tiny little DSL for describing insurance items.

An alternative is to allow the object to have an invalid structure but you track it with an invalid state, perhaps using a state pattern.  This is not exactly what the state pattern was meant for, but it will work nonetheless.

The last time I was with this team was in August 2006, and it is really great to work with them again.  So, much more for me to learn from them.