A key building block for burgeoning software architects is understanding and applying software architecture styles and patterns. This session covers basic application and distributed architectural styles, analyzed along several dimensions (type of partitioning, families of architectural characteristics, and so on). It also provides attendees with understanding and criteria to judge the applicability of a problem domain to an architectural style.
Let's talk about these architecture styles. I'm going to spend most of our time talking about styles here, given the amount of time that we have. Here are the styles that I want to talk about, both technical and domain specific architecture patterns. And I'll describe what I mean by that in just a moment, but I want to talk about all of these generic architecture patterns. These are generic because these are broadly useful to solve a lot of generic, typical problems that you discover in software architecture, things like layered architecture, microkernel, event driven architecture, a couple of flavors, two different topologies, the enterprise service bus driven SOA, which I'll only briefly talk about.
And in fact, I'm not going to go into a lot of detail on any of these architecture styles, because first I don't have time to give them the scope of this talk. All those details are there in our book if you're interested in going to more details. Well, what I really want to talk about and cover in this talk is the philosophy behind each of these architectural styles, why you would choose to solve a problem in this style versus one of these other styles.
And so, I'll talk a little bit about the structure, but mostly focus on the philosophy behind these architectures. And one of the first things you have to think about is what really differentiates these architecture styles from one another and it really boils down to: So when you think about the job of an architect, the kind of structural design part of the job of software architect, what they are looking at is designing the domain, whatever this problem is.
So, you have a problem of some kind and you decided “I'm going to write software to solve this problem”. That's your problem domain. But that's not the only thing you have to think about when you design a software system, you also have to think about all these other things. This is what Mark and I referred to as architecture characteristics.
Some people refer to these as nonfunctional requirements or system quality attributes or crosscutting requirements. Whatever you call them, though, this is another aspect of design that you have to think about when you are designing a bit of software architecture, and this is the thing that really differentiates one architecture style from another, because one architecture style has a sort of built in support for things like performance, scalability, and elasticity, and another style does not have that same inherent support.
We wanted to really define this idea of architecture characteristics. And we put this together in a three-part definition. These are things that specify a non-domain design consideration. So that really gets to that split that I talked about between the domain and these other things that are necessary to be successful in your architecture, an influence of some structural aspect of the design. Not every single requirement yields an architectural characteristic that has to be something that supports something about the structure, because remember we're going to design an entire system with code. What we're looking at here are the things that really impact structure in particular.
Things like operational architecture concerns, like performance elasticity. I’ll talk more about those in just a second. And finally, critical, or important to application success. Each of these things is synergistic with all the other things that you have to design in your system and supporting a lot of these makes your design a lot more complex.
And so, one of your jobs as an architect is not over-design your system by choosing too many of these architecture characteristics. So, finding the exact sweet spot for these things is critically important. Now, overlaid on top of this are these ideas of implicit and explicit architectural characteristics.
Explicit ones are ones that are written down like a performance, a requirement, or a requirement to support a certain number of concurrent users, for example. But there are other implicit architecture characteristics as well, like internal architectural structure. You typically don't get a requirement in your software system that says, “please don't screw up the internal structure of your architecture”, but that's one of your jobs as an architect, is don't mess things up.
And so, that should be one of the things that you think about as you design your system. Yeah. All of these things support that domain design that you're working towards in your system. And these really form the scaffolding. And we built this as an unstable pyramid on purpose because all these things lean against one another and influence one another as part of your design, which again is more a motivation not to over specify these things. And so, this gets to that split nature of architecture, which is really about the domain and figuring out these architectural characteristics.
Well, one last thing I want to talk about, which gets to that categorization that I was showing you before, and that's about the top level partitioning in architectures. Now, you can build components in architectures, and components can be nested inside one another, but the thing that we call the architecture style is really the organization of the top level components in that architecture, what we call top level partitioning.
And so, let me talk for a second about what we mean by that. So, when you think about the traditional layered architecture with the presentation layer of business rules and persistence layer, this is a good example of what we call technical partitioning in architecture. It's partitioned along technical capabilities like presentation and business rules, etcetera.
And this is certainly a logical way to organize your architecture. Just make sense. All the persistence code goes together, and that certainly makes sense. But it's not the only way to organize your architecture, and you have to think about some of the tradeoffs of organizing your architecture like this.
So, for example, where do domain concepts like a catalog checkout live in the layered architecture? Well part’s in presentation, part’s in business rules and part’s in persistence, part’s in the relational database. So, you've taken that domain concept and kind of smeared it out across all of these technical layers.
Another way of organizing your architecture is domain partitioning, and this has been very popular in recent years, even with monolithic architectures, it deployed as a single unit with a single database, but organizing things around domains rather than technical capabilities, so the yellow component here would be catalog checkout rather than some sort of technical capability.
This is a different way of organizing things, and in fact catalog checkout may have some layers inside it because you're using a persistence library or framework, for example. But the top level partitioning has a lot to do with the way that you think about your architectures. And in fact, that's how we have architecture organized here between technical versus domain partitioning.
That's that first split between technical and domain partitioning. And as you can see, the more modern architectures, modular monoliths, microservices and service-based, are more domain partitioned. And I'll talk about why that is as we talk about some of these architectural philosophies.
The other legend that I have here is really about whether it has a quantum of one or a quantum of greater than one. And I don't really have time to go into this quantum concept here given our time constraints, but that really just is: is it deployed as a single thing or is it deployed as a distributed architecture? And so, the pillars there mean it deploys a single thing.
And so, let's talk about some of these architectures. I've already talked about the layered architecture and many of you are familiar with the layered architecture, I’m quite sure, but I go into most organizations and ask them, “What kind of architecture do you have?” And they say, “What is architecture?”
Typically, what they have is the layered architecture of this presentation. A layer of business rules and that persistence, probably with a relational database of some kind. Typically, when you see a layered architecture like this, all of those layers are closed. And the reason for that, the philosophy behind this architecture is separation of concerns.
And what were the benefits of this architecture as well? If I have all of my persistence code in that persistence layer. If I need to make a change to that persistence layer, and I know that nothing else can go into that persistence layer other than business and database for the enter and database for the exit, then that gives me freedom to make broader changes to that persistence layer.
One of the things you have to worry about for every architecture style is pattern governance. So, as the architect, you design an architecture for a particular reason, and one of the reasons you designed this layered architecture is for separation of concerns.
So, what happens when the reporting team comes to you and says, “We need direct access to the database for performance reasons”, should you allow them to do that? And the answer probably is no, in this case, because that's basically going to ruin your separation of concerns, and it's going to lead you to the big ball of mud anti-pattern in your architecture, and that's definitely what you do not want. Now, one of the things that you're responsible for is governance as an architect, and it turns out that there are a lot of modern tools that allow you to automate architectural governance. This is a tool called ArchUnit that is designed to allow you to write unit tests to test the structure of your architecture to make sure that it's sound. this uses the hand crest matchers from the J unit world to make for these very readable assertions. And you see here, the first test:
This is a great example of something that's called an architectural fitness function. And if you're interested in this, I don't spend much more time here today on this, but I'm doing an entire workshop at this time tomorrow evening, a three hour workshop about evolutionary architecture and delves into exactly this kind of automated governance mechanism, the ability for architects to define principles in architecture and then build mechanisms that preserve those architectures for you. ArchUnit is for the Java ecosystem. NetArchTest is the same kind of testing tool for the.NET ecosystem, and it uses the same kind of fluent matchers.
The drivers for the layered architecture are very much simplicity and cost. Not many people build the pure, layered architecture anymore, it is the simplest kind to build. But even if you're building a monolith, you're probably building a modular monolith because that would translate more easily into a more modern architecture style, like microservices, for example.
So, let's talk about some more interesting styles. Like microkernel, also known as the plug-in architecture pattern. And the core typology here is a core system that has the primary functionality of the system, and then plug-ins that drive whatever changes you want to make to that system.
And so, the main idea of this ecosystem is I want to build a core system that changes very little or not at all, and then drive changes through all of these plug-ins. This works well if you, for example, have a high degree of customizability in your solution.
Probably the most famous example of a success story using this architecture pattern is Eclipse. Eclipse very much uses this architecture style. If you ever downloaded the bare version of Eclipse with no plug-ins, I think it can open and close text files and that's about it, so it's a very weak functionality by itself.
Everything is driven by plugins, but this is also quite common in, for example, business applications, like insurance claims. For example, in the U.S. we have 50 different states and it would be quite common as a business for us to have different rules for different states.
And so, building this as a microkernel allows you to build a core of insurance processing in the middle and then drive changes or customizability through each of those plug-ins. Typically, the complexity in this architecture comes through how complicated these contracts have to be between the plug-ins and the core system.
And this is really the thing that differentiates this between just plugins versus a microkernel. There's definitely a spectrum here, because not everything that supports plug-ins is a microkernel. It really depends on how functional the middle part is, the core. So, for example, a browser isn't really a microkernel because it’s perfectly functional without any plugins.
The idea of a microkernel is it's not functional without plug-ins, but the plug-ins are the things that drive behavior. A great example of a microkernel would be a source validation tool. And my tool, all it does is read source files and apply validation rules to them. And now I can plug in all these different validation rules. Now, without any plug-ins, it's not useful, because there are no validation rules.
And so, this is really the essence of a microkernel versus just a plug-in. That, of course, just like all of these architecture patterns or styles, it really exists along a spectrum. So, the real driver for microkernel is really customizability, which doesn't really show up here, but is implicit in a lot of the combination of these things. That customizability really allows you if you've partitioned your problem space correctly. If you find yourself having to make a lot of changes to the core system, then this is not a good architecture style, but this is also an architectural filing that’s embedded in a lot of other systems.
So, for example, you might have microservices in one part of your one service that needs a high degree of customizability, and so this would be a perfect architecture just for that service.
Lots of embedded tools, like enterprise service buses use this pattern, uh, any kind of adapter uses this pattern. Integration hubs typically use this package. So, you see this architecture pattern a lot, especially once you start seeing it, you tend to see it everywhere.
All the ones that we've talked about so far have been single deployment, monolithic architectures. Let's talk for a bit about distributed architectures, which are more complex, but more powerful and therefore more interesting, for the most part.
So, let me talk about two event-driven architectures briefly here, broker and mediator topology. Now, events and messages can be used and are quite often used within higher-level architectures, like microservices. And in fact, at the end of the day for you today, but tomorrow morning for me, I'm doing another talk called Architecture by Example, and it actually demonstrates using events inside microservices as a way to design an architecture, but you can also design an architecture purely just on top of events and messages.
And you still might want to do that, because it gives you the unique combination of both scalability and performance, and it's hard to get both of those at the same time. Now, you have to build a lot of the moving parts yourself in an architecture like this, but you do get some really interesting capabilities.
So, let's talk about the two shapes of this architecture. And the first of these is the broker topology. And here you have an initiating event, just something that happens from the outside world. And that gets captured by an event channel, which then redirects that to an event processor, which is where code lives within this architecture.
And that unit processor will do some processing on it, as to its name, and then optionally post a message to another event channel, which will then do some processing on it, and post another message until this business process is complete. This is a good example in a broker of what's called choreography as a message passing style.
So, let's look at a complex business process in a broker typology. So, let's say for example, we're an insurance company and the initiating event is change of address for one of our customers, so our customer moves. Customer process will pick that up and do whatever internal update is necessary for that move and then post a message to anyone interested in a change of address. Turns out both quote and claims are interesting change of address, so they'll both pick that message up and, in parallel, they will process and do whatever they want to do with it until finally, this processing is done. Notice that claims may, in fact, multicast and send messages to multiple different end points.
And this is called choreography because there's no central ordination here. Each of these processes is just reacting to some event that happened before, and so adding, for example, a new event process is trivial here, because you just latch on to an existing event queue.
So, let's talk about the other topology, mediator. And it's worth saying parenthetically here that I said that these two give you the unique combination of performance and scalability, but one of these gives you higher performance and scalability, and I'll talk about why in a second. So, let's talk about the other one, the mediator topology. And this has the same basic building blocks we saw before: initiating event, any event queues and messages, but it has this extra piece called a mediator.
Now, realize this is an architecture, a style or pattern. It's not a particular tool, although lots and lots of different tools implement this mediator pattern. Enterprise service buses implement this, Apache Camel implements this, Spring WebFlux implements this; basically any architectural component that allows you to define some workflow between distributed components, and that's a pretty broad category of things.
And so, in a mediated event-driven topology, you have this mediator and it's the one that accepts messages and sends out work to all these different processors. But you notice none of the internal event processors send messages to each other. They always go back through the event mediator.
And that's important because the important business workflows are defined in that mediator. And you don't want to accidentally bypass one of those by going around it for example. When you look at our complex business workflow here, it's much simpler to understand because you can write that down in your mediator.
Now, this is typically written in XML, or central workflow language, or maybe it's a B.P. tool or business process, execution language tool, or something like that. But it allows you to write down what order things get, what happened. And in fact, do things like pseudo-transactional coordination across these end points.
This is what's traditionally called orchestration and that process mediator is acting as the orchestrator. So, what's the distinguishing factor of an orchestra is the conductor standing up front, controlling the timing and coordination of everything, and that's exactly what a mediated event-driven architecture does.
Why would you build an architecture in all these very low-level moving parts? You notice I never mentioned a database here. If you want data, you have to wire that in yourself, any kind of behavior, like transactions all have to be hand coded in this architecture.
The reason you picked this architecture is a specific kind of modulator to get a high degree of agility and fault tolerance, mostly built into the tools, but also really, really good scalability and performance, And that's the real selling point of this architecture.
Now, of the two topologies, broker or mediator, which do you think gives you higher degrees of performance and scalability?
Turns out broker is the champion here because you can do more things asynchronously and there's less coordination required than through something like a mediator, which always becomes a bottleneck, both from a technical standpoint and from a social standpoint, you'll end up with integration architects that start ruling your organization around that enterprise service bus, for example.
But of course, everything in software architecture is a tradeoff. That's actually the first law of software architecture from our book, everything in software architecture is a tradeoff, including this, because while you get better performance and scalability from broker, it's much more complex to deal with because everything's asynchronous, you get deadlocks and race conditions.
Debugging is really difficult, doing things like error handling and transactional coordination is very difficult. And so, generally you rely on higher level architectures like microservices, but very often you create hybrids. And in fact, you will often see a broker style, event-driven architecture being used in combination with microservices to solve some of the performance issues that you sometimes see in microservices, and we'll talk more about that as we talk about microservices.
You also get really good elasticity, adaptability and evolvability. Those last two may seem like the same thing, but they're not. Adaptability is the ability to keep existing behavior and then add more to it, whereas evolvability is the ability to fundamentally change over time, and this architecture supports both of those things very nicely.
So, the last two I want to talk about are the generic technical architectures, the Enterprise Service Bus-driven, service-oriented architecture, and the old-school SOA, we call this orchestration-driven SOA in our book. I'm not going to spend hardly any time at all on this, because this is mostly interesting from an historical state point now, but you'll notice the name of this talk is Architecture Styles and Patterns.
Now, while I spend most of my time talking about styles, I do want to touch on a few patterns and how those have changed philosophically over time. And this is a great example of one of those, because one of the interesting things about this architecture style, outside of the taxonomy and all the other complexity here, was part of the driver, part of the reason that architects choose this style was a heavy emphasis on shared resources. This is back when operating systems and databases and application servers, and every part of your ecosystem was commercial and expensive and needed to be shared. And this also penetrated into the way architects thought about solutions.
So, one of the things that you were instructed to do as an architect, or one of the assistants, let's say you're an insurance company and you have all these different divisions, Auto and Homeowners and Commercial and Casualty and Life and Disability. And you noticed at some point, “Hey, wait a minute. They all have some bit of customer inside them.” Part of what you were instructed to do in this world was to go, “Hey, I recognize that these are all part of one larger customer, so I should just create a single customer service and have all these others point to it.” And this certainly makes good sense from a sharing standpoint, because now I have a single source of truth for all the things that I know about the customer in my organization, but mostly what this is, is a misunderstanding of what the actual tradeoffs are.
Remember: everything in software architecture is a tradeoff and in fact, the first corollary to that law is that if you think you found something that isn't a tradeoff, it just means you haven't discovered the tradeoff yet. And a lot of organizations even now still believe that reuse is purely a force for good. It has no real negative tradeoffs, but turns out that's not true, because when you build an architecture around reuse like this, you get two big negative side effects.
One is everything is now coupled to everything else. So now if I make a change to customer service, that change ripples out to all different parts of my architecture, making everything very brittle. So, if I change one thing, I have no way of knowing what else may break.
But the other problem with this, it was really identified by domain driven design, is if I have to make one big customer service that knows everything about customers, it's going to be really complicated and anybody who deals with that is going to have to deal with the entire complexity of everything we know about customers. Almost all these divisions just need one little bit of customer and they don't want to have to deal with all the rest of it.
And this is really the philosophy that became known as micro services and domain driven design. So, we learned some important lessons in this architecture. The only reason you would choose the parts of this architecture now, like an enterprise service bus, are things like integration, and yes, I realize the slide says integration twice, because that's really the sweet spot for this architecture.
One last technical architecture style, and this was one that we did not even put in our book for reasons I'll get to in just a second, which is serverless. We don't actually believe this is an architecture style yet, we believe this is an architecture pattern. And now there are two different variations of serverless out in the world. There are actually three now, but I reject one of them as being invalid. You sometimes hear people say, “Well, I'm running my microservices. Kubernetes clusters are cloud and that's serverless.” That's not serverless. Your Kubernetes containers are your servers.
Real serverless is either backend as a service or functions as a service. And when serverless first came out, the whole backend as a service thing was a very popular option. The idea was if you take a traditional kind of client server, split with a browser some sort of functionality in the middle and a relational database, and then adopted back in as a service, basically what you do is find online services to do all the things you were doing before. So, a gateway to give you some sort of purchase function with something like a Lambda and then a search, there's a product database, like big data or something like that, or a Google table that you could use to store things in.
And so, it's basically piecing together a whole bunch of things that are online to be able to build a solution. One of the side effects of that is part of our functionality that used to live in the middle code there in the Pet Store Server probably moves up to the browser, any kind of integration where you can [inaudible] like that because that's really the only place you have a lot of ability to write code.
The other one of course is functions as a service. This is Amazon Lambda and Google Cloud Compute and all those other platforms. This basically allows you to write a code and have it deployed, and then automatically triggered by someone, you know, moving something into a bucket, or invoking some sort of event or something like that. So, serverless is very appealing, you know, right now, because it's this lack of infrastructure, somebody else's computer, somebody else's problem.
We don't believe it's a full-blown generic architecture style yet. We think it will eventually be one, but we don't think it's there yet because of this: something that we identified, actually a long time ago, in the evolutionary architecture book as the last 10% trap.
Many years ago, I used to work for a consulting company who built projects for clients in Microsoft Access, and we ended up shutting down that part of the business because we realized a common pattern where every Access project started as a booming success, but then ended in total failure. We wanted to understand why that kept happening, and we codified that as what we call the last 10% trap. So, if you look at all of what the user wants, are you using something like Access or serverless?
80% of what they want is super easy and fast. And it's amazing how fast you can get it done. Wow! Look, I've already got this running. It was prototype though. Up and running. That's awesome. The next 10% of what they want is possible, but difficult, because now you're trying to do something that doesn't really natively support, so an Access or all these things that you'd have to hack around and figure out how to do in a serverless, you know, if the startup time is too slow, then you [inaudible], ping this one to keep it alive, and you have to hack like that. The problem though, is the last 10% you need is impossible to get far enough underneath the tool or framework to get it to work, and it turns out users always want a hundred percent of what they want, and they're never satisfied with less than that.
I believe that it is Amazon and Google’s great interest to make this a full-blown architecture style, but I don't think it's there yet because there are still way too many limitations for building general purpose systems.
So, some of you may remember the four GLS. These fourth-generation languages were all the rage back in the late nineties and early two thousands. In fact, my first book was on one of these tools called Delphi. DBAs, FoxPro, Paradox, PowerBuilder; none of those tools really exist anymore, because they all suffered from the last 10% trap. Again, I think serverless will eventually become a full-blown style, but right now it's still a pattern for solving some problems, but not a general-purpose architecture style.
Okay, so we've got 10 minutes left. Modular monoliths, I've already talked about, this is the idea of partitioning things, from an architectural standpoint, around domains or workflows, rather than technical capabilities. This is obviously inspired by the domain driven design, by Eric Evans, just like microservices are, and this gives you many of the benefits that you get from microservices without a few of the distributed architecture headaches.
Many of the proponents of modular monoliths talk about, you know, the same kind of separation into domains and the same kind of a worker separation, call it inverse Conway Maneuver, that you get from separating things around domain, drive and technical capabilities.
If I were building a monolith today, this is almost certainly the kind I would build, because it's very easy now to move this over into something like microservices if I needed to go distributed. For example, if I were working in a startup and we really were trying to get to market as quickly and simply as possible, I might not have time to build a big fancy microservice architecture, but I can build one of these and then easily migrate that to microservices when the time comes.
That brings us, of course, to everyone's favorite cool kid architecture, microservices. I won’t spend a lot of time talking about this, because there are lots of sessions here at the conference this year about this. This is a very popular architecture style.
This is of course, a distributed architecture and the overwhelming philosophy here comes from domain driven design and this idea of a bounded context where each of these services is meant to be its own individual bounded context with its own data and very decoupled from everything else.
One of the biggest challenges in microservices is getting the right size and granularity, because you have to look at multiple features. One of your instincts as a developer is to crush it down as small as you can to single-purpose, but then there are other factors that make you bulk it back up, like transactional boundaries. If you're trying to define domains or workflows, transactional boundaries are a great way to identify those things. Also are you being forced to do too much choreography? In fact, that's really the weak point of microservices. You get really great scalability, but often not fantastic performance.
This is one of the common things that you have to address with microservices, because you're moving all this functionality from internal method calls out to networks. So, that's always going to be a lot slower when you do that. And so, too much choreography is also a driver to consolidate things back into services.
One of the mistakes developers make is trying to make these things arbitrarily small, and one of the pieces of advice from Martin Fowler is: “Remember, microservice is a label, not a description.” This is not an excuse to make things arbitrarily small, you're trying to capture things like that in context. One of the common ways that you address poor performance, I say poor, less than desired performance in microservices is by creating a hybrid architecture and using events.
Now, part of the philosophy in microservices is extreme decoupling. Now, which of the two event-driven architectures feature really extreme decoupling? The broker event driven architecture, so a really common combination you see is broker event and microservices, which gives you the scalability of microservices plus the data stuff, but also some of the performance and the synchronicity of events. So, the real drivers here, of course, are a very specific degree of modularity and even around things like data, which is where in any of these architectures to go to that degree of modularity, agility and the ability to make changes fast, really good at fault-tolerance, all these other operational concerns like scalability, really good testability, it grew up in the era when that was an important thing, along with deployability, and the ability to evolve, maybe the most evolvable architecture that we know of.
The last thing I'll talk about is service-based architecture. Service-based architecture is a hybrid, one that rather than go all the way to microservices, this is a more typical target for migrating from a monolith. So, the common differences between a microservice and a service-based architecture, the two main ones are here on the left.
One is service granularity. We don't try to go nearly as small from a granularity standpoint, but the main one is database scope. It's just too difficult to break apart a database, in many cases, if you're trying to untangle a monolith. And so, leaving it as a single database while breaking apart some of the services is common, but you also would like as much as possible to be able to utilize some of the 21st century engineering practices, like deployment pipelines and machine provisioning, etcetera.
This is very much a hybrid that tries to take advantage of architectural migrations as much as possible. I actually talked some about migrations in my evolutionary architecture workshop, which I'm doing this same time tomorrow. One of the ideas of evolution, of course, is the ability to do migration.
And this is what I was talking about before, the tradeoffs here. Typically, you get higher performance in a service-based architecture because you're doing less network stuff, but more complex because you have a much higher scope, of course. The database, of course, is the big headache here, and very often in service-based architecture you get much better performance, and it's very difficult, of course, to untangle the entire thing.
One last architecture I'll talk about, just as an interesting sidelight, space-based architecture, which is domain specific about scalability.
So, what happens if you run into this problem where you get too many users, so you build out all your web servers, but then it gets hammered, so you build out your app servers and then you build out your database and then you still get hammered?
There's a specialized architecture that was built years ago called a space-based architecture, and it uses these in-memory processing units and does eventual consistency at all of this virtualized middleware in the middle, these processing units is where things actually go on, but it also has this data replication engine built inside, and there's all this code that replicates data back and forth between these processing units. And so, this allows you to build systems that can handle 10,000 new concurrent users at once, for example, and all that virtualized middleware handles synchronization for all that data and reconciling it. And, of course, this is an individual consistency kind of environment, but it does allow to handle this really extreme bursting kind of traffic, either going through some sort of synchronization data writer or going directly to the database.
This can also fit in the cloud, of course. There are actually tools that do this, like Oracle Coherence, and this is really an interesting architecture if you’re really interested in super elasticity, but you can't get transactional behavior, which is a very common tradeoff here.
So, to wrap these things up: you’ve got to look at the shape of your problem, and if the architecture’s suitable for this. Microkernel is a good example, if you need customizability, that's a perfect architectural style. You can solve any problem using any one of these architectures. The question just becomes how difficult it is to solve that problem in that architecture.
It's really important to understand the philosophy behind that architecture, because almost none of them will appear in their pure form in the wild, and so you need to know when it's okay to cheat on that without breaking the underlying philosophy, and mostly what you'll see out in the world are not pure ones, but hybrids. This is more common than the pure ones.
But it's also important to distinguish patterns from tools, so mediator’s a pattern, but there are lots of tools that implement that. Understanding how the pattern works is really important, and then it's trivial to understand how the tools work.
Alright, that's it, and we finished with one minute left, so got that done just in time. There's actually a question here: If a customer is waiting for a request to be processed, how do you compare microservices?
Boy, you’re making a lot lot of crazy assumptions there, VJ! Microservices are not synchronous, they can be synchronous or asynchronous, and you always decide on a case by case basis if you want to be synchronous or asynchronous.
So, towards VJ’s question, one of the core things you have to decide in architecture, the first question is: Synchronous or asynchronous call? Then you have to decide what's the implementation. Am I going to do that? Because I can make a synchronous call or an asynchronous rest, but I can also do a synchronous call with events, or I can do an asynchronous call with events. And so, you have to understand why to do it first.
Um, another question here: Broker and mediator bit, orchestrator. One is scalable. What about functional scalability? So, functional scalability, the second one. Okay. So yes, there are always cases, specialized cases where one of these can be made to be more scalable than the other. I'm talking about in the general case here, less coupling yields more scalability. There are special cases where that's not true, but yeah, that's a special case.
So it's really important, Ashitosh, don't be binary when you think about architecture, everything is a tradeoff. And so, it's not really about one of them always being the best. It's always one set versus the other.
Can these architectures be mixed and matched? They're always mixed and matched. Now, you have to be careful. You can't really do layered and event-driven. I mean, you can, but you can gradually migrate toward a distributed architecture, but yeah, almost none of these are unified.
What are the best ways to maintain transactions in microservices? That question is worth a three-hour course all by itself. And in fact, I'm going to leave that someone else. I suggest you go to one of the microservices courses, which will probably spend about two hours on that question. I can't address it here because I'm out of time.
Thank you all very much for attending. I apologize for the technical difficulties, but thanks for the great questions and attention. Hope you enjoyed it. I'll be back at the end of the day today for you, but tomorrow morning for me.
And I hope you come for my evolutionary architecture workshop; we'll have some more time. I'll be able to answer some more questions and I'll show you some very cool tools that you probably did not know existed yet to help you automate architectural governance, which is something a lot of folks want to do now.
So, thanks very much for attending and have a great conference today, and I'll see you at the end of the day.
“Once again Wurreka has knocked it out of the park with interesting speakers, engaging content and challenging ideas. No jetlag fog at all, which counts for how interesting the whole thing was."
Cybersecurity Lead, PwC
“Very much looking forward to next year. I will be keeping my eye out for the date so I can make sure I lock it in my calendar"
Software Engineering Specialist, Intuit
“Best conference I have ever been to with lots of insights and information on next generation technologies and those that are the need of the hour."
Software Architect, GroupOn
“Happy to meet everyone who came from near and far. Glad to know you've discovered some great lessons here, and glad you joined us for all the discoveries great and small."
Scott Davis, Web Architect & Principal Engineer, ThoughtWorks
“What a buzz! The events have been instrumental in bringing the whole software community together. There has been something for everyone from developers to architects to business to vendors. Thanks everyone!"
Voltaire Yap, Global Events Manager, Oracle Corp.
“Wonderful set of conferences, well organized, fantastic speakers, and an amazingly interactive set of audience. Thanks for having me at the events!"
Dr. Venkat Subramaniam, Founder - Agile Developer Inc.