---
# System prepended metadata

title: The Software Organization

---

# The Software Organization


## Your Org and Software Are Really One System
As organizations consider how to provide better value in the face of complexity, they turn to software, and the creation of new software to deliver more and more services to their customers. It's a plain fact that software is eating the world. Digitizing customer experiences, automating back office processes, marshaling information into insight and even real knowledge, all are the purview of the world of software. Paradoxically the era of the knowledge worker, and of the human based organization is being made possible by our advancements in the machine. Software allows us to operate in a world of  automated service that can interconnect with each other to bring about an era of mass customization.

Because of the pervasiveness of software systems in the modern organization, no serious book on organizational design can be considered complete with out a real look on synergistic effects that organizational design and software system architecture have on each other.

To many organizations ignore the impact that org structure has on software design and vice versa, to their detriment. Many organizations that have truly scaled for agility have done so with scant attention to published agile methodologies. Think the Amazon, Google, Netflix of the worlds. What these organizations have done is treat their software and their organizations as a single system. They organize around the software they want to create, with the knowledge that they will write software according to how they are organized

This chapter will lay out both some of the theory and approach you can take to aligning the two systems of software and org structure. Much of this chapter is taken from my experience in applying concepts taken from the excellent text by Eric Evans, "Domain Driven Design - Tackling Complexity in the Heart of Software". The book is known for being an excellent book on modeling and building software solutions that mirror the language of the business. But the book is more than that, Domain Driven Design discusses how models of software relate, integrate and depend on the teams that build and run them. Over 15 years ago, Domain Driven Design was my introduction in terms of how to think about software and organizations as interrelated systems.

When I originally planned to write this chapter, I expected to have to do a fair amount of work taking many of my experiences and approaches and refining them to something a little more concise and share-able. Then, I came across a recently published book, *Team Topologies - Organize Teams For Fast Flow, by Matthew Skelton and Manuel Pais*. This book has some glaring similarities to mine in that it covers team and interaction patterns to scale with agility. Amazingly we have come to some very similar solutions, and even happen to use the exact same naming in a couple of places (we both use the enablement concept). There are differences, of course, Team Topologies is almost exclusively about software teams, but conceptually I feel the books are very aligned.

Team Topologies spends a fair amount of time  covering, and does an amazing job of illustrating, how to apply the concept of domains to align team structure to software system structure. Rather than re-inventing the wheel, I'll be leveraging some of their work. A big shout out to the great work Matthew and Manuel have done to move this body of work is warranted. It certainly made writing this chapter easier.

## The Peril Of Ignoring Conway's Law

Let's start with a discussion on Conway's Law. Way back in 1960, Mel Conway observed that when separate groups in a larger organization worked together on larger systems they would tend to break up system they working on into parts so that each group could work on their own piece as independently as possible. Or to quote Mel "Any organization that designs a system will inevitably produce a design whose structure is a copy of the organization's communication structure." 

When Mel came up with this law, he defined a system more broadly than just software systems, but it is in the world of software and agile software in particular, that Conway's Law has gained real prominence.  Both open source advocate Eric S. Raymond, and software celebrity James Coplien, are among the many that have observed the impact of Conway's law on software systems. James Coplien stated in a 2004 book concerned with organizational patterns of Agile software development:

"If the parts of an organization (e.g., teams, departments, or subdivisions) do not closely reflect the essential parts of the product, or if the relationships between organizations do not reflect the relationships between product parts, then the project will be in trouble ... Therefore: Make sure the organization is compatible with the product architecture."

Over the last two decades of experience in the software world I have witnessed the dysfunction that takes place when we ignore the impact of Conway's Law. Teams developing redundant code in the same system that provide the exact same business functionality, but inconsistently so. Teams dramatically increasing code complexity though multiple translation layers design so that each team can avoid "infecting" their code with another team's code. Dependency "magnets" that result in multiple teams being unable to develop or test any functionality with out involvement from every other team. Blurred and overlapping module boundaries causing unintended and varied server production issues. 

Mathew and Manuel, in their book Team Topologies rightly point out that when you design a dependency between two parts of a software system, you also need to think about the ideal  communication path for the two teams in the organization that build or own those parts of the software system. When the overall organization is small, this is not much of a concern, but as you scale the number of teams that are building software, you create real fragility when team boundaries and module boundaries are inconsistent with each other.[^tt] Team communication grows exponentially, and the need for management style coordination, and even control, goes up.

Perhaps one of the biggest sins we see when organizations don't pay attention to Conway's law is the creation of the monolith. When communication is poor across multiple teams working on the same software system, we end up with overlapping modules, poor abstractions, leaky interfaces, and dependency magnets. Despite the best intention or well though out design, our software solutions devolves over time into a mess. We end up gravitating towards a slow and clunky monolith.

When multiple teams work on monoliths they lose the ability to make decisions without input from every other team. Or worse, they make decisions on their own that negatively impact other teams. They lose the ability to change the system, without impacting everyone else. Monoliths aren't all accidental, indeed an industrial organizational mindset, with it's emphasis on standards, instructions, and conformity naturally leads to what Manuel and Matthew describe as monolithic thinking. "A “one size fits all” thinking for teams that leads to unnecessary restrictions on technology and implementation approaches between teams.
Standardizing everything in order to minimize variation simplifies the management oversight of engineering teams, but it comes at a high premium."[^tt]

[^tt: Skelton, Matthew; Pais, Manuel. Team Topologies. IT Revolution Press. ]

## Introducing The Inverse Conway Maneuver

If we accept that the wrong organizing structure will have severe impacts on our software architecture, which in turn will impede our organization from effectively delivering value using that software, than it becomes fairly obvious that you can't design effective organizing structure without a deep understanding of software systems. If you leave org design in the hands of your HR department, then HR will also (accidentally) decide your software architecture. You want the opposite to occur, you want your architects, or senior developers, or what ever you call your people with deep software system knowledge to intentionally define teams around the software architecture you have, or want to have.

This approach, dubbed the "Inverse Conway Maneuver", by Matthew and Manuel, is an intentional act of re-configuring the team intercommunication according to the boundaries we want between the different parts of our systems. The frequency, intimacy, and bandwidth of communication paths shape the kinds of solutions we devise. When one or two teams closely collaborate on a system, we are more likely to see chatty module boundaries, or perhaps a system with few distinct partitions. When multiple teams "intentionally" operate more independently, we are more likely to see the team integrate through well defined APIs, or loosly coupled through publishing and consuming events. When we have a mismatch between teams and separate system parts, we get a mess. But the idea here, according to Manuel and Matthew is to use the synergy between system and organization "to our strategic advantage. If we want to discourage certain kinds of designs...we can reshape the organization to avoid this." [^ttt2]
[^tt2: Skelton, Matthew; Pais, Manuel. Team Topologies. IT Revolution Press. ]

### The Perils Of Focusing On Software Internals
Historically, we have seen an emphasis on focusing software architecture around system internals, on decoupling the technology layers as much as possible in an attempt to create a layered, or "tiered" architecture. Systems were divided into a minimum of three loosely coupled layers, the presentation, business logic, and data layers. Often additional integration, orchestration, or workflow layers added to the mix. In an attempt to follow Conway's law, we would create separate teams stood up to develop and possibly maintain the distinct software for each specific layer of the system. We ended up with a presentation layer team, a business logic team, and a data team. At a minimum. 

This approach seemed sound to many at the time. But really, it is the product of the inward focused thinking we see from an industrial mindset.  And we get many of the same problems that we do from a functionally siloed industrial organization. This is because most system software changes typically impact multiple layers of a software solution. For instance, if we need to expand our shopping cart functionality to accommodate discounts from external marketing campaigns - this will impact the presentation layer, the business logic layer and the data layer. Members from all three teams will need to closely communicate to make sure that changes that take place across the system are consistent, and do not contradict each other. 

In contrast, when we ask the teams to make changes to how the solution manages product inventory, we would want that change to have low to little impact on adjacent functions such as how we manage customers, or perform billing. But in our current org design, these concepts such as customers, billing, inventory, etc are all worked on by the same teams. Whether intentional or not, we are more likely to have chatty interfaces and poor partitioning across these functions, and un-forseen dependencies between these concepts are likely. 

*Stephanie Dimovski, was one of the product owners leading an ambitious initiative to  modernize the point of sales system being used by in store pharmacists. "This was an important initiative. Inconsistency in prescription, disbursement, and patient data had been shown to be costing actual lives, so it was important to increase timeliness and accuracy of information across all pharmacies in all provinces across Canada. We had an immediate focus on building real time integration between the store POS and the provincially setup health patient prescription tracking system. Because of the focus on safety, our engagement had some pretty tight timelines. Previous teams on this program had suffered from some previous hiccups, late delivery, missed scope, things like that. That put this engagement in a situation where we were asked to deliver something in a matter of months."*

*"Early on in the engagement, the decision was made to re-structure the teams in our "Mission" (their word for ecosystems) according to architectural layers so that we could focus engineers on individual components that they would be experts in. While the Product Owners felt there was a risk that teams would lose the context of feature as it traveled across the front end and back end teams, we agreed to try it out with an open mind.*"

*In the end the approach did not provide the gains that leadership had hoped for. Teams did indeed lose context as a feature traveled across teams and many hand-offs occurred. Teams did not have ownership of a feature and therefore didn’t need to be accountable to the end state of that feature. Really it was a bit of a disaster. The deliver by contract approach may have sounded good on paper, but it required so much upfront design to understand who could work on what. It quickly became a nightmare to know who was responsible for which pieces. No one had ownership of when an end to end piece was going to be done. There was no tangible business “Thing” you were building. And our throughput plummeted, to about 7 stories a sprint from an average of 16."*


## Introducing Domain Driven Design
Domain Driven Design (DDD for short) is based on the idea that the structure of our software systems should reflect the way business experts think about their business. Software should mirror business concepts and subjects, business activities, business state, and business rules. Infrastructural and cross cutting concerns, should be treated as they are, which is system internals. 

In a Domain Driven Design approach you partition modules firstly by business concepts, known as business domains. Things like Customers, Billing, Orders, Fulfillment are all potential ways to partition the system. As systems scale, the rate and reasons to introduce change are more likely to be different across these business domains than across software layers. For instance, changes to you supplier code will likely change the way you your fulfillment code works, but have little impact on the code you use to acquiring new customers.

In contrast UI, workflow, data access, are considered to be internals; and while consistency may be desirable for these pieces, it is far more important to have well managed interfaces between the business oriented concepts than to obsess over internal consistency between all code belonging to a software layer. 

Domain Driven Design tackles solution complexity because it focuses on the areas of the system that are most subject to change, ie the business domains. It places emphasis on capturing the knowledge that are most likely to require experts outside of the field of software, ie the business, and the customer; the business domain.

![](https://i.imgur.com/uiiqDMs.png)

A team is doing Domain Driven Design when they model, communicate, and develop according to the core business domain logic of a solution, and do so using a common domain language, known as a *Ubiquitous Language*. Software specialists work intimately with domain experts to capture the domain model, using domain terms, and embed the domain terminology into their code.

The benefits are systems designed to flex and evolve in a way that reflects how the business will change. Major changes will create major system changes, minor business changes will require minor system changes.

## Organizing around Domains

### Domain Aggregates
If we accept that structuring our system architecture according to business domains is the preferred approach, than we can in turn start thinking about structuring teams according so discrete *domain aggregates*. A domain aggregate can be thought of set of domain concepts that are very tightly interrelated with each other. A customer and their demogtaphics, or a shopping carts and all of the independent order items in it. Domain aggregates are made up of domain entities and all of their invariants, in other words, dependent domain objects that are retrieved together, updated together, and otherwise change together. The Inverse Conway maneuver is most effectively applied when we think about partitioning software into separate domain aggregates. This allows us to organize teams so that they be can be focused on the software required for a limited number of these separate business domain aggregates.

![grouping domains into aggregates](https://i.imgur.com/psQwVC6.png)

### Bounded Contexts
In larger systems, DDD recommends that we place our domain aggregates into into separate *bounded contexts*. A  bounded context places a hard boundary around one, or possibly a small number of highly dependent domain aggregates. In a nutshell we define bounded contexts according to distinct, but possibly related domains of knowledge. A bounded context could be set up around a Payments domain aggregate, or Customer, or Accounts and Agreements, or Charging and Billing. Bounded Contexts can nest, perhaps larger ones representing entire systems, and a smaller one representing a single domain service.

We may then refine our bounded contexts by grouping smaller domain aggregates into larger composite domains, and dividing larger domains into separate, but related component domains. We explore how different domain aggregates relate to each other, and what the dependencies are between them. This allows us to suggest bounded contexts that can serve as the basis for a team structure that minimizes the number and impact of dependencies that cross teams. 

Structuring teams around bounded contexts is a good way to achieve an *acceptable* level of independence when multiple teams are working on a large scale system. While we may want teams and ecosystems to be truly independent, complete independence is often an impossibility. In the real world, we often have to settle for *decoupling the dependencies* across teams and ecosystems of teams. Defining bounded contexts around decoupled domain aggregatres allow us to achieve this.

![defining bounded contexts for teams and the aggregates they work on](https://i.imgur.com/fcgn14n.png)


*Ruth Nielsen, another product owner on the initiative talks about how re-organizing according to bonded contexts helped to turn their program around. "We continued to advocate for owning how we wanted to structure ourselves. We showed the impact of the development by contract approach to our throughput. Eventually we were given the reins back."*

*"Right away myself and the other product owners agreed that we couldn't focus on getting components done in isolation, if we just built the button, or just the message, etc, we wouldn’t have a product. Instead we structured our work so we could incrementally show how user activity was translated to the Provincial Information System, and back again. This is what the province cared about, and this is what our stakeholders cared about. There was no point showing something to the province if it wasn’t working end to end. So we organized around building end to end functionality. We organized around user feedback."*

*"We ended up forming teams around distinct, but related domains, each within their own bounded context. Each team was expected to work cross-functionally, delivering an end to end slice of functionality that demonstrated a complete journey from in store POS, to provincial disbursement information system, and back again."*

*Ruth, Stephanie and the rest of the leads across the teams collaborated on how to go back to a cross functional team structure like they had before, but with a subtle but distinct difference. Teams members would form into smaller feature cells around discrete bounded contexts.*"

*Ruth discusses how the approach kept things manageable. "Team were were tightly defined and people could work within a small group, according to a tight set of features within a particular bounded context. Team members got to learn the entire stack without being overwhelmed by the entirety of what the program was doing. This made developing end to end flows ALOT easier to do. After a few weeks of setup time the teams began to get and throughput started top increase, eventually to almost 30 stories a sprint!" *

*Stephanie adds “Allowing teams to form around specific domain based context increased the understanding of the value the team was providing, toward end to end value being returned. There was no going back to a siloed way of working. We gave the teams ownership of something tangible, something to be proud of, we were successful because their work had meaning."*

## Representing The Software Artifacts Of Your Business
An important aspect of a bounded contexts is that is represents a *hard boundary*, one where all the aggregates within the boundary are part of common consistent context. They represent a common view that is only considered "true" within the boundary. Different representations of the same concept are allowed, and even to be expected across bounded contexts. What this mean is that the software used to represents these concepts will only be consistent within a boundary. Thus, we need to be explicit about dependencies across bounded contexts, and be explicit in the definition, translation, and integration required when crossing bounded contexts. This is important not only when thinking from a software perspective, but more importantly, from the perspective of what these concepts mean to the development teams and business experts that work within a particular bounded context.

![two views of the same thing...](https://i.imgur.com/VrJg7Mm.png)


Within a bounded context we ask software and business experts to examine each domain aggregate and agree on what *services* (or operations) are being provided by the aggregate, what domain entities are being managed, what orchestration happens, and how these domain entities within each aggregate can be retrieved, created, and stored into a *domain repository*. Concepts like what is considered valid state, or various other rules , workflow, and conditions are also explored. The idea is to create a programmatic API that is expressed purely in business concepts and business terms. Such that if a business expert can see past the programmatic syntax, they could see a living expression of their business.

![the coomon software artifacts of your business](https://i.imgur.com/3Gj72hW.png)

The relationship, dependencies, and interactions between dependencies between bounded contexts can be illustrated by using a *Bounded Context Map*. A bounded context map can shows the relationship not only between the system boundaries, but can show also the interaction model being used by the teams that own the interaction model.

![](https://i.imgur.com/9zKbjJo.png)


In the above diagram, where the CRM and Customer contexts, overlap, we have what Eric Evans calls a *Shared Kernel*, impacts to the model of element in the kernel impact both teams and require intimate collaboration and shared code ownership, daily integration is common, perhaps a single repo or pipeline is in use. In the case of this example the teams have agree that they need to act as *Traveling team Workers*, and come together to work on demographics and contact info together. This approach is appropriate when two teams are both working on inter-related domain concepts forte first time, or when major changes to both teams representation of these domain concepts are being made. Coming about with an agreeable boundary, determining exact dependencies, and coming to a good API will require trial and error across both teams, intense collaboration will be required. Shared kernels can also come from accidental architecture, dependency magnets, and other forms of tight coupling. Where possible try to refactor your solution to minimize this form of coupling.

Many bounded contexts will be separate but still have some form of dependency with another bounded context. Expressed as arrows in the map, these dependencies in this case are more decoupled than the shared kernel variety, and changes to ordering code may only require minimal changes to customer code. Code that is already expressed as a well formed, and stable customer API. In this case the customer team can act as a *Service Provider* to the orders team. The customer team can gather requirements from the orders team, preferably in the form of acceptance tests, implement the changes needed, and review / demo the results with the orders team. Eric Evans calls this a *Customer / Supplier relationship*

Finally we will have cases where a bounded context will require no change to the API or underlying code in order to support the needs of the team/context with the dependency. In this situation the supplying team is really responsible for acting as an *Enabler*. In our current example the Orders team is being enabled by the CRM team as they work on the sales domain.  The CRM team is responsible for providing a well tested API that is easy and obvious to use to the Orders team, and to provide great support to the Orders Team when they have issues or questions, Eric Evans calls this integration approach the *published language* method.

Personally speaking, the idea that context boundaries and bounded context maps are an effective way to organize boundaries across multiple team on a large program is something I have been working with clients on for over 15 years at the time of this writing. Demarcating context boundaries based on distinct domains, in a way that respect Dunbar's numbers gives us an approach that lets us decouple our organization into separate pieces that can free them to experience change at different speeds from  each other, while at the same time bringing people together based on their ability to collaborate. Using Context boundaries to group teams, code, and other knowledge together was my very first stab at trying to think of more organizing structure that enabled rather than stifled agility!*


![my earliest days at agile organizational design, the bounded contexts of a provincial vehicle management system](https://i.imgur.com/6lDbBHP.png)

## Identifying Domain Aggregates and Context Boundaries
For the most part aggregates and boundaries can be identified by simply taking an inventory of the most important subject areas of your business. Then ask how coupled are these concepts from a business perspective? Working closely with business subject matter experts, it is relatively easy to come up with such a list, general concepts like Customer, Account, Billing, and Product come to mind, but make sure to find topics that are specific to the business you are writing software for. For instance in the world of Pharmacies you would likely have domains around Prescriptions, Disbursements, Patients, and Medical Providers. In wealth management you could have distinct bounded contexts around Financial Instruments, Trades, Interest, Equity, Business accounts, Consumer Accounts, Client Contact Information, and Broker Information. The point here is many technologies try to build solutions around abstract models and then struggle to adapt these the specifics of a problem space. I recommend you model your solution, and organize your teams around concrete business concepts that matter to your stakeholders that directly serve the market. Let abstract concepts evolve as you apply domain concepts to multiple areas.

There are also some additional ways you can think about carving out domain aggregates into separate bounded contexts, often there are various approaches we can take to identify the subtleties in a domain that justify partitioning a portion of into a separate bounded context:
- **Regulatory and Compliance** : the requirements imposed on a solution can often be housed into its own bounded context, even if those requirements span a number of other, adjacent domains. For instance requirements that come from "Know your Customer" related  regulations often consistent across many banking products and lines of business. The rules, structure, validations, and other business logic related to complying to these regulations could be served up by common micro-service infrastructure and injected into various parts of the solution. A Know Your Customer Team would be responsible for a KYC API and collaboraring and supporting other development teams.
- **Transaction Rates** : When transaction occur a dramatically different rates from each other in a system, chances are you have identified a distinct domain boundary that can be decoupled into separate contexts. Customers and their accounts tend to be acquired, updated, or retired a lot less frequently than customers purchasing new products. For telecom or financial products, we see transactional activities taking place much more frequently than we see products being purchased. Inventory replenishment happens at its own cadence, less often than customer transactions, but typically more frequently than changes to products being offered changes.  When we compare how many time data will need to change  over time across a solution, it becomes clearer which domains should be more tightly coupled, which areas can be more loosely coupled.
- **Market Actors** : The needs of various customer segments, user personas, etc that make up your market actors may be distinct enough that you define distinct bounded contexts based on these distinct needs. For instance in world of banking the workflow, the applications used to serve world small business customers often can be quite distinct from the kinds of large scale processing applications used to serve large commercial business customers. The flows can be quite distinct, the requirements for reversibility and audit-ability can vary, etc. Concierge clients may also have a different feature set, risk profile, etc than other customers, and thus managed as a separate bounded context.
- **Domain Life Cycle State**: Our view of a domain can be quite different based on where a domain entity can be in it's lifecycle. We care about very different things when we are managing a lead vs managing the transaction of a real customer.  Having distinct bounded contexts for both Leads and Customers can often make sense. Likewise we may care about different things about a Product when managing it's assembly, vs marketing the product on our website to consumers. Again, separate bounded contexts for each of these product perspectives can make sense. 

 ## Limiting Domain Complexity Per Team
 A natural question to ask is how much domain complexity can a team handle. Matthew Skelton and Manuel Pais discuss using domain complexity as a guide to determine this number. In my experience this is a function of both complexity and change being made to the domain, so I would amend their guidance to include both complexity and degree of change, to determine the number of domains a team can work on at a time:
- One complex domain or one domain going under a high degree a change
- two to three simple domains, or a domain going through 2-3 simple changes
- avoid a single team owning more than one complicated domain or having to make substantial changes to more than one domain at a time
 
Again these are good rules of thumb, and context matters. The point here is to make sure that we keep cognitive load on teams manageable while at the same time we encourage the teams to grow their skills and knowledge. Looking at the teams flow of work may giveyou warning signs that the team is overwhelmed. So will asking teams how they feel about the amount of domain complexity that they own. 

## The Modern World Of Micro-Services
As mentioned previously the thinking behind structuring teams so they can develop distinct and decoupled bounded contexts has had an influence on the direction and adoption of new architectural paradigms like container based provisioning, micro-services, and No-Sql. 

Using modern development and deployment technologies, we can take each one of our bounded contexts, and represent it as a cohesive code base that is represented through a well formed API, and deployed independently from the rest of the system using container based technology. We deploy a separate container for each bounded context, and each container includes the business logic, data access code, and even, thanks to No-Sql technologies the database itself. Some organizations are even experimenting with deploying formatting "naked" UI code, so that application consumers have the option to skin a reference domain based UI and hook that into their larger front end. We can then maximize decoupling across each bounded context through event based coordination, perhaps using the latest event streaming platforms.

![](https://i.imgur.com/3maZvek.png)

This book is on no way a text on software architecture of any sort, and there are others who have delved far deeper into how to apply modern software approaches than I have. But I'll admit to an unbridled passion for the subject. And it is worth pointing out that micro services, containerization, event streaming, and no-sql have been inspired by concepts such as domain aggregates and bounded contexts. When we guide the use of these more modern delivery technologies with Domain Driven Design and the Inverse Conway Maneuver we end up with a system that is decoupled in a way that allows teams to work independently an intelligently on a larger system. 

We avoid the dangers of the monolith and the dependency magnet. We are able to deliver, and operate these distinct parts of our system according to natural seams within the system, what Matthew and Manuel call "fracture planes" [^tt3]. Each fracture plane can be supported in a way that matches their unique needs. Each fracture planes will have it's own rate of change, it's performance requirements and usage load, it's security needs, or other risk factors. Teams can thus fit their approach to the profile of the fracture plain they are supporting. WE get the best of both worlds, a well reasoned architecture that provides teams with the freedom they need to deliver based on their context. We get to scale with agility.
[^tt3:Skelton, Matthew; Pais, Manuel. Team Topologies . IT Revolution Press.]


![context boundaries structure both teams and the work they do](https://i.imgur.com/iDUpOuG.png)

It is worth being wary of that fact that when many traditional organizations look at how they are approaching their deployment of technologies like cloud and micro-services, they do not appear to bring much of this thinking along with it.

Many responsible for adoption of these approaches forget that these technologies are there to enable better self-organization, and increase autonomy of teams. They mandate usage according to detailed standards, gate cloud access through specialist teams, and otherwise use these technologies to exert unnecessary control on teams. Worse they do not consider the relationship between domain bounded contexts, micro-service topology, and team structure. The result is often a worse mess than the monolith they started with. A fragmented architecture and organizational mess we call the *distributed monolith*. Those leading the adoption of new technology would do well to remember that successful adoption of these tools without increasing team autonomy is really not much of a success at all.  


## When We Need To Organize Around Technology Instead
While I have emphasized the importance of a taking a business domain based approach to partitioning systems and defining different bounded contexts, there **are** situations where bounded contexts should be based on technology considerations. This is often necessary when a solution relies on a number of packaged software and integrating legacy systems. In these cases teams are forced to work with system representations of various domains, and these representations will vary from system to system, hence the need to define bounded contexts from a systems perspective. Delivery flow will be considerably different across systems, with changes involving older technology being rather slow, because of more manual testing, onerous deployments, poor documentation and aging code bases. Both package products and legacy system often do not have good support for modern engineering tools and practices like Test Driven Development and Continuous Integration & Deployment. Finally, the ecosystem of tools (IDEs, build tools, testing tools, etc.) around such technology tends to behave and feel very different across various proprietary packages and legacy systems. 

![](https://i.imgur.com/tIs2Oni.png)

All of these factors make a compelling case to structure teams around systems, rather than domain aggregates. Using this approach, we define bounded contexts for each system, and perhaps for discrete modules in theses system. We can use a bounded context map to identify the way we want teams to collaborate where domain entities are represented in multiple systems, and need to work on the integration required to ensure the overall solution works in a consistent way. It is important to note that this approach can suffer when the systems under change are being stood up for the first time, or undergoing a very large amount of change. Dependencies across teams can make delivery an incredibly complicated affair. In these cases, it may be better to start with a single team made up of one or two specialists from each system, and have them lay out a common understanding of how requirements will cascade across the various systems. Once this common understanding is established, it then becomes much more feasible to scale out toward system based teams.

## In Summary 
- **Scaling organizational agility** in many cases means treating the **organization and the software that supports it as a single, integrated system**.
- **Conway's Law**, implying that the **dysfunction of your software will match the dysfunction of your organizational structure**, has been ignored by many an enterprise, resulting in monolithic and fragmented systems that have frozen organizations ability to deliver value quickly
- We can use the **Inverse Conway Maneuver** to **deliberately partition our software solution around the communication pathways we want our teams to have**, in other words deliberately aligning software architecture to organizational design
- **Domain Driven Design** asks us to design **software solutions that intimately reflect business domain concepts**, domain language, and the business domain experts think and speak
- Partitioning system into **Domain Aggregates and Bounded Contexts** allow us **define parts of the system that change together**, and that are **naturally decoupled** from the remainder of the system, as opposed to partitioning the system based in technology internals, which results in system parts that are highly dependent on each other.
- We can **structure teams around each bounded context**, allowing multiple teams to work in a reasonably autonomous way on a single system.
- A **modern software stack** using micro-services, containerization, No-Sql, event streaming, etc **enable teams to increase their ability to work within a bounded context while minimizing the impact to other teams** working within a separate bounded context.
- When working on **legacy systems and package software solutions**, the diversity in technology may require us to **set up teams and their bounded contexts around these systems** instead of domain based bounded contexts.

