I recently read the very interesting Ph.D. thesis of Michael Waterman on the topic of Agile Software Architecture. Michael investigated how professional software engineers in the industry are applying Agile principles to software architecture and design. His conclusions are that there are five main strategies:
- Respond to Change
- Address Risk
- Emergent Architecture
- Big Design Up-Front
- Use Frameworks and Template Architectures
These are Michael’s definitions for these five strategies:
“Responding to change is a strategy in which a team designs an evolving architecture that is modifiable and is tolerant of change.”
“Addressing risk is a strategy in which the team does sufficient architecture design to reduce technical risk to a satisfactory level.”
“An emergent architecture is an architecture in which the team makes only the bare minimum architecture decisions up-front, such as selecting the technology stack and the high-level architectural patterns. In some instances these decisions will be implicit or will have already been made, in which case the architecture is totally emergent.”
“The big design up-front requires that the team acquires a full set of requirements and completes a full architecture design before development starts.”
“Using frameworks and template architectures is a strategy in which teams use standard architectures such as those found in development frameworks, template or reference architectures, and off-the-shelf libraries and plug-ins. Standard architectures reduce the team’s architecture design and rework effort, at the expense of additional constraints applied to the system.”
In his thesis Michael provides many details about each one of the strategies above. Reading his work provided me some very interesting insights. The most important of them I would like to present and discuss below.
Emergent Design vs. Framework-Based Design
I personally do not believe in Emergent Design, and thus I have always been surprised to see so many people saying that they were very successfully doing Emergent Design. But after reading Michael’s thesis, I understood that most people who claim they are doing Emergent Design in practice are doing Framework-Based design.
Today there are many categories of software systems for which there are very sophisticated and rich frameworks that already implement most of the hard work. For example, most people building Web sites do not need to understand anything about the underlying communication protocols; they just need to define the site structure, its content and some simple business logic. As a consequence, we all have heard stories about some very nice sites that were built in a few days by people with no degree on Computer Sciences or Software Engineering.
The same is true about applications for smartphones. There are frameworks that make the task of creating a new app extremely simple, to the point that the developers may completely ignore the underlying operating system and use the same code for Android or iPhone apps. There is no need for much development experience or sophisticated programming skills, and as a consequence there are teenagers creating apps and games that are used by millions of people worldwide.
This same reality applies to many domains: Software developers are not doing much design, but the reason is not that design became an obsolete activity. The reason is that developers are adopting ready-made designs; they are following design decisions that were already made by someone else and thus they don’t need to make their own decisions. They are not conceiving neither implementing their own architecture, they are basically “filling holes” with small pieces of relatively simple business logic.
Programming in the Large and Programming in the Small
The distinction between “programming in the large” and “programming in the small” was coined in the 70’s. At that time, it represented the difference between developing software systems and implementing simple programs. The term “programming in the small” characterized tasks that could be done by a single programmer. But at that time there were not sophisticated application frameworks that could be extended.
Today it is important to take in consideration the ratio between “new code” and “reused code”. It is a characteristic of modern software systems that this ratio is relatively small, meaning that most of the code is being reused from existing frameworks, platforms and libraries. In this case, it is possible to create complex systems with small amounts of new code. This is sometimes called “glue code” because it just connects existing components.
For example, Apache is the most popular HTTP server, with a 60% market share, and its implementation has more than 1.7 million lines of code. In contrast, the average Web page has only 295 kB of scripts. Assuming that each line of script has in average 30 characters, this means that the average page has 10,000 lines of scripts. Of course a Web site has multiple pages, and there is also code running on the server side. But on the other hand most sites also use other platforms such as MySQL. Thus, for the average Web site the ratio between new code and existing code is very small.
In another example, an analysis of the top 5000 most active open-source software (OSS) projects has shown that OSS written in Java has in average almost 6 millions lines of code. In contrast, the average iPhone application has in average just a few hundred thousand lines of code. In this sense, OSS is “programming in the large” and iPhone apps are “programming in the small”. But thanks to advanced frameworks, even small iPhone apps can have a very sophisticated and impressive user interface.
Adaptable Design Up Front
What should be done in situations in which there is no framework ready to be used for a particular application? Of course in this case the software developers should be responsible also for defining the architecture, and in my opinion this always requires a certain amount of design up front.
I personally adopt the “Respond to Change” strategy, which I call Adaptable Design Up Front (ADUF). In my opinion, in an Agile environment in which the requirements are constantly changing, this is the only strategy that guarantees the successful evolution of software systems. The idea is basically: If you don’t have a framework to build on top of it, first create your own framework and then extend it.
In one of my previous articles I describe how the ADUF approach combines Domain Modeling and Design Patterns. In another post I explain how ADUF is an application of the Open/Closed principle to high-level design. I’ve also prepared a set of slides to introduce the ideas behind ADUF.
Most people claiming that they are doing Emergent Design in practice are doing Framework-Based design in which they don’t need to make high-level design decisions, because they are adopting decisions that were already made by someone else.
In modern software systems the ratio between new code and reused code is quite small. Thanks to advanced frameworks, platforms and libraries, software developers may build sophisticated applications with a relatively small effort.
For the situations in which there are no existing frameworks that can be easily extended, the approach of Emergent Design does not work. It is necessary to do some amount of design up front. My suggested approach is called Adaptable Design Up Front (ADUF).
What do you think? Do you know projects that claimed to do Emergent Design and were not based on existing frameworks? Please share your experience in the comments below.
Great post, Hayim.
“Most people claiming that they are doing Emergent Design in practice are doing Framework-Based design in which they don’t need to make high-level design decisions, because they are adopting decisions that were already made by someone else.”
That they don’t realize that is a bit worrying. It makes you wonder what the result would be if they truly were left to their own devices re: architectural design.
Gene, I believe today there is an entire generation of software developers who never built a system that was not extensively based on existing frameworks and platforms. This is the reason that it’s so common to meet young programmers that don’t understand what is so nice about Design Patterns…
Indeed, and given the productivity gains from those frameworks and platforms, that lack of extensive hands-on experience is understandable. That being said, the lack of appreciation of it is not. I’ve never had to write something that directly interacts with lower-level internet protocols, but I’m at least aware they’re there and know what they do on a conceptual level.
I like the taxonomy of strategies, it’s very useful in thinking about different teams’ approaches.
To answer your question: no, I have never seen a team use “emergent architecture” that wasn’t really template-driven. The people I’ve seen claiming that no separate consideration of architecture is necessary were all building either websites, or enterprise applications using the “J2EE blueprints” (for example) as a template. They don’t need to think about architecture because it’s already been done for them, but they do not understand this for the most part. Ask a typical enterprise software architect when and why you should or should not use EJBs and most will not be able to answer. (That’s been my experience, anyway.) Or ask a web development team dedicated to Ruby on Rails what projects it might not be appropriate for….
I find template architectures harmful in those cases where there are alternatives, because alternatives are not even capable of being considered. The templates are not suitable (and not meant to be suitable) “as is” for all occasions. Yet once a template architecture has been chosen for an organization, it’s rarely modified. The skills to do so aren’t available or encouraged.
For my part, I think I’m using a combination of addressing risk through the use of exploratory architecture “spikes”, and responding to change by starting with–and maintaining throughout–a flexible, adaptive architecture.
FWIW, Big Design Up Front is more appropriate for architecture than it is for the detailed software design, but it still doesn’t fit well in agile development processes and it’s too easy to get it wrong–in which case it turns into “responding to change”, anyway (with a lot of time wasted.)
The original author notes that in some instances in emergent architecture “the decisions are implicit or have already been made.” I think this corresponds to what you’re saying: that these are really instances of template architectures. I’ve yet to see a real example of emergent architecture and I have still to be convinced that it is viable.
Thanks for your comments, Vanessa. I agree when you say that “alternatives are not even capable of being considered”. Worse yet, while participating in discussions about software architecture, I frequently meet people who apparently do not understand that their personal experience developing a particular kind of system cannot be universally applied to other domains.
Big Design Up-Front and Frameworks and Template Architectures are closely related in that Big Design Up-Front is needed to produce a good template or reference architecture. If the template or reference architecture is not targeted to the domain of interest, using the template or reference architecture has the risk of forcing the wrong solution on the problem.
Architecture resulting from Big Design Up-Front, whether generic through a template or reference architecture or custom through domain analysis can guide the detailed software design or composition of the technology stack. Without such guidance, any of the other approaches risks gaps in the solution, e.g., one that is inappropriate or incomplete. The good news is that there are variations of Big Design Up-Front that are highly supportive of the other approaches (e.g., see O’Brien, Wayne. “Avoiding Semantic and Temporal Gaps in Developing Software Intensive Systems.” Journal of Systems and Software 81 (2008): 1997-2013.
When it comes to a large SOA based organization where one team is a consumer of capabilities delivered by other teams it becomes imperative to determine the what and why upfront about the SOA landscape when building new capabilities in your application ( for e.g. for a given capability, which service or services you need to consume, is there service orchestration required, how should the orchestration be done, what are the various protocols available to connect to those services, what do we need to do from the WS-Security perspective to consume those services which are protected using Authenticated and Authorization facilities, do we need the service providers to modify those services to meet our requirements for the application consuming those services.
To address the above questions, I am not advocating big-design Upfront but I think striking a middle ground between emerging solution architecture and Big Design upfront works. I have been employing this strategy which is a hybrid of the above 2 strategies and its working great for us!
I am very skeptical of the claim that the average OSS project in Java is 6M lines of code. I went to the original source of the data, and it says that the average Ruby project is .5M lines of code, the average Python and Perl projects are 1.5M, etc. I don’t believe any of these numbers.
For what it is worth, the first paper on refactoring (about 1990, Opdyke & Johnson) was motivated by framework design. The authors had discovered refactoring when looking at the process people used to design frameworks.
Thanks for your comment, Ralph. I am not sure how precise are these numbers, since they are probably based on a specific repository of OSS projects. But I do believe that Java projects are in general much bigger than Ruby, Python and Perl projects.
I would like to hear your opinion about the two main claims in the article:
1 – When adopting a framework, developers are actually adopting a pre-defined architecture.
2 – What is called “Emergent Design” is very often in practice just the extension of a framework.
Yes, framework are reusable designs, so predefined architecture.
“Emergent design” is often working with an assumed architecture. They may or may not be using a framework. I think of people who build web servers using PHP or any of a number of similar system. They aren’t necessarily frameworks, but they do force a particular architecture.
But on the other hand, sometimes emergent design happens by a small group who develops over a long period of time and is able to take what they have learned and use it to improve their design.
But I also agree that sometimes when people say they are doing “emergent design” they are just too lazy to do real design.
Pingback: Manifesto for Adaptable Software Development | Effective Software Design