Posts With Tag: architecture

Abstract Style: Space-Based Architecture

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')

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

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

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')

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

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...

Architectural Styles - The Tailor-Made Pattern Language

In our previous post, we discussed how the business problems we tackle through software architecture seldom align perfectly with just eight sizes (the conventional architecture patterns). More often than not, any system’s architecture that adheres to a specific pattern tweaks it significantly. This deviation brings forth two critical challenges that the Tailor-Made approach seeks to resolve:

Firstly, the prevalent tendency to oversimplify diverse and distinct systems filled with numerous modifications leads to miscommunication and ambiguity in portraying the architecture’s intricacies. Secondly, relying on a pattern-based language holds value only if there’s a unanimous consensus regarding the pattern’s definition.

We have already shown that an architecture can essentially be defined by its constraints it is, consequently, imperative to embrace Dr. Roy Fielding’s notion of the “architectural style.” Such an adaptation ensures clearer pattern definitions and more transparent architectural communication. Moreover, it unlocks a vast spectrum of architectural styles, moving beyond the confines of the standard eight patterns.

Continue reading...

Eliciting Capabilities Deterministically - Design by Constraint

In the multifaceted world of software architecture, there’s a tantalizing allure to architectural patterns promising given set of capabilities. We, as architects, gravitate towards these seemingly well-structured models, hoping that by employing ‘Pattern X,’ our deployed system will exhibit ‘Capabilities A, B, and C.’ Yet, reality often paints a different picture. Despite our sincerest intentions and methodical adherence to models, these expected capabilities can prove elusive, leaving us pondering where and how the divergence occurred. This divergence isn’t just a hiccup in the grand scheme of system design; it’s an essential reminder that architectural blueprints, foundational as they are, often lack completeness. This fundamental disconnect was one of the major drivers for me to begin to formalize the Tailor-Made Architecture Model. In this post we will embark on an exploration of this inconsistency, striving to understand why deterministic results from architectural patterns can sometimes be more of a mirage than a milestone.

Continue reading...

Business-Driven Architectural Capabilities

Generally, when I am hiring for any technical position, I am less interested in what a candidate knows and more interested in how they think. This is doubly true when evaluating prospective architects. To this end, I’ll often directly ask “What is the best architecture?” A surprising amount the time, I get answers like “microservices.” In my experience, this type of answer often betrays a lack of architectural thinking. I won’t typically terminate the interview right then and there. I want to give them the benefit of the doubt as it is easy to misunderstand a question and it can be challenging to determine expected answers in the heat of an interview (especially arguably trick questions like this). I will always ask some follow-up questions as an opportunity to course-correct, but historically they haven’t and thus I have yet to hire someone after an answer like that.

Architecture doesn’t exist in a vacuum and we must avoid projecting our own biases and preferences into this type of work. We can’t have the architecture conversations without first having business conversations. Anything less is putting the cart before the horse, which is a formal architecture anti-pattern. In this post, we look at where architecture decisions come from, how to avoid common anti-patterns, and look at a process to begin to infer architectural capabilities from requirements and conversations with business stakeholders.

Continue reading...

Defining Architecture Capabilities

Some years ago, I sat in on a conference session hosted by Llewelyn Falco. In one timeboxed exercise, the class collaboratively wrote and iterated over a single line of code. Within about 10 minutes we had come up with several dozen ways to express that single line and, when time ran out, we weren’t slowing down we were speeding up. I left that experience with conviction that there are a near infinite number of ways to write code to implement a set of features. All implementations may provide equivalent functionality, but they don’t necessarily offer the same system capabilities.

In our previous post we discussed how architecture is focused on the capabilities of a system beyond its features and functions. As architects, it’s our job to carefully and mindfully constrain the degrees of freedom on code with the goal of having the desired set of capabilities emerge. But what are the capabilities? In this post we will explore and define various architectural characteristics.

Continue reading...

Becoming an Architect

I’ve spent the better part of the past year developing a formal model, process, and distilling a way of thinking about software architecture. The result is an approach I’m calling Tailor Made Architecture. This is the first post in a long series to explore these ideas. If this topic is of interest to you, note that this blog has an atom feed to subscribe to updates. Check out my speaker website for speaking dates where I will be covering this topic. Also, if these ideas resonate and you’d like to participate in an immersive, hands-on, three-day workshop; I’ll be giving the next workshop in Dallas, TX November 13-15. Early-bird discounts are available through October 13th.

Continue reading...

Content Negotiation - A REST Superpower

REST is the architecture of the web and the web has seen unprecedented growth and evolution since its inception over 30 years ago. A web of static documents gave rise to the read/write web–the so-called web 2.0. New media types and formats have evolved, protocols have become more powerful and more secure. In short, the web has only grown bigger in scale, more powerful in terms of capabilities, and continues to evolve. The human web is a marvel of software engineering and its longevity is a testament to the vision its founders and architects. Unlike much of the software I use today, I have never opened a web browser to a message that the back-end of the web has undergone a breaking change and I would need to download new software before continuing.

At some point in the first decade of the 21st century the web crossed an inflection point; machine-to-machine API calls eclipsed human traffic on the web. Many of these APIs have been labeled REST APIs despite many–perhaps even most–of these APIs fail to exhibit the qualities elicited by truly following the REST architectural style. Consequently, the machine web consists of a lot of brittle integrations that require countless person-hours to craft and maintain. To be clear, I’m not here to get on my soapbox about how all these sinners are “doing REST wrong”; I really don’t care. Not every API needs to–or should–be a REST API. The REST architectural style is a very specific tool to solve specific problems.

“Some architectural styles are often portrayed as “silver bullet” solutions for all forms of software. However, a good designer should select a style that matches the needs of a particular problem being solved.” -Dr Roy Fielding Architectural Styles and the Design of Network Based Architectures

Fundamentally I want to talk about some of the overlooked aspects of this architectural style and how they can be implemented to eliminate problems with versioning, evolution, and flexibility. Today we’re focusing on content negotiation.

Continue reading...

Building a Modular Monolith Part I

Ask most developers these days “Which is better: Monolith or Microservices?” you will likely receive a prompt and definitive “Microservices. Hands down.” The term monolith has become a pejorative; a four-letter word in 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. Many (perhaps most) non-trivial monoliths in the wild today could be classified as a Big Ball of Mud. I submit that most criticisms of monolithic software architecture would be more accurately targeted at Ball of Mud architectures. A monolithic deployment granularity doesn’t necessarily presage a Ball of Mud and furthermore, adopting a distributed architecture (such as microservices) does not automatically inoculate a system against evolving into a Ball of Mud.

Continue reading...

What is Rest

This question, it would seem, has been answered countless times on countless blogs, articles, conference talks, papers, etc. yet here I am, joining the throng to tilt at this windmill.

My understanding of REST has been evolving continuously over the past 15+ years. I continue to find new nuances, new applications, new patterns, and rediscover concepts that I once completely misunderstood. I have brilliant friends and mentors, but I’m an autodidact at heart and more often than not, they merely illuminate the path. As I’ve sought to navigate this life and the information space we call the web, I have learned being self-taught is fraught with peril.

The web is full of contradictions.

Continue reading...
{"cc_re__cc_re__cc_by_sa_4_0": ["             <li property=\"keywords\" content=\"web\"><a href=\"https://sufficiently-advanced.technology/tag/web\">#web</a></li>\r\n                \r\n                    \r\n                    <li property=\"keywords\" content=\"architecture\"><a href=\"https://sufficiently-advanced.technology/tag/architecture\">#architecture</a></li>\r\n                \r\n            </ul>\r\n        \r\n        \r\n    </div>\r\n\r\n    \r\n</article>\r\n        \r\n    \r\n</section>\r\n        </main>\r\n        <footer class=\"site-footer\">\r\n    <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\">\r\n    <img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-sa/4.0/88x31.png\"></a>\r\n    <br>\r\n    <span property=\"http://purl.org/dc/terms/title\">\r\n            sufficiently-advanced.technology\r\n    </span> by <a href=\"https://magician.codes\" property=\"http://creativecommons.org/ns#attributionName\" rel=\"http://creativecommons.org/ns#attributionURL\" resource=\"https://w3id.org/people/michael\">Michael Carducci</a> is licensed under a <a rel=\"license\" href", "licenses/by-sa/4.0/\">\r\n    <img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-sa/4.0/88x31.png\"></a>\r\n    <br>\r\n    <span property=\"http://purl.org/dc/terms/title\">\r\n            sufficiently-advanced.technology\r\n    </span> by <a href=\"https://magician.codes\" property=\"http://creativecommons.org/ns#attributionName\" rel=\"http://creativecommons.org/ns#attributionURL\" resource=\"https://w3id.org/people/michael\">Michael Carducci</a> is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\">Creative Commons Attribution-ShareAlike 4.0 International License</a>.<br>Based on a work at <a href=\"https://sufficiently-advanced.technology\" rel=\"http://purl.org/dc/terms/source\">https://sufficiently-advanced.technology</a>.\r\n</footer>\r\n        \r\n        \r\n        \r\n        <script src=https://sufficiently-advanced.technology/assets/js/simple-jekyll-search.min.js></script>\r\n<script src=https://sufficiently-advanced.technology/assets/js/theme-changer.js></script>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<script>\r\n    S"], "copyright__copyright__copyright": ["", ""]}