DevOps Zone is brought to you in partnership with:

Programmer, solution architect, user group and conference organizer, conference speaker and traveling fun code evangelist. Johannes tries to apply Agile principles to large software projects, but what he's really passionate about is sharing the experience of more fun programming with other coders around the world. Johannes is a DZone MVB and is not an employee of DZone and has posted 37 posts at DZone. You can read more from them at their website. View Full User Profile

Humble Architects

  • submit to reddit

Humility is not a very common trait with software architects. After having worked with a few awful architects and recently with a very pleasant one, I’ve compiled a few of my experiences in the way every architect loves: As a set of rules.

Rule 0: Don’t assume stupidity

It seems like some architects assume that developers, if left to their own devices, would behave like monkeys. In my experience, this is very rarely the case. The only situations where I’ve seen developers do something stupid is when silently protesting against an architect. If you follow this rule, the rest are details.

Rule 1: You may be wrong

When reviewing someone’s design idea, I prefer to try and ask questions that are honestly open. Maybe I think the developer have overlooked a critical fact, for example concurrency. There are a few different approaches to the situation:

  1. Architect: “You can’t do it that way, because it breaks the code guidelines”
  2. Architect: “You can’t do it that way, because it won’t be safe when there are several users”
  3. Architect: “Have you thought of how it will work with several users?”
  4. Architect: “How does your solution address the situation of several users?”

Dear architect: Please rate these approaches from the one least to the one most likely to get a best possible system. (Tip: This is an easy task, even though many architects fail it routinely)

Rule 2: Be careful with technology

Every technology comes with a cost. Many technologies come with an infinitesimal benefit.

Here’s a list of technologies that I’ve experienced as having consistently higher cost than benefits, and thus will never use (if you don’t know them, don’t worry. The point is the number): JavaServer Pages, Java Server Faces, JAX-WS, Hibernate, Spring, EJB, Oracle SOA Server, IBM WebSphere, Wicket, Google Web Toolkit, Adobe Flex, JBoss jBPM, JMS (all implementations), JBoss.

Here’s a list of technologies that I happily use: JUnit, Jetty, Joda-time, Java Standard Edition.

Here’s a humble exchange that you may want to try and copy:

  • Architect: You should use technology X
  • Me: I’ve looked at technology X, and I don’t see how it will help me solve the business problem
  • Architect: What do you mean?
  • Me: Well, this is what we need to do: ….. And this is what technology X assumes: …. I don’t see how they match.
  • Architect: So what do you suggest using instead?
  • Me: Um… I think we can solve this with plain Java. As a matter of fact, I made a pretty good proof-of-concept yesterday evening.
  • Awesome architect: Cool. Let’s use it.

Rule 3: Consistency isn’t as important as you think

If I’d have a penny for every time I’d hear this….

  • Architect: “Yes, I know this way may seem clumsy, but you have to do it. You see, if you don’t, the system becomes inconsistent and impossible to maintain”

Granted, I don’t often work with maintenance, but I know that when I deal with any system, the most difficult part is understanding the business logic for that system. Whether system X (which has one set of business logic) and system Y (which has another) are consistent is very low on the list of things that make me lose sleep.

The fact that system X is horribly complex because it has a dozen layer to be consistent with system Y – now this is something that does make me want to pull out my hair. Different contexts have different trade-offs.

Oh, yes: Remember Rule 0? Assume that the developers in a given context are trying to create a good solution for that context.

Oh, yes, another thing: I’ve never seen something that was incomprehensibly complex in the small become maintainable just because we grew to become big.

Oh, yes, yet another thing: If a programmer really runs screaming away from the code because some of it had one style of curly braces and some had curly braces in another style, I’m going to lose all faith in humanity.

Rule 4: Bottom-up consistency beats top-down consistency

There is one way I’ve been able to create more consistency inside a system:

  • Create a reference application with an architecture that is easier to follow than to break. If you do this well, the developers will shake their head at the very idea of deviating from the architecture. Unless they really need to. In which case it’s okay.
  • Foster a culture of cross-pollination: Developers who see each other’s code have more consistent code than developers who just see their own code. Pair programming, code reviews and tech sharing sessions all foster cross-pollination.

Rule 5: Tactical reuse in across systems is suboptimization

Reuse creates coupling. If system X and system Y reuse some functionality and system X needs that functionality to be modified, this will affect system Y. At the very least, the team working on system X must decide to make a private fork of the reused functionality, which means that it’s no longer really reused. At worst, system Y will get a bug because of a change in the reused functionality.

When you reuse across systems, what you reuse should either be stable (say: the Java SE platform, or something so stable that you definitely didn’t make it yourself) or strategic. By strategic reuse, I mean services that integrate information and not just duplicate functionality.

In other words: Reuse should either be use or integration. Duplication is your friend.

Rule 6: Separate between rules and dogma

There are three reasons to have a rule in any coding standard:

  • Unsafe: The code has a bug that will manifest under some (non-theoretical) circumstance
  • Incomprehensible: “I” don’t understand what’s going on
  • Heresy: The code is written in a style some person doesn’t like

Pop quiz: If you have a rule that says “all fields must have a JavaDoc comment”, is that a safety issue, a comprehensibility issue or a heresy issue? What if the standard uses this example:

 *  Contains the name value of the object
private String name;

What about the rule that says “no newline before an opening curly brace”? What about the rule: “the style used for curly braces should be consistent”? Is it addressing Unsafe code, Incomprehensible code or Heresy?

We should be more concerned with writing appropriate code for the situation and less concerned with appeasing the Gods of Consistency.

Rule Omega: Be humble

In the years I’ve worked with software development, I’ve seen more harm done by software architects than help. As a professional role, I think we’d save money if we got rid of them (us). Even if we still paid their salaries.

When you’re in a profession that causes more harm than they prevent, you have two options: You can try and improve, or you can pray that nobody notices.

Published at DZone with permission of Johannes Brodwall, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)


Nicolas Frankel replied on Mon, 2013/12/02 - 3:03am

Thanks for this good piece of humor! I know that architect-bashing is popular nowadays, but this "article" is at the top of my list...

At least you have the decency to be truthful:

Granted, I don’t often work with maintenance

So perhaps requirements apply to people that don't apply to you? If you're concerned with developing an application, please consider that others may have other concerns (maintainance, using existing skillset, integrating within the existing information system, and so on)

Oh yes, one last thing, I assume you are a developer who display the same humility that you expect from others, since you are the proven expert of which technologies are worth and which are not.

May you live in interesting times!

Daniel Kec replied on Mon, 2013/12/02 - 7:06am

Awesome architect: Let's build everything on Java SE and Jetty

Exhausted developer: :-/

Christophe Blin replied on Mon, 2013/12/02 - 2:31pm

Globally, the rules are OK but you are sometimes a bit extremist (do you really build a usefull webapp on j2se+jetty I doubt it) !

Johannes Brodwall replied on Mon, 2013/12/02 - 5:03pm in response to: Christophe Blin

Oh, I've built good web applications on J2SE + Jetty. I wouldn't object majorly to throwing in a bit of Spring-MVC (as long as I can keep away from the XML madness) and Hibernate. But in general, I've found that most of the J2EE stack costs so much more in debugging effort than it ever saves in development effort...

In my last application, I could run the whole system within a JUnit (integration) test, I could perform most changes while running the debugger in Eclipse (or IDEA), I could restart the application on 5 seconds and I could deploy and restart a new version in about 30.

These things are hard to do with an app server, but trivial without it. E.g. JBoss is a faustian bargain.

Johannes Brodwall replied on Mon, 2013/12/02 - 5:08pm in response to: Nicolas Frankel

It sounds like your experience is different than mine, Nicolas. Are you saying that to you, the main time consumption when you come into a new system that you maintain is whether they used the "correct" framework and whether they put the curlies on the correct line, rather than understanding the business logic or the bulk of the system?

Oleksandr Alesinskyy replied on Thu, 2013/12/05 - 11:26am in response to: Nicolas Frankel

It is even just a piece of humor - it is a piece of black humor :(

Some statements are so weird that I hardly may believe my eyes.

  1. Spring (if we speak about its "classical" DI, AOP and data access/transaction management parts) is a huge time saver. Yes, there are parts that you do not want to use - but nobody force you to use them.
  2. " If a programmer really runs screaming away from the code because some of it had one style of curly braces and some had curly braces in another style, I’m going to lose all faith in humanity." - consider your faith lost, I have seen quite a lot such cases. BTW, consistency makes an adoption of cross-pollination much easier. If each developer works on its own piece of code that consistency is not so important. But consider a piece of code migrating between several developers. How it would like if each of them prefer his own style? Or how you would track changes if each next developer will reformat it up to his liking?
  3. "Reuse creates coupling" - yes, if done stupidly. If you ever need an incompatible change in the reused code you may develop your own - but why not reuse till it satisfies your needs?
  4. "What about the rule: “the style used for curly braces should be consistent”?"" - see point 2 above.
  5. "Please rate these approaches from the one least to the one most likely to get a best possible system" - it depends on the team with which the architect works.

Johannes Brodwall replied on Fri, 2013/12/06 - 4:47am in response to: Oleksandr Alesinskyy

I was one of the earliest adopter of Spring in Norway. We developed a large system where we eventually had to start thinking about things like different mechanisms for reuse of XML configuration. Eventually, this evolved into the @Autowire and component-scan which removed the ability to reason about the whole source code - instead isolating developers in a very small island in the application.

The applications tended to blossom in complexity as either the culture, the tool, the documentation or something else made developers build unnecessary layer upon unnecessary layer.

Later, I tried to build applications without a Dependency Injection framework, but taking with me the lessons about when to use "new", when to have a setter or a constructor argument and which types were good to use as dependencies and which created coupling to infrastructure.

So I found that some of the instincts that the DI container had given me made me improve the design, but at the same time, I found that when I removed the container, the solution became smaller (which is good!), easier to navigate and understand and easier to test.

This leaves me with a dilemma. I found that the cost of using the container is very high - it creates a force towards increasing complexity and size and reduced coherence. But at the same time, it taught me some good design skills as well.

In the end, creating a coherent, small system is to me of much higher value than to create one that is decoupled just of the case of decoupling. Coherence and decoupling are opposing forces and I side with coherence.

At the same time, I found that the culture around dependency injection has a very strong preference for reuse. But reuse does introduce coupling. If module A reuses module B, module A and B are coupled. A change in B might affect A for better (a bug fix) or worse (an introduced bug). If the savings from the reuse are high, this is a trade-off worth making. If the savings are low - it is not.

So reuse and decoupling are opposing forces. I find myself siding with decoupling.

When there is a conflict, I value Coherence over decoupling and decoupling over reuse. The culture where Spring is in use seems to have opposite values.

Jakub Holý replied on Sat, 2013/12/07 - 7:28am

 Johannes is a very experienced and respected architect and developer. It is a pitty that some readers focus on their interpretation of a small parts of his post without trying to understand.

Regarding frameworks: I, as a developer, love frameworks. The trouble is that they are great when they work and thus simplify my job - but I then often pay a terrible price when they stop working or when I have to go beyond that what is simple (and I eventually have to). They also often do more than I need and thus are more complex than I need, invite me to create more complexity ("wow, this feature looks nice, let's try it!"), and as a framework is layered upon framework, it becomes unmanageable. Therefore I very much understand the call for simplicity by Johannes and others, even though I hate writing code that I could reuse from elsewhere (yet I hate debugging and configuration issues even more).

I guess we can agree that dependency injection is often a good thing, enabling testing and such. But frameworks such as Spring IoC that do the injection "magically" create new categories of problems. As with other frameworks - it's great when it works but pain when it breaks. And the fact that it is hard to see how the system actually fits together at runtime, the additional complexity it invites, and the dreadful debugging when the wrong dependencies are injected at runtime or when you want different dependencies during testing make the cost of such frameworks non-negligible. I have experienced that quite recently.

I do not believe that Johannes says "never reuse" and "always use just plain J2SE". He does point to the too often ignored cost of these - generally positively regarded - things like reuse and frameworks. So do not take his statements absolutely. We always need to seek balance. Open your eyes and start looking for the hidden cost of reuse, complexity, convention-over-context. Hopefully this journey will lead us to better software if we walk it with an open mind, willing to learn and question rather than to defend our holy cows. I.e. with humbleness. (And yes, I too am not all-knowing and am never completely right, which I humbly admit.)

PS: I would like to thank the architect who has forbidden me from using a XML-POJO biding framework and made me code it manually in my early career at IBM. It was unexpectedly simple and certainly an order of magnitude less complex. I still carry the lesson with me.

Johannes Brodwall replied on Sat, 2013/12/07 - 11:29am in response to: Jakub Holý

Thank you for the nice comments and your insights, Jakub.

To be sure - my point was for the architect to avoid pushing technological choices and especially heavy technology onto developers. I have a personal bias towards a very simple technology stack (in Java), but that's beside the point.

Dean Schulze replied on Mon, 2013/12/09 - 12:13pm

Please take a look at Java EE (>= version 6) for the solution to your frustrations with Spring and J2EE.  I particularly recommend Adam Bien's book to understand how Java EE solves the architectural madness of J2EE.

Johannes Brodwall replied on Mon, 2013/12/09 - 12:33pm in response to: Dean Schulze

Java EE 6 fixed many problems with J2EE to be sure. But by the time it came out, I had learned to get by without it (and to love getting by without it).

If we ever happened to work together, though, I'd love to have you change my mind. ;-)

Christophe Blin replied on Mon, 2013/12/09 - 3:35pm in response to: Johannes Brodwall

You picked out my curiosity so I tried to write a full J2EE webapp without anything else than jetty.

Effectively, except the db access that is really painfull with plain JDBC (so I used jooq that is a self contained library) and the JSON serialisation (so I used GSON that is also self contained), it is fairly easy to build a json webservices !

I highly expect java 8 to simplify it further ! 

I'll try to put that on a gist or whatever asap.

Vic Cekvenich replied on Mon, 2013/12/09 - 11:16pm

After being one (an architect ) and VPE, I consider architect title/role an insult the the person labeled as one. In general, they can't code. 

Just have a lead on your team period.

Also you are explaining something else, here is the science:

good luck.


Lund Wolfe replied on Thu, 2014/01/09 - 2:37am

Love your article.  I'm a month late but I can't resist commenting.  The title is tongue in cheek.  If you don't really know what you're doing, be more humble.  Unfortunately, we usually get the opposite.

"A foolish consistency is the hobgoblin of small minds."  Don't add complexity and reuse for its own sake.  Different apps should look different (have different designs).  The solution should suit/fit the problem.  A "simple" solution requires that the problem be well understood, however.

I love your unapproved technologies list, though I like JAX-WS when it serves a purpose and it isn't overkill for the job at hand.  I can name that tune in two notes (JSE + one library or one framework).  Real developers are a rare breed.  Don't expect much company.

Johannes Brodwall replied on Thu, 2014/01/09 - 4:20pm in response to: Lund Wolfe

Thank you for the kind comment, Lund.

The important part about technologies is that architects often dictate technologies without having compared the technologies with alternatives through actual use. Or indeed even used the technology at all. It sounds like you've made a thoughtful consideration about JAX-WS and reached a different conclusion than me. As you point out, the goal in my article is to focus on the "thoughtful" part.

Lund Wolfe replied on Sat, 2014/01/18 - 8:22pm

Hopefully, the "architect", regardless of title, is hands on enough to build the architectural prototype/proof of concept to see if it basically works as expected.

I know what you mean about JAX-WS.  Even more than other tools, it can be and usually is done very badly, which makes it look very bad and leads to a very frustrating experience.  I recently had to connect to a webservice that was autogenerated from ColdFusion.  The WSDL was completely invalid, useless garbage (to a human and client code generation tools).  I just connected to it with my own soap XML from httpclient.  CXF is an excellent webservices framework, but I've worked on in-house webservices in CXF that were nonsensically complex.  Developers can make it look really bad.  Never ever use this technology again kind of thing.  Try not to judge webservices by what you've seen done by others in the real world.  If it is hard or hard to use, you aren't doing it right.

IMO the Java SOA Cookbook is an excellent and thorough book on building and using webservices.  I left a glowing review myself on Amazon.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.