agile

Modularity and Agile Architecture

What is Agile Architecture?

Architecture is an important aspect of agile software development efforts. It is critical to scaling agile to meet the needs of the business. “Agile architecture is a set of values and practices that support the active evolution of the design of a system, concurrent with the implementation of new business functionality”. The goal of agile architecture is to eliminate the impact of change by crafting software that is easy to adapt. The structural aspect of agile architecture should be how flexible the architecture is or how easy is it to make changes.

Why is modularity important in agile development?

Modularity is a key ingredient of agile architecture. Change is a major part of agile development. As the Agile Manifesto states: “Welcome change requirements, even late in development agile processes harness change for the customer’s competitive advantage.” Modularity allows development teams to envision and manage change more easily because it separates a program into components that contain functionality that is independent and interchangeable. Many organizations that follow an agile process do so without considering the structure of their application. When business requirements change for a project, the team struggles to adapt. The flexibility of modularity combined with continuous integration allows for quick identification and resolution of any architectural issues or shifts in the code.

As an example, let’s say that an agile team is told that they need to use a library from Vendor X as part of their development. The project becomes tightly coupled to this library. If the structure of the application is not monitored and not modular, it’s hard to identify areas of the system that talk to this library. The business then tells you that Vendor X is out and you need to use the library from Vendor Y. How easy is it to remove Vendor X and replace it with Vendor Y? If all of the code that depended on the library from Vendor X was isolated in a single module, it would be pretty easy. To handle change, modularity is necessary. Since agile welcomes change, modularity is necessary for agile architecture.

Modularity is also important for Agile Parallel development. Agile Parallel development is when two components that have no dependencies on each other are able to be worked on at the same time instead of waiting on other teams to finish their components. This dramatically increases developer productivity. By removing the constraints (dependencies) with modularity, you empower teams to work in parallel. According to CA Technologies, Agile Parallel Development enables up to 90% more defects to be detected and up to a 50% reduction in a typical development schedule.

In large code bases, it becomes harder to manage the architecture at a code level to ensure modularity. Is it easier to understand the impact of change when examining a system of 10,000 classes or a system with 10 classes? Clearly the latter. A higher level visualization and analysis tool like Lattix Architect is needed to understand and manage the dependencies between components, which is critical to modularity and accommodating change. To get an idea of how modular your code is and/or how you can make it more modular, check out Lattix Architect.

Architecture Erosion in Agile Development

Software architecture erosion refers to the gap between the planned and actual architecture of a software system as observed in its implementation.1

Architecture erosion is a common and recurring problem faced by agile development teams. Unfortunately, the process of solving this problem is usually ad hoc or very manual, without adequate visibility at the architecture level. One effective solution is the reflexion model technique. The technique is a lightweight way of comparing high-level architecture models with the actual source code implementation while also specifying and checking architectural constraints.

The diagram below is an example of the reflexion model technique.

Agile Architectural Analysis

Architecture erosion can result in lower quality, increased complexity, and harder-to-maintain software. As these changes happen, it becomes more and more difficult to understand the originally planned software architecture. This is particularly important in an agile environment where, according to the Agile Manifesto, working software is valued over comprehensive documentation and responding to change is valued over following a plan. In reality, this means that the architecture is evolving as the software is evolving. Therefore, software changes need special attention (architectural assessment) from software architects. If this does not happen, the architecture could erode or become overly complex. Uncontrolled growth of a software system can lead to architectural issues that are difficult and expensive to fix.

How to avoid architecture erosion

Architecture erosion can be avoided or corrected by continuously monitoring and improving the software. Continuous checking of the implemented architecture against the intended architecture is a good strategy for detecting software erosion. Once architectural issues have been found, refactoring should be used to fix them. In an agile environment, you should combine development activities with lightweight continuous architectural improvement to avoid or reverse architecture erosion. The process of continuous architectural improvement can be broken down into four steps:

  1. Architecture assessment
    1. Identify architectural smells and design problems
    2. Create a list of identified architectural issues
  2. Prioritization
    1. Decide the order in which the architectural issues will be tackled starting with strategic design issues or high-importance requirements first
  3. Selection
    1. Choose the appropriate refactoring pattern to fix the issue. If none exist create your own.
  4. Test
    1. Make sure the behaviors of the system did not change
    2. Update the architecture assessment to make sure you fixed the design problems and did not introduce new issues. Watch the Lattix Update Feature video for more information on this step.

This is particularly useful in agile development. In a scrum environment, architecture refactoring should be integrated into sprints by adding time for refactoring both code and architecture. During the sprint, architects need to check their architecture, while testers and product owners should validate the system still meets requirements. Architecture refactoring should be done once during a sprint as opposed to code refactoring, which should be done daily. If it is done less often, fixing architectural issues involves more time and complexity as more code changes are added on top of design issues. If done more often, the architecture could change needlessly and add to software complexity. Architectural problems not solved in a current sprint should be saved and maintained in a backlog.

Summary

Architecture erosion can happen in any software project where the architectural assessments are not part of the development process. Architectural refactoring makes sure wrong or inappropriate decisions can be detected and eliminated early. One of the principles of agile development is "maintain simplicity." Focus on simplicity in both the software being developed and in the development process. Whenever possible, actively work to eliminate complexity from the system. A clean architecture eliminates complexity from the software while a lightweight, reflexion technique compliant tool like Lattix Architect makes the process of continuous architecture improvement simple.

1. Terra, R., M.T. Valente, K. Czarnecki, and R.S. Bigonha, "Recommending Refactorings to Reverse Software Architecture Erosion", 16th European Conference on Software Maintenance and Reengineering, 2012

A new way to think about software design

This year’s Saturn Conference at San Diego reflected an evolving landscape as macro trends such as cloud based architectures, Internet of Things (IoT), and devOps in an Agile world, continue to reshape the industry. How do we think about design and architecture in this changing landscape?

Professor Daniel Jackson of MIT, in a keynote at the Saturn Conference, gave us a fresh look on how to think about design. The idea is simple and elegant and one wonders why it took so long for somebody to come up with it. Simply put, Professor Jackson describes an application as a collection of coherent concepts that fulfill the purposes of the application. The beauty of this formulation is that it eliminates the clutter of implementation artifacts.


When we describe the design of a program in UML, we struggle to create structural and behavioral diagrams that accurately reflect program implementation. Sadly (and, perhaps, mercifully) we rarely succeed in this endeavor and even if we did, those diagrams would likely be just as hard to understand as the code (think of creating interaction diagrams to represent various method call chains). And if our implementation language happens to be a non-object oriented language then we are plain out of luck. On the other hand, this new kind of thinking has the potential to transcend implementation language and, perhaps, even technology. It also has ramifications on the architect vs developer debates that rage in the world of software engineering today.

Conceptual Design vs Representational Design: Reducing the clutter

Professor Jackson provided several examples of applications and the concepts they embody. For instance, an email application embodies concepts such as Email Address, Message and Folder while a word processor embodies concepts such as Paragraph, Format and Style. A considerable part of the presentation delved into the details that illustrated the sophistication that underlies these concepts and the confusion that befalls when these concepts are poorly defined.

So, how do we select concepts? Professor Jackson defines purposes that a concept fulfills. In a clean design, he said, a concept fulfills a single purpose. This has ramifications that I have yet to fully get my head around. It reminds me of the Single Responsibility Principle which is also a difficult concept to understand. In any case, I suspect that defining a coherent set of concepts is difficult and takes repeated iterations of implementations to get it right. In fact, the user of that software is likely to be a critical part of the process as concepts are pruned, split up or even eliminated to make them coherent and understandable.

And, how do we implement concepts? Does a concept map to a single class or multiple classes if implemented in an object oriented language? I will eagerly wait to see further work on this approach.

Go look up the slides of this thought provoking presentation here: Rethinking Software Design.

Just Enough Anticipation

How much "architecture" is good for agile development? How should you think about the future implications of design as you write code to meet immediate requirements? A recent article in CrossTalk, tackles this subject head on. The authors - Nanette Brown, Robert Nord and Ipek Ozkaya are from Software Engineering Institute (SEI) and well known for their prior contributions to the study of software architecture.

In their own words: Our mantra for Architectural Agility is “informed anticipation.” The architecture should not over-anticipate emergent needs, delaying delivery of user value and risking development of overly complex and unneeded architectural constructs. At the same time, it should not under-anticipate future needs, risking feature development in the absence of architectural guidance and support. Architectural Agility requires “just enough” anticipation.

According to them, tools such as dependency management, real options analysis and technical debt management can help you strike the right balance. Check out this thought provoking article: Enabling Agility Through Architecture.