Posts With Tag: abstract-style

Abstract Style: Space-Based Architecture

Drawn/blueprint-style illustration of the space-based architecture pattern.

Many developers strive for elegance efficiency in their code. Imagine a hypothetical developer who takes this too far. Perhaps this developer looks back in shame at the sloppy, inefficient implementations their much less experienced self had written. They were, undoubtedly and objectively, “bad.” Over time, their code grew cleaner and more efficient. They could measure progress in wall-clock time, algorithmic complexity, or other quality metrics. Somewhere, however, the pendulum swung too far. If their “bad” code was slow, and their “better” code is faster, it stands to reason that even faster is even better. They reached a point where they would squeeze out every spare microsecond at all costs. The result was difficult to read, change, and understand; perhaps “the juice was not worth the squeeze.”

Performance can be a valuable system capability, but only in context. Remember the “Mad Potter’s” wisdom on the difference between “a lot” and “enough.” Architecture trade-offs must be considered in many dimensional contexts. Never trade an excess of one capability for a deficit of a more important capability. That said, sometimes performance is among that short-list of business-critical capabilities–perhaps at the very top. What constraints induce high-performance at the architectural level? Read on to learn about the Space-Based Architecture.

Continue reading...

Abstract Style: Service-Based (a.k.a. 'miniservices')

Drawn/blueprint-style illustration of the service-based architecture pattern.

In our previous post we looked at a technically partitioned, coarse-grained, distributed architecture. Although that pattern balances capabilities like scalability and elasticity with low cost and simplicity, a domain-partitioned architecture may offer many advantages. For an organization with well-defined domains and domain-aligned teams, this next pattern offers a very balanced and pragmatic distributed architecture that offers comparable capabilities to an architecture like microservices at a fraction of the cost and complexity. In short, a Service-Based architecture offers a highly viable “middle-ground” between monoliths/n-tier architecture and microservices. This architecture can act as a stepping stone between monoliths and more complex topologies although often it will represent an acceptable and desirable end-state for green-field and legacy systems alike. Read on to learn about the Service-Based Architecture

Continue reading...

Abstract Style: N-Tier

Drawn/blueprint-style illustration of the n-tier architecture pattern.

So far in this series on abstract styles we have only looked at monolithic abstract styles and a handful of defining constraints. In reality, however, much–in not most–of the systems we will design as architects will involve some kind of network component. Although many implementations of the layered monolith or modular monolith may be extended through the addition of the client-server constraint (and, typically, some type of API constraint) the next several posts will focus on abstract styles that are, at their core, natively distributed. We will start by examining the N-tier architecture.

Continue reading...

Abstract Style: Microkernel

Drawn/blueprint-style illustration of the microkernel architecture pattern.

Agility is a term that is typically poorly-defined–and often overloaded–in many business circles. Yet the underlying capability remains highly sought-after. Agility can be broadly defined as the ability of the business to adapt and respond to change. Agility is desirable because change is inevitable, and comes in a number of forms. With the progression of technology, from digital computers to personal computers, to the internet, to the web, to the mobile web, and beyond; the rate of change is only increasing. Businesses unable to keep pace will be disrupted, and we see this almost daily. We also cannot escape the fact that software runs almost every business. While there is a near infinite number of ways to write code to ship a set of features, software systems that are rigid and difficult to change will continue to constrain business agility. In short, if our software is not agile, the businesses it powers won’t be either.

As we have discussed in previous posts in this series, conventional wisdom is that monolithic architectures might offer low cost and high simplicity, but aren’t capable of meaningful agility. Through careful combination of key architectural constraints, however, architecture can yield monolithic systems that balance agility and simplicity. The goal of architecture is not to provide “a lot” (undefinable) of a given capability, but a minimum of “enough” (driven by business needs). To this end, we introduce another abstract architectural style, the Microkernel Architecture Pattern.

Continue reading...

Abstract Style: Modular Monolith (a.k.a. 'Vertical Slice Architecture')

Drawn/blueprint-style illustration of the modular monolith architecture pattern.

When many developers these days are asked “Which is better: Monolith or Microservices?” The answer is often a resounding ‘Microservices!’ The term monolith has become a pejorative; a veritable four-letter word in some software architecture circles. The folk-wisdom criticisms are not entirely undeserved, after all there are a lot of bad monoliths out there; unmaintainable, untestable, brittle to the point of personifying a Jenga tower of code. Yes, the microservices pattern offers many strengths. Yes, the layered monolith carries many weaknesses. However, that’s not the end of the story. As we have learned so far in this series, capabilities like testability, maintainability, evolvability, etc. don’t originate from deployment granularity but instead emerge from architectural constraints.

What might the humble monolith look like if an architect applied some of the constraints that give microservices their magic? Meet the Modular Monolith.

Continue reading...

Abstract Style: Layered Monolith

Drawn/blueprint-style illustration of the layered monolith architecture pattern.

Patterns have become indispensable tools in software development.. Patterns can provide a high-bandwidth mechanism for communicating ideas, however as our industry has noted (and we explored in-depth in our previous post) application of architecture patterns rarely yield a consistent set of outcomes for any given project. A powerful solution is to apply the idea of design-by-constraint. This resolves the prevalent semantic ambiguities of our current architecture pattern set and enables a more reliable and deterministic means of inducing architectural capabilities in systems.

In the dynamic world of software architecture, be it for buildings or software, two dominant philosophies emerge. The first imagines a designer starting from scratch–a void on a whiteboard–and begins meticulously crafting an architecture, piece by piece, with familiar components until it embodies the system’s aspirations. The alternative perspective envisions a designer commencing with an all-encompassing view of the system’s requirements, unshackled by constraints. As the design evolves, constraints are strategically imposed on system elements, fine-tuning the design canvas and allowing the forces that mold system behavior to move fluidly, in perfect sync with the system’s essence. While the former accentuates unbridled creativity, the latter champions understanding and discernment within the system’s milieu. It’s this latter philosophy that the Tailor-Made Software Architecture reveres, focusing on constraints as composable design elements to both precisely define our architectures and also enable fine-grained control of the capabilities and characteristics the architecture elicits. Architectural constraints possess a high-degree of reusability and they can typically be applied to almost any pattern or candidate architecture. For the next several posts, we will define the eight common patterns in terms of their core constraints, potential optional constraints, and highlight how the composition of these constraints results in a predictable set of architectural capabilities. We begin with the humble layered monolith.

Continue reading...