My Stuff

2010 Conferences

OSGi DevCon @ JAX London

February 23 - Keynote titled OSGi in the Enterprise: Agility, Modularity, and Architecture’s Paradox

EclipseCon

March 22 - 25 - Tutorial on Modular Architecture

Über Conf

June 14 - 17 - Sessions titled Turtles and Architecture and Patterns of Modular Architecture

Catalyst

July 26 - 30 - Two sessions on rich mobile applications and one on agile development. Half day tutorial on software process improvement.

Tweets @ Twitter

re: #apple event "We sold more iPads than any PC manufacturer sold of their entire PC line." 2012-09-12

re: #Apple Event ""Our notebooks now rank #1 in the US in Market share in the last three months." 2012-09-12

Right on. I just won a Best Buy drawing worth $1000. Either that or I won a shiny new virus by clicking the link. Hmm...what to do. 2012-08-29

The #osgi alliance response (http://t.co/KrN8XNWg) to the @mreinhold #jigsaw announcement (http://t.co/9YvcDdqC). 2012-08-29

Good Q&A with @mreinhold on project #jigsaw. http://t.co/9YvcDdqC. Modularity will change the way we design and run apps! 2012-08-28

LinkedIn Profile

The opinions expressed on this site are my own, and not necessarily those of my employer.

Granularity: Architecture’s Nemesis

Filed Under Architecture & Design, Development, OSGi |  

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. This is pretty natural. If it does less, then it’s more likely to apply across a wider variety of usage scenarios. I spent some time discussing this tension in Reuse: Is the Dream Dead?

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.

A Really Simple Example

Consider the following save method:

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
   }
}

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.

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.

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.

Yet another alternative might be the following:

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.
      }
   }
}

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.

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. 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?”

Bring It Up a Level

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. I discussed another, much higher level example, in the post on architecture all the way down. So what I really want to know is, “How do I determine the appropriate level of granularity?

This is the million dollar question. Because granularity is a significant inhibitor to creating reusable software that’s easy to use. (Oh, and managing dependencies too.) If something does too much, it’s less reusable. If something does too little, it’s more difficult to reuse.

In the past, I’ve used the diagram at right (click to enlarge) to help illustrate one view of granularity. As can be seen, 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?”

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.

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.

Another Dimension

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 at right illustrates this (click to enlarge). As we can see, as we move down the layered hierarchy, entities become finer grained.

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.

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.

The Complete Picture

At this point we can make the following general statements:

  • Entities in higher level layers are more coarse-grained than entities in lower level layers.
  • Services are coarser than modules which are coarser than packages which are coarser than classes.

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.

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.

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.

Comments

7 Responses to “Granularity: Architecture’s Nemesis”

  1. Tim on April 23rd, 2010 4:16 pm

    I like your analysis. However, I think that the scope is perhaps too narrow for many organisations. Reuse is hard, even if patterns (of whatever type) are where the reuse is captured (as opposed to code). It’s often much harder to find a component to re-use than it is to build a new one.

    There’s another issue, too - most of the deployed software isn’t even going to be based on the same programming language. Even if it is based on the same language, there are likely to be different technical architectures that, in practice, pervade the different layers of the abstraction diagram. These differences typically arise from either differing non-functional requirements or differing original technologies.

    I think that there are also some complications arising from the lifespan of components (how are version upgrades rolled out in a testable, safe manner) and the distinction between compile/link dependency on classes and runtime artifacts.

    Nice to find someone else looking at these issues ;-)

  2. Anonymous on April 25th, 2010 2:27 pm

    Good article. One minor correction, where you say, “If something does too much, it’s less reusable. If something does too little, it’s more difficult to reuse.” I think you meant to say, “If something does too little, it’s more difficult to _use_.” Or, it’s easier to unintentionally abuse.

  3. Gergely on October 10th, 2011 1:14 pm

    Very good description of the problem. I would like see more about how to address this in a larger systems.
    I would like to mention that there are even more dimension (aspect) to consider which are presented nicely on the p33 in this old but good article: http://www.makeitfly.co.uk/Presentations/suntoneam_wp_5.24.pdf.

  4. TupNuaft on November 2nd, 2012 6:34 am

    buy a http://www.birkin-bag-hermes.org/ - hermes bags birkin with confident

  5. Granularity on May 31st, 2013 4:07 pm

    Hi,
    i like the article and it might fit to the following research paper:
    Weber, M.; Wondrak, C. (2012)
    Measuring the Influence of Project Characteristics on Optimal Software Project Granularity
    In: Proceedings of the 20th European Conference on Information Systems (ECIS)

    Currently, we are working on a web-based service to make the tools from the project available for software architects. You can find a preview/demo here: http://www.granu.com/

    Regards,
    Moritz

  6. cheap ray ban wayfarer 2140 on November 28th, 2013 7:35 am

    9999 The show results you have undertaken has gotten you this far. These station duplicate handbags are often the clone for that reliable spectacular channel totes.
    cheap ray ban wayfarer 2140 http://eliteinsidetrader.com/cheap-ray-ban-wayfarer-c-9.html

  7. louis vuitton belts sale on November 28th, 2013 7:35 am

    9999 The small-scale specifics, like as fabric bows or embroidery make it possible for them to give a certain measure of panache to the most regular all outfit. We were like “ok, you can marry Harry!” Could perhaps she someday be Prince Harry’sthen? “Nah! No!”.
    louis vuitton belts sale http://www.aquarius-solutions.net/louis-vuitton-belts-sale-c-11.html

Leave a Reply