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.

Modularity Patterns

Filed Under Architecture & Design, Development, Java, OSGi |  

In The Two Faces of Modularity & OSGi, I talked about the OSGi runtime and development models. The development model has two facets - a programming model and design paradigm - that impact how organizations will use OSGi to build more modular applications.

In Reuse: Is the Dream Dead, I talked about the failed promise of reuse. In stating that maximizing reuse minimizes use, I examined significant impediments to reuse and use - component dependencies and context dependencies.

Here, I talk about the benefits of modularity, focusing exclusively on the OSGi design paradigm. I review modularity’s relationship to reuse and touch on how modularity helps ease maintenance and improve extensibility. To wrap up, I present some modularity patterns that help balance module weight and granularity and make modules more reusable and useable, while also making the system easier to understand, maintain, and extend.

Logical and Physical Design

Almost all principles and patterns that aid in software design and architecture address logical design. Identifying the methods of a class, relationships between classes, and a system package structure are all examples of logical design. Since most principles and patterns emphasize logical design, it’s no surprise that the majority of developers spend their time dealing ony with logical design issues. Other examples of logical design include deciding if a class should be a Singleton, determining if an operation should be abstract, or deciding if you should inherit from a class versus contain it. Developers live in the code, and are constantly dealing with logical design issues.

Making good use of object oriented design principles and patterns is important. Accommodating the complex behaviors required by most business applications is a challenging task, and failing to create a flexible class structure can have a negative impact on future growth and extensibility. But logical design is just one piece of the software design and architecture puzzle. The other piece of the puzzle is physical design. Physical design represents the deployable units composing a software system. Physical design is equally important as logical design, and physical design is all about modularity.

Benefits of Modularity

Almost all discussions on modularity mention reuse as a prime advantage. But there are other advantages, of course. There is a reduction in complexity that helps ease the maintenance effort. Cohesive modules encapsulate behavior and expose it only through well-defined interfaces. Because modules are cohesive, change is isolated to the implementation details of a module. Because behavior is exposed through interfaces, new modules containing alternative implementations can be developed without modifying existing modules. There are other benefits to modularity that extend beyond design to runtime, too. But from the design perspective, modularity helps increase reuse, ease maintenance, and increase extensibility.

Modular Tension

Time for an example. Assume we define an interface to decouple client classes from all classes implementing the interface. In doing this, it’s easy to create new implementations of the interface without impacting other areas of the system. The principle surrounding this idea is the Open Closed Principle - systems should be open for extension but closed to modification. Logical design makes extending the system easier, but it’s also only half of the equation. The other half is how we choose to modularize the system.

Let’s assume the interface we’ve created has three different implementations, and that each of the implementation classes have underlying dependencies on other classes. We’re faced with a contentious issue. On one hand, grouping all the classes into a single module guarantees that change is isolated to only that module (ie. easier to use and maintain). If anything changes, we’ll only have one module to worry about. Yet, this decision results in a coarse-grained and heavyweight module (ie. harder to reuse), and a desire to reuse a subset of that module’s behavior leaves us with one of two choices. Duplicate code or refactor the module into multiple lighterweight and finer-grained modules. In general, logical design impacts extensibility, while physical design impacts reusability and useability. Well…this is only partially true.

As we refactor a coarse-grained and heavyweight module to something finer-grained and lighter weight, we’re faced with a set of tradeoffs. In addition to increased reusability, our understanding of the system architecture increases! We have the ability to visualize subsytems and identify the impact of change at a higher level of abstraction beyond just classes.  In the example, grouping all classes into a single module may isolate change to only a single module, but understanding the impact of change is more difficult. With modules, we not only can assess the impact of change among classes, but modules, as well.

Unfortunately, if modules become too lightweight and fine-grained we’re faced with the dilemma of an explosion in module and context dependencies. Modules depend on other modules and require extensive configuration to deal with context dependencies! Overall, as the number of dependencies increase, modules become more complex and difficult to use, leading us to the corollary we presented in Reuse: Is the Dream Dead:

Maximizing reuse complicates use.

Creating lighter weight and finer-grained modules increases reuse but also increases module and context dependencies, while creating fatter modules decreases dependencies but also decreases reuse. Modules that are too lightweight provide minimal value and may require other modules to be useful. Modules that are too heavyweight are difficult to reuse because they do more than what the client needs. Of course, there are other challenges beyond reuse.

Coarse-grained and heavyweight modules may do a good job of encapsulating change to a single module, but understanding the impact of change is more difficult. Conversely, fine-grained and lightweight modules make it easier to understand the impact of change, but even a small change can ripple across many modules. How do we deal with this problem, especially for large software systems where these challenges are even more pronounced?

Modular Design

Large software systems are inherently more complex to develop and maintain than smaller systems. In addition to increasing reuse, breaking a large system into modules, makes the system easier to understand. By understanding the behaviors contained within a module, and the dependencies that exist between modules, it’s easier to identify and assess the ramification of change.

For instance, software modules with few incoming dependencies are easier to change than software modules with many incoming dependencies.  Likewise, software modules with few outgoing dependencies are much easier to reuse than software modules with many outgoing dependencies. This tension surrounding module weight and granularity is an important factor to consider when designing software modules.

Today, frameworks like OSGi aid in designing modular software systems. While these frameworks can enforce runtime modularity, they cannot guarantee that we’ve modularized the system correctly. Correct modularization of any software system is contextual and temporal. It depends on the project, and the natural shifts that occur throughout the project impact moduarlity. I examine our willingness to embrace this idea when discussing Agile Architecture.

Modularity Patterns

Modularity patterns provide guidance and wisdom in helping design modular software. They explain ways that we can minimize dependencies while maximizing reuse potential. They help balance module weight and granularity to make a system easier to understand, maintain, and extend. For those who have attempted to design modular software, it’s common for modularity to drive the logical design decisions, which I briefly explained when discussing the SOLID design principles.

Below are a list of modularity patterns that I’ve used on past projects. These patterns also build atop proven object-oriented design concepts. Right now, the list only includes the pattern descriptions, and provides no detailed explanation. Hopefully, you can infer from the name and brief description the general intent of the pattern. Some may be intuitively obvious, while others less so. In the meantime, I welcome your feedback, your questions, and your criticisms, as I work to provide more detail going forward.

Base Patterns

  • ManageRelationships – Design Module Relationships.
  • ModuleReuse – Emphasize reusability at the module level
  • CohesiveModules – Create cohesive modules.
  • ClassReuse - Classes not reused together belong in separate components.

Dependency Patterns

  • AcyclicRelationships - Module relationships must be acyclic.
  • LevelizeModules – Module relationships should be levelized
  • PhysicalLayers - Module relationships should not violate the conceptual layers.
  • ContainerIndependence - Consider your modules container dependencies.
  • IndependentDeployment - Modules should be independently deployable units.
  • CollocateExceptions - Exceptions should be close to the classes that throw them.

Usability Patterns

  • PublishedInterface - Make a modules published interface well known.
  • ExternalConfiguration – Modules should be externally configurable.
  • ModuleFacade – Create a facade serving as a coarse-grained entry point to the modules underlying implementation.

Extensibility Patterns

  • StableModules - Modules heavily depended upon should be stable.
  • AbstractModules - Depend upon the abstract elements of a module.
  • ImplementationFactory - Use factories to create a modules implementation classes.
  • SeparateAbstractions - Separate abstractions from the classes that realize them.

Utility Patterns

  • LevelizedBuild – Execute the build in accordance with module levelization
  • TestComponent – For each module, create a corresponding test component that validates it’s behavior and illustrates it’s usage.

Comments

21 Responses to “Modularity Patterns”

  1. Dew Drop – August 6, 2009 | Alvin Ashcraft's Morning Dew on August 6th, 2009 12:33 pm

    [...] Modularity Patterns (Kirk Knoernschild) [...]

  2. Robert Rawlins on August 10th, 2009 5:39 pm

    Hey, excellent article, I’m really very keen on this approach to development, it’s something I always find very challenging but very rewarding when you pull it off.

    I’ve really learned the value of this recently when writing a few modules that I’ve literately dropped right into other projects and they work off the bat. I think you kind of hit the nail on the head when you said it’s about finding a balance, sometimes I find myself trying to modularize quite niche use cases that are not likely to be reused in any other project when really keeping the implementation coupled wouldn’t be such a bad thing, it’s just a judgement call I guess.

    Thanks for the interesting read, really appreciate it.

    Rob

  3. links for 2009-08-11 « Xume linklog on August 11th, 2009 1:02 pm

    [...] Modularity Patterns : Software & Technology @kirkk.com (tags: architecture modularity patterns osgi) [...]

  4. Modularity by Example : Software & Technology @kirkk.com on August 13th, 2009 3:24 pm

    [...] are lots of benefits to modularity, some of which I discussed when introducing modularity patterns. But here’s a simple example, which serves as a prelude to some upcoming posts explaining a [...]

  5. Modularity Pattern - Manage Relationships : Software & Technology @kirkk.com on September 2nd, 2009 3:31 pm

    [...] I posted an entry introducing 19 patterns for modularity. The first of these patterns was ManageRelationships. ManageRelationships is a simple pattern [...]

  6. Agile Architecture Presentation : Software & Technology @kirkk.com on September 11th, 2009 6:02 pm

    [...] Modularity Patterns - Presents 19 modularity patterns that help ease the tension between reuse and use while making a software system easier to understand, maintain, and extend. [...]

  7. The Use/Reuse Paradox : Software & Technology @kirkk.com on October 7th, 2009 5:05 pm

    [...] principles, patterns and practices (like SOLID and modularity patterns) that increase architectural agility help resolve the tension between use and reuse, and are [...]

  8. Agile Architecture Presentation : Software & Technology @kirkk.com on November 5th, 2009 7:04 pm

    [...] for providing such positive feedback. I’ve also uploaded the code samples used to show the modularity pattern examples found toward the end of the presentation. The code can be found under the billpayevolution [...]

  9. OSGi Adoption Increasing? : Software & Technology @kirkk.com on November 10th, 2009 7:31 pm

    [...] only a fraction of overall Java jobs, it’s refreshing to see that folks recognize the benefits of modularity (here’s an example). I can only expect that this graph will continue to trend upward over the [...]

  10. OSGi: The Value Proposition? « Paremus Blogs on November 14th, 2009 3:32 pm

    [...] just how difficult such concepts can be. Before attempting to phrase my response, I visited Kirk Knoernschild’s blog - IMO one of the industries leading experts in modularisation - to see what he had to say on the [...]

  11. Applied Modularity - Part 1 : Software & Technology @kirkk.com on November 16th, 2009 6:06 pm

    [...] the same tools and techniques that we can leverage in the enterprise right now. This is where the modularity patterns, as well as a few other tools, will [...]

  12. OSGi: The Value Proposition? « Adapt and Evolve on November 18th, 2009 2:14 pm

    [...] attempting to phrase my response, I visited Kirk Knoernschild’s blog – IMO one of the industries leading experts in modularisation – to see what he had to [...]

  13. OSGi: The Value Proposition? « Paremus Blogs on November 18th, 2009 3:04 pm

    [...] attempting to phrase my response, I visited Kirk Knoernschild’s blog – IMO one of the industries leading experts in modularisation – to see what he had to [...]

  14. Applied Modularity - Part 2 : Software & Technology @kirkk.com on November 19th, 2009 5:10 pm

    [...] of our application a step further. We’re going to apply two refactorings using two different modularity patterns - AbstractModules and AcyclicRelationships. First, we’re going to separate the bill and audit functionality out into separate modules so [...]

  15. OSGi & Maven & Eclipse « The Art of Software Development on November 21st, 2009 10:30 am

    [...] in a large software development effort in Java, then OSGi seems like a natural fit to keep things modular and thus maintainable. But every advantage can also be seen as a disadvantage: using OSGi you will [...]

  16. Applied Modularity - Part 3 : Software & Technology @kirkk.com on November 23rd, 2009 8:02 pm

    [...] each layer out into separate modules. In Part 2, we applied two refactorings using two different modularity patterns - AbstractModules and AcyclicRelationships. But we were still left with a problem, which we’ll solve [...]

  17. Chapter 7 – Reference Implementation : Modular Architecture on December 21st, 2009 7:27 pm

    [...] the same tools and techniques that we can leverage in the enterprise right now. This is where the modularity patterns, as well as a few other tools, will [...]

  18. OSGi: Complexity is NOT the Problem : Software & Technology @kirkk.com on April 15th, 2010 6:40 pm

    [...] OSGi to design modular applications will require us to learn new concepts, tools, and design paradigms, but there is no doubt that [...]

  19. Mike Nash’s Two Cents Worth » Blog Archive » Why Modularity? on April 26th, 2010 2:06 pm

    [...] Reading: Agile Architecture Requires Modularity Modularity Patterns Runtime and Development time [...]

  20. roberto marchiori on September 29th, 2010 11:27 am

    Congrats for this catalog of modular patterns. I was looking for something like this for a while.

  21. OO: Responsabilidades, Modelagem e Dependências « Mente de Iniciante on December 21st, 2012 12:23 pm

    [...] facilita a manutenção, isola dependências e, se bem projetados, habilita o reuso. Alguns Padrões de Modularização foram documentados e estão altamente relacionados com Orientação por Objetos. About these ads [...]

Leave a Reply