There’s a hidden pattern that Microsoft has been promoting for many years with Dynamics. It’s the notorious monolith pattern. Most applications that start off as one thing and then grow to become another typically begin as monoliths and that’s perfectly fine. It’s when those applications take on a life of their own and become much more than we expected that can run into a host of challenges. In this article I want to give you my perspective on how the monolith has come about as the pattern of choice for Dynamics and what we need to understand as practitioners of software systems.
Management of Complexity
Complexity is a typical foe we face when building enterprise business systems. The challenge software teams face is the question of how to fulfill business requirements in such a way that still meets project constraints while doing so within the technology, policy and development constraints. In addition, it’s not unusual for business stakeholders to push for more software capabilities in a project than may be feasible. The political ramifications of failure can mean the difference between not getting a bonus, promotions or even the loss of a job. Software teams naturally do their best to adapt to such an environment and there are underlying consequences to driving influences. This usually is expressed in the emphasis of development speed and feature visible. The hidden consequences of such a mindset are the things we tend to not appreciate until go live which are system performance, robustness, and maintainability.
The monolith design pattern shouldn’t necessarily be viewed as an anti-pattern, but like most patterns should be used within a given contextual scenarios. Small scale development efforts can benefit from a monolithic style as it is often more simplistic and easier. What can and does happen on occasion is software teams attempt to design for extreme scenarios and build out complex architectures that take significant time and effort to build for things that may never happen. As an application begins to grow and take on additional roles and responsibilities you must then consider what parts of the application should ideally begin to be segregated into isolated pieces of functionality. On the other hand, if the monolith continues to grow it can become much more challenging to maintain and enhance as functional dependencies begin to become more brittle. Part of the rationale to break down monoliths is to reduce the complexity of the code into more manageable parts that can change or enhance the code base independently without breakage due to explicit concrete dependencies.
Microsoft’s Hidden Monolith Paradigm
The prevalent Dynamics development paradigm promoted by Microsoft is the app segregated monolith. This is where you build a system for multiple use cases in a single system with a shared data and business automation model but provide separate apps or customized user interfaces to different user groups. When you look closer, you’ll often see that what we’ve done is taken what are separate applications and consolidated them for the sake of implementation convenience. I refer to this as domain entanglement where two or more applications and merged their domain models. Once a system is designed in this way it is very challenging to later separate them. It also dramatically decreases the maintainability of the system as changes made for one user class often impact the others. In large systems this often necessitates a significant regression testing effort in order to ensure other system functions have not been broken or adversely impacted.
The Challenge of Domain Entanglement
Domain entanglement is not a new software development challenge. It’s a legacy integration pattern called the shared database pattern. If you’re old enough to remember the days when servers were very expensive and provisioning times were weeks if not months developers had to be creative in order to build and deploy new applications. It often wasn’t acceptable to simply tell the business they had to wait 4 to 6 weeks for a new servers to come in and be provisioned for an application. We had to use existing application and database servers already available. The easiest and fastest way to integrate two or more applications was to simply read and write to the database tables of other applications if not share the same tables all together. This allowed for faster development times, but cane at the cost of maintainability. While we scored points with the business for initial deployment speed, we took a major hit when those applications needed to change. When two or more applications require a shared consistent data model naturally are more brittle and harder to maintain because a change in one application’s data model had to be compatible with all the other applications. An even worse scenario arises when these applications are maintained by separate development teams who may not be fully aware of that planned changes being implemented by the other teams. I can admit that I used this design paradigm back in the day and application enhancements were always met with resistance and questioning about whether requirements were really a necessity due to the pain and consequences of app breakage that may occur.
The Microsoft Platform Strategy
Satya Nadella has made it clear that Microsoft is serious about the democratization of IT vision. While I think this is a progressive strategy like any strategy there are potential consequences that must be mitigated. If you empower people who fundamentally practice another function, but then give them the capability of creating their own apps then you would have to assume a level of amateurism in what they create. I’ve pondered why Microsoft would push a monolithic design paradigm in the Dynamics platform and the simple answer is it’s the easiest way to build applications. If your building a platform focused on functional business users who have no formal training in software development, then clearly it makes sense to use the simplest architecture pattern possible. For the small-scale system this can be fine. The challenge is when those initial small projects continue to grow in scope and usage across an organization or we attempt to simply use this pattern for large scale projects. This is where we run into trouble and where the rubber meets the road when it comes to democratization of IT, because what we’re really saying is let the people who know the least about software development build the applications.
Monolith applications are wonderful for getting something to work up and running as soon as possible. At the same time monoliths are one of the worst architecture patterns when it comes to solving big nasty complex problems. So, the answer here is yes sure, give the business a way to create the simplistic initial applications and gain an initial level of productivity without the need of IT, but then we must mitigate the challenge of shadow IT and building on to apps that were never designed to scale. The good news is we can use proper architecture principles with the tools and platforms Microsoft has provided, but at the same time it is going to cause many IT departments problems when this new super power is inevitably abused.
Doing Our Part as Experts
The challenge for us as the expert practitioners is to understand Microsoft’s perspective in creating their platforms. When we are designing and building applications, we still need to keep in mind how an enterprise application should be built regardless of what may be promoted. Enterprise architecture is a requirement for enterprise class applications with thousands of users, integrations and geo-distributed consumption scenarios. Let’s be honest. Designing applications that can scale and perform under enterprise scenarios increases implementation complexity and requires more time to build. Ultimately the goal should be to create something that will continue to provide business value over time that is also maintainable and easy to enhance. I can’t tell you how many systems I’ve come across over the years that were initially proclaimed as a success that required a significant effort to upgrade let alone migrate to the cloud. While many project teams see go live as the even that defines success it’s just the beginning of the journey (at least for the customer). Most well-designed systems have a life span that far exceeds the development effort and that should be the expectation. When we use patterns that don’t lend themselves to adaptability and fundamentally breaks one of the main selling points of the platform which is easy upgrades and enhancements, we do ourselves and the business a disservice.
What does all the mean at the end of the day. Stop looking at systems as an all-in-one build. While there are modules to Dynamics, and we can create apps don’t automatically entangle multiple user classes and use cases in the system. While it’s cheaper for the customer to run a single instance of a system the cost comes when you lose the flexibility to for example, separate the sales system from the customer service systems. Think of them as two separate application domains that happen to share the same data store. While this is easier said than done given the current toolset it will promote better system designs and models than simply lumping everything into one big ball of mud.