Chapter 3. Deconstruction and Design

Perhaps something has occurred in the history of the concept of structure that could be called an “event,” if this loaded word did not entail a meaning which it is precisely the function of structural—structuralist—thought to reduce or suspect...

Jacques Derrida, “Structure, Sign, and Play in the Discourse of the Human Sciences”

Introduction to Deconstruction

This section might appear “out there,” marginal, even inconsequential, as some distracting oddity in a book on software design. It could feel external to our purpose, irrelevant, too unfamiliar, discomforting.

This section serves as critical context for the practical tools and strategies you will learn in Parts II and III of this text. Is this section the marginalia, or is it the thing itself?

***

Cut To:

INT. A CONFERENCE BALLROOM AT JOHNS HOPKINS UNIVERSITY, BALTIMORE, MARYLAND, US, 1966 — NIGHT

The Scene: A conference for philosophy professors titled “The Language of Criticism and the Sciences of Man.”

Action!

Enter French philosopher JACQUES DERRIDA. He is 36, French-Algerian, soft-spoken, dressed in a suit rumpled from his recent travel from Paris. He steps to the podium to deliver his paper. He takes a sip of water. He speaks.

DERRIDA

(quietly)
Perhaps something has occurred in the history of the concept of structure that could be called an “event,” if this loaded word did not entail a meaning which it is precisely the function of structural—structuralist—thought to reduce or to suspect...

As he continues, the room falls hushed. Then nervous. Then angry. Then astonished. His talk is called “Structure, Sign, and Play in the Discourse of the Human Sciences.” After he delivers it, the attendees retire to a chamber to smoke and argue into the early hours of the next morning on its implications.

This paper would mark an origin of change, and advance, in the course of philosophy and the humanities for the next several decades. It is an astonishing piece of writing, and an incredibly erudite, fiery blast to his audience of assembled philosophy professors who, like those at the 1968 NATO conference, were searching for the path forward in their field.

Derrida had been invited to speak with the supposition that his work would elaborate and help popularize the idea of structuralism. Instead, he devoted his argument to illustrating how philosophers can only talk in the language they inherit, and that as a result, their concepts are limited: they rely on the patterns of previously established metaphysics and base their arguments on it, even as they denounce it. He exposed how the central theses and propositions of the structuralist philosophical endeavor were in contradiction and how, as a result, their field was in stasis.

Derrida gave this paper at a conference intended to promote structuralism, and in a sense, in a single evening, it ended the field. It is widely cited as the precipitating event, the rupture, that ignited post-structuralism in the United States, introducing new ways of thinking about writing, feminism, language, epistemology, ontology, aesthetics, social construction, ideology, and political theory, across philosophy, sociology, political science, the arts, and the humanities.

The Paper

You can read “Structure, Sign, and Play” here in English translation. I highly encourage it. It’s a (very) tough piece of writing, in part because the writing is performative. That is, the writing exhibits an acting out of the circling argument that Derrida is making. It is, purposefully, a triumph of structure.

In “Structure, Sign, and Play,” Derrida begins with the idea that in an argument or analysis, terms (signs) are defined purely in relation to one another. Put simply, we only can conceive of “good” in relation to “bad,” or “success” in relation to “failure,” along a spectrum of nuance and differing meaning in contexts. Such structuralist systems thereby allow “play” in their terms because meaning is deferred; in a sense, the can is kicked down the road from one sign to another such that establishing a fixed and firm meaning in a sign is problematic because of this play.

The crux of Derrida’s position is this: throughout the history of structuralist thought, we have relied on some anchoring center. This center is the term, sign, or idea that appears as fixed, immutable, assumed, given: metaphysical. As such, it is beyond the system of play that all the other signs operate within; it is incontrovertible, assumed and therefore unexamined, not held to the same standard or afforded the same interpretations. It is not subject to the same terms of the established system and as such is outside the system. “The center,” he therefore concludes, “is not the center.”

Derrida’s philosophy, introduced in this talk and subsequently outlined in dozens of books across his formidable career, especially his key work Of Grammatology, is called deconstruction.

Deconstruction in Popular Culture

This is probably a term you’ve heard in popular culture, where it is typically misunderstood, diluted, misused. There’s a movie, Deconstructing Harry. It is a term Derrida employed to mean destroy and create from within, at once. Before his death, he evolved this idea of deconstruction over decades in dozens of books. He was incredibly smart and learned, and his ideas are very complex, and are in no way intended for the layperson. Our aim here is to take up, in the manner of a bricoleur, the bits and pieces of these ideas available to us and apply them as tools to illuminate our endeavors in software design.

Derrida argues that when we examine semantic structure via deconstruction, we see that the structure of meaning rests upon a series of binary oppositions, sets of pairs that are opposed to each other in meaning, and from which they respectively derive their meaning. Such pairs, as we can see even in our loose conversation in our daily lives, might be good/bad, good/evil, presence/absence, speech/writing, man/beast, God/man, man/woman, being/nothingness, normal/abnormal, sane/insane, healing/hurting, primary/secondary, civilized/uncivilized or “savage,” theory/practice, and so forth.

Binary Oppositions

The idea of binary oppositions is important to understand in semantic software design. You can read more about it here.

Assigning fixed meaning requires that we privilege one of the terms in a pair of binary oppositions that unwittingly are held up as unquestionable, beyond reproach. Derrida argues that the history of structuralism is the history of mere substitutions of one honored and indisputable center for another, whether the central idea is “God” or “Being” or “Man” or “presence.” His point is that there is a contradiction inherent in structuralism such that it is rendered incoherent.

So what does all this mean in practice? The deconstructionist move is as follows:

  1. Read the argument closely and carefully. For us, this means we consider our understanding of the domain, the semantic field, closely and carefully.

  2. Find the sets of binary pairs that form the structure of the concept as given.

  3. Determine which term in the binary pair the author privileges above the other.

  4. This can lead us to the assumed anchoring center that escapes challenge and makes possible the rest of the discourse in which the terms can abound in meaning.

  5. Expose this contradiction and overturn the binary oppositions such that the argument unravels and a new concept is created that properly can incorporate the terms in the system without the prior inconsistency and false privileging. It does this in a way that does not glibly reduce to “everything is everything,” but rather marks the undecideability and interplay of the terms.

It’s a Process

Pay careful attention to understand this method insofar as it’s presented here. Deconstruction provides a critical means for gaining a true understanding for how a system operates, especially a system derived from a concept that is purely logical and linguistic, as any particular software system is. In this way, a method of deconstruction is a critical tool in better system design. These few steps in deconstruction represent a key, one might say “central,” element in semantic software design as it unfolds throughout this book. We’ll see how to apply it practically. For now, just don’t lose this term.

In this talk, Derrida revealed the problems philosophy had at its core, how its internal contradictions abounded in ways that could no longer be ignored.

He closes his paper with the following:

Here there is a sort of question, call it historical, of which we are only glimpsing today the conception, the formation, the gestation, the labor. I employ these words, I admit, with a glance toward the business of childbearing—but also with a glance toward those who, in a company from which I do not exclude myself, turn their eyes away in the face of the as-yet unnameable which is proclaiming itself and which can do so, as is necessary whenever a birth is in the offing, only under the species of the non-species, in the formless, mute, infant, and terrifying form of monstrosity.

It’s interesting to note that building architecture, our sometime progenitor, has an entire school of deconstructionists who are among the best in their field. Included on this illustrious list are the Pritzker Prize–winning Zaha Hadid, whose opera houses, bridges, and cultural centers are among the most brilliant works of her generation; the Pritzker Prize–winning Rem Koolhaas, who has designed museums and Prada stores around the world while also holding a position as an architecture professor at Harvard; Frank Gehry, the architect of the practically perfect Disney Concert Hall; and Daniel Libeskind, whose work includes the very moving Jewish Museum in Berlin.

The power of deconstruction in philosophy over the years caused it to reach into farther-flung realms, including cuisine: the deconstructed Caesar salad introduced in California in the 1990s owes its existence to Derrida and his philosophy of deconstruction.

What does this have to do with software? Everything, in fact. Certainly as much as buildings and towns do.

After you define your concept and your semantic field, deconstruct it yourself in an analytical move to expose the inadvertent bad arguments and misunderstandings and contradictions and privileges introduced into the system. This is the step in which you really improve it for better flexibility, more accurate representation of the world, better resilience, scale, and more.

If it’s not at all clear how exactly this is the case, not to worry. This is just an introduction and we explore further what it means and how it works in the coming chapters.

Simplexity

We often are told, and sometimes cling to, the slogan to make systems simple. We hear, “Keep It Simple.” We “know” that good design is simple. This is not the case. Or rather, while this statement passes for an idea, it isn’t one.

The engine of a typical E-class Mercedes-Benz has three times as many parts than a typical Honda Accord. Which is the better engine? There’s one answer if you want to go 180 mph. What are you hoping for from the car? Access to a greater number of mechanics with fewer specialized skills might be a design goal. That offers a different answer.

Is Google search “simple”? For the end user, amazingly so. It’s estimated that Google contains two billion lines of code, or roughly 40 times the size of Microsoft Windows, estimated at 50 million lines.1 This of course begs the question, What part of Google is “search,” when it’s used in web searches, Maps, Gmail, and many other products? Or is it more complex than that?

Your intent must not be a facile “simplicity.” Nor can it be to design for its own sake. Nor, obviously, to overengineer because complexity is fun or because we’re building our resumé, or we don’t know when to stop or what we’re designing or for whom.

We create accidental complexity when we focus improperly on simplicity.

Fred Brooks is the famous architect and manager of the IBM System/360, and the author of the book The Mythical Man Month in the 1970s. He thought to write it after his exit interview from IBM in which Thomas J. Watson asked him why it was so much harder to manage software projects than hardware projects. In his paper “No Silver Bullet,” Brooks outlines two types of complexity:

Essential complexity

This is the complexity inherent in the design problem. It cannot be reduced.

Accidental complexity

This is the kind of complexity that is created by the developers themselves. It does not inhere in the concept itself. It is due to weak design, poor coding quality, or inattention to the problem.

Counterintuitively perhaps (and certainly counter to recent received ideas), your intent should be to embrace the complexity of the many users of different kinds with different needs. These include the many competing concerns of audit, attestation, accounting, the timeline, the budget, and so forth.

Right-size the complexity of your concepts according to the job.

More important, never mistake accidental, or potential complexity, for essential complexity.

(De)composition

The problem is not getting cool air to the engine, it’s getting the hot air away.

Dr. Ferry Porsche

When we go to design a software system for a Human Resources (HR) department to use, we ask what matters an HR department is concerned with. We decide they are concerned with humans: after all, it’s in the name.

But, alas, they are not.

There are many humans that are not accounted for in an HR database—most of them, in fact. So we decide to cast the lasso that will demarcate our field, our ground, a bit more modestly. So we say: let an Employee (the kind of human the system is about) be a thing that exists in this world.

We quickly ascribe attributes to this class. We then consider what assumptions we have made, what we have left out. We realize there may be reasons to keep records of contractors who work for the company, but are not employees. So we must add an accounting for them, and their employers. Now we have extended the idea, and also realize we have room for some consolidation, because even though employees and contractors are different, they share many attributes that matter for these purposes.

So we say that a person exists, to hold these shared attributes, since both, for now at least until the robots come, are people. And so forth.

The point is not to review basic object-oriented analysis, an understanding of which is assumed. The point is to illustrate how this process might go well, how it might go wrong, and how we do best to quickly search out the boundaries of our field, the horizon beyond which we will not step, because that’s where the ambiguities are found.

The second we cast any figure into the field, we ask what assumptions we’re making.

To avoid oversimplifying, or early simplifying, both of which lead to accidental complexity or overengineering and poor design, is to understand the essence of a thing.

You do this by looking at the universe first and then zooming into your problem space. Then, after you have posited some figures onto the field, stop and zoom out further again, to ask what you might be assuming.

Focusing on making something simple will create unwanted complexity later.

Embracing complexity now will allow you to organize your work properly. The organization here is to reveal what functional, integral subsystems can work together to create the complete functional system (see Figure 3-1).

Figure 3-1. Decomposition (source: Wikipedia)

If you start from “simple,” you will end up tacking things on to handle the burgeoning, competing concerns. This will create a design with less integrity and harmony and internal consistency.

Instead, start with the universe, and then narrow down subsystems.

With practice you can do this quickly, and then almost intuitively as a matter of course, so it doesn’t take as long as it sounds.

If we think our problem is how to get cool air into the engine, we have made many assumptions, and started too late in the problem space. The problem is not that; it is how to keep the engine cool enough to function properly. These may casually sound the same, but they are entirely different.

These assumptions invite nonessential elements. They add unnecessary complexity to the design.

You might ask how to give more horsepower to a big engine that is already very powerful. That is a failure of analysis. Instead, ask whether the real problem is not that you want the car to go faster.

Look for the nonobvious places to start. We must take time to separate the categories of the problem space properly or assign relations properly.

To make a car go faster, increasing horsepower is an obvious place to start.

A Maserati Granturismo has a very large 4.7 liter V8 engine, which is made in partnership with Ferrari, at 454 horsepower. By contrast, the Lotus Evora 400 has a relatively modest 3.5 liter V6 engine made by Toyota, with only 400 horsepower. Which is the faster car?

Lotus did not ask how to make a bigger engine. They took a different view. Instead of focusing on changing the engine (the “figure”), as would be obvious, they turned their attention to the body (the “ground”). They threw out weight.

The Maserati weights 4,400 pounds. It needs that horsepower. The Lotus Evora weighs only 2,700 pounds. To the Evora, they added a supercharger that compresses air to make a bigger explosion in the same size engine. As a result both cars share the same top speed of 190 mph.

These are not trade-offs: these are design decisions.

First you are designing the concept, then designing the factory for making those concepts. The rest of the book is about how you create this concept realization factory. Then, the developers in the framework of your architecture go on within in it to make the thing.

It’s no longer all about horsepower, but more ideas per horsepower.

Porsche

Affordance

Years ago when I was living very briefly with a stockbroker who had a very good cellar I asked him how I could learn about wine. “Drink it,” he said.

Jeanette Winterson, Art [Objects]

The way you address ease of use is by considering affordance.

Norman doors got their name from the lovely book The Design of Everyday Things by Donald Norman. In the book, he recounts the design of a particular door he encountered: it had a handle on it, as doors do. But the way it was designed and installed meant it had to be pushed to open it. This is counterintuitive, and makes the door difficult to use. People see a handle and naturally pull, and their efforts to enter are thwarted, albeit temporarily. But the frustration is real and unnecessary. The handle, by its presence, affords pulling. It all but asks to be pulled. Pushing is not why we make handles. This is bad design and must be avoided.

We must ask in our empathy what the most intuitive thing would be, to a wide array of diverse people, with a wide array of aims, and design for what best affords, or suggests, how to use our system in the way they will want to.

This idea can be extended to include more: the keys of many cars today are electric and battery-operated. But the battery failing in the key should not mean you can’t open your car. Then what is otherwise a very expensive and nonnecessary “convenience” becomes a nightmare of the tail wagging the dog: the key is supposed to serve the car. So these keys have a backup key: a small metal one inside the electric one that work when the battery fails.

Do not make two equally obvious ways to accomplish the goal. Make one obvious path and make the backup at once hidden and accessible.

You must also consider how you can afford from different perspectives.

Porsche has a rich heritage in track racing, and has won the Le Mans race more than any other manufacturer: 18 times to date. It used to be that drivers at Le Mans did not start in their cars: when the flag went down, they would sprint to their cars, get in, turn it on, and go. So the designers at Porsche realized that by placing the starter on the left of the steering wheel instead of the right, the driver could parallel process, by turning the ignition on with his left hand while getting into gear with his right hand. In a race like this, shaving off a few extra milliseconds matters. So to this day, even with the keys powered by Bluetooth and even with no racing requirements for the family getting into an SUV, every Porsche has its key on the left of the wheel.

Tying to their racing and design heritage and sense of tradition is important to Porsche owners, and this subtle reminder affords a desired pleasure and connection, even if it is silly or inconvenient for the 90% of people who are right-handed and are used to it being on the right side of the wheel like every other car in the world. It’s a good design—from that perspective.

Give Intention and Use Value to Negative Space

Architecture is the thoughtful making of space.

Louis Kahn

Whenever you make space, you are making two things: the space demarcated within the boundary, and the place outside it.

We demarcate a field in the raw space of thought. We then assert objects into this field, and pay them considerable attention. These are the systems we make, the applications, the databases, the products. We fret over the usability, the vendor, the cost, the performance, the maintainability, the ease of use of these objects. Much wringing of hands ensues. We are obsessed with the objects—the figures—that we assert.

But what of the negative space? The negative space is the field, or the ground, that which is not our asserted object, but the place in which it can obtain ontological status, appear on the horizon, come into existence. 

The white chalk letters we draw on a blackboard are our figure, the blackboard is the ground. The charcoal letters we inscribe on brown butcher paper are the figure, the paper is the ground. The software is the figure. But what is its space?

We might say it is the infrastructure on which it can run. But is that not software? We might say it is the hardware, and software makers “abstract” this into a field—a public or private cloud—that we fancy simply exists. We don’t have to bring it into existence. It is not part of the application. It is a supplement.

Similarly, we abstract away the “business.” We narrow our scope to make our figure workable. We find binary oppositions (here/there, now/then, inside/outside) and assign one the status of priority.

You have likely encountered the image shown Figure 3-2 before.

Figure 3-2. Is it a vase, or two faces, or both? (Source: Wikipedia)

Figure-Ground theory states that the space that results from placing figures onto a place (asserting them into the field) should be as carefully considered as the figures themselves.

When you design, do not focus only on the figures, but look also to the ground. What negative space are you creating?

We first must create negative space because in software there is no “situation,” no necessary context. We can outsource its creation, we can buy it, we can license it; at the outset we aren’t sure what it will do or where it will run or exactly whom it will serve or how it will be used.

We create the negative space, the ground, every bit as much as we create the figure.

Our designs suffer, and our users suffer, when we do not recognize this. Because when we do not recognize it, we do not approach the design as purposively, as holistically, as intentionally, as thoughtfully.

The unattended space between the figure and the ground creates a zone of ambiguity, a tension, which, left unattended, creates an avenue of entry for uncertainty, uncoordination, chaos.

To improve the efficacy of the system, we recognize and closely observe the boundaries of the system, and attend to them with the same care we do our cherished figures. We must do this because by demarcating the field in the first place, as we must, we have invented that boundary, too. It is figure, too.

The Japanese word for this is “ma,” meaning the space or pause between two structural elements, not created by the elements themselves, but in the perception of the human observer.

In a linguistic and conceptual failure, there is no corresponding word in English.

How can you give that negative space, the ground, an intention? How can you find for it a use value? How can it be incorporated so that there are not stars and extras, not masters and servants, not text and margins, not real and other?

The Cassandra distributed database has no masters and no servants. Each node is equal.

The Infrastructure as Code pattern inverts the old paradigm, and affords a way to version entire datacenters, allowing a rollback to a last known good state that is truly known, complete.

Zoom in, to contemplate the design of a single component of your application system, and recognize that now what was figure (the whole application) becomes ground, and that component must work within that ground, that field. And recognizing the haziness at the boundaries where the figure meets the field, find every opportunity to invert the logic, placing it outside.

The Eclipse IDE is the IDE for “everything and nothing.” It is an IDE for making IDEs, and the Java assemblage just happens to be the first one, but it supports many other languages and tools through its empty space and its foregrounding of interfaces.

Make your software pan-pluggable, focus your work on the interfaces, the boundaries, making as few assumptions as possible about the business logic of the implementation. Do not make the application you’re told to make. Make the frame on which it could be hung, as one route the data will take on its circulating journey through the world. Do not simply implement the requirements as given—not to ignore or devalue them, but to serve and realize them better. Instead, make a space where those requirements could spring to life. Then the implementation can be injected from the outside. Because we know that we don’t know how things will change, what new constraints and possibilities will be introduced. Foreground the field, and make it the figure of your work.

The design that contemplates and sets in harmony the business, the application, the data, and the infrastructure is effective. The designer is effective when they recognize that during discovery, the executives are the users of the design, as they contemplate its budget and timeline and purpose and constraints; the developers are the users as they build it; the customers are the users as they wish it to disappear to gain the true value that lies behind it; and the monitors and maintainers are its subsequent users, who must navigate their way through consoles, documentation, tests, and code to find their avenue in.

What we assign to the margins, to the boundaries, to the field, will always leave its trace in the figure. Eventually, these traces will upend the figure. Perhaps nothing is destroyed entirely from the outside.

Give Design Decisions at Least Two Justifications

A stair is used for going up. And down. And also for congregating. Also for eavesdropping, for sitting, for enjoying the beauty of a grandeur, for showcasing adornment.

The quad at a university serves in organizing the buildings, studying, relaxing, meeting, playing Frisbee, graduations, protesting.

A theater is used for concerts, play productions, readings, assemblies.

We cook in a kitchen; we also gather, converse, prepare to leave, and eat.

Try to arrange the components of your design such that each has only one stated responsibility. But allow multiple “witnesses” standing to vouch for the component’s justification for being in the system at all.

Do this, and you’ll be able to get the most out of your components, maintain the “simplexity” of the system to best balance between what should be simple for the user and what is complex about the world, and see your best ideas win.

In software terms, you might envision a system that acts as a lookup registry to support service discovery. This system shields your application code from complexities of locating the right partition or shard where data is stored for geographically situated customers. You have data for Europe in Paris and data for APAC in Tokyo, but you don’t want developers to have to know about or manage repeatedly finding the right database for the current runtime customer when what they want to be able to do is to just invoke the shopping function.

You might create an abstract “resource name” that knows how to find the appropriate database given the customer ID. Considering this as the service registry, it does only one thing and does it well: it maps the abstract service name to the proper location and metadata to create a connection. That’s maintaining high cohesion, and the optimizations you make for your lookups will be inherited throughout the system, and the management of the cache and offload to resource bundles can all work the same. That’s a worthy service.

But you can also consider that if you properly structure the resource names, this same system allows you to deploy multiple copies of your software in particular datacenters around the world, or allows one of the copies to span multiple datacenters, affording greater resilience.

So inserting that resource name has given you two justifications, though it performs its singular purpose very well.

By focusing on interfaces, which capture the idea and not the implementation, by focusing on factories, which embrace the result and not the means, your work will invite multiple justifications for utility while maintaining the sturdiness of its frame. You make your system fit to purpose when you contemplate many purposes while designing still for high cohesion. This is one hallmark of platforms, and truly usable and extensible systems, which are the ones that endure.

You know that you don’t know all the uses. Your extreme users will find new ones. Embrace your extreme users.

Design from Multiple Perspectives

Think of your software as a three-dimensional object.

Do not design the entire application and then the entire infrastructure and then the entire data model. These are three subsystems, but consider the entire system at once, as well.

The data scientist might be concerned with choosing the proper neural network algorithm, but if the infrastructure architecture is not concomitantly thought of, you might miss a GPU-based server that would perform better.

Design it in “section,” which to building architects means seeing the whole thing from the side top to bottom with the fourth wall cut out so you’re seeing it from the side.

Then separately consider the floor plan, which is the view from the top with the roof cut out. Looking after only the floor plan might result in an undifferentiated box.

Design from multiple perspectives: a little section, then a little floor plan. Design from the view of the entire site, then do a detailed design of a specific minor detail in a corner, or a piece of furniture. Zoom in, and zoom out, and back again, repeatedly.

Consider how the software change would affect the organization. Consider how the infrastructure would change the software.

When the team at Google created the MapReduce algorithm, which resulted in the popular Hadoop implementation, it was specifically to perform with resilience even while running on cheap, commodity hardware that was presumed to regularly break.

A shift in perspective can create new constraints, which can be welcome design mates.

Create a Quarantine or Embassy

Consider the embassy. The geopolitical purpose of an embassy is, in part, to carve out a place for foreign government officials to work, free to abide by the laws of their own land, even while on foreign soil.

In software, when we want to do something innovative, but we are dealing with nontrivial legacy systems, we can create an embassy package, or more sharply, a quarantine package. We create space for the legacy mappings and adapters and business logic to work as they reliably have. But then you can have a standalone new system that is free from any such constraints within its many chambers.

This lets the new stay new and be different and allows one messy space for the legacy it must connect to, like the mudroom.

It’s an underscoring and permutation of the Adapter pattern, not because the interfaces are incompatible and need to talk, but because the new interfaces don’t exist yet, and you don’t want them to be too compatible with the legacy. Otherwise, you won’t innovate.

If you don’t do this, it’s very easy to unintentionally infect the new system and its design with the legacy’s restrictions, received ideas, and ways of thinking. You will dumb everything down to the point where there’s no point making a new system; it all looks just like the legacy.

Design for Failure

Design the system so that one part is the part you intend to fail or break. This allows the pressure to exert focus there, keeping other parts free from that pressure. That part can be swapped out readily. You can have service departments with a strong understanding of that area and parts ready to replace it.

You won’t be able to anticipate where exactly it will fail. It won’t fail conveniently where and how you want it to at just the right time when you’re available and ready to fix it.

A corollary can be found in chaos engineering, which reveals to us the parts that break under different conditions and how they do so. This gives you feedback to understand how to make it more resilient.

With this scapegoat in the system, the rest of the system can stay more sturdy. You don’t want to have to replace or update many little aspects across many areas in the system.

Design Language

One of Louis Kahn’s many important contributions to architectural theory was to develop his distinction between “served” and “servant” spaces. For Kahn, “served” spaces are those spaces in a building that are actively used by people, with “servant” spaces being those spaces that serve the utilized: ventilation systems, furnace rooms, elevator shafts, and so forth. Those are primarily used by systems.

This sounds reasonable enough. We don’t want to live in the stairway or the water closet. But we must be careful with this distinction, because as we’ve seen, it presents a privileged binary pair, which will inevitably become, one day, subject to a deconstruction, making the software very difficult, time-consuming, and expensive to work with.

Designing properly is about using words properly. The names demarcate the space. There should be truth in advertising in your API.

Naming

You define the semantic real estate when you name things.

This is very difficult for anyone to do. As stated earlier, we are forced to compromise in the language we use to describe our systems, and that creates problems.

Your system is a linguistic object.

Naming is one of the hardest things a designer will do—and one of the most important.

Name things as narrowly and as completely as their idea truly communicates. Do not “false advertise” in the name. If you write the Shopping service, by golly it better allow the user to shop All of The Things—hotels, houses, cruise ships, groceries, laptops, pencils, executive hoodies. What if your company wants to enter adjacent businesses, or new ventures? Are you really sure you want a “Shopping service”? If you have that, it is a good candidate to becomes a so-called God Object, which is the one gigantic, omnipotent class that is difficult to understand and change (let alone do so predictably and safely).

Are you sure it’s not really the HotelShopping service? Then there’s another one called the VacationRentalShopping service. Things that they can share can go in a library, or another service. But now they are allowed to be individuated and developed, maintained, tested, deployed, migrated, upgraded, retired, all on independent life cycles.

Name it properly and leave room for the other things and your user and help all your colleagues know what belongs where.

Additionally, consider the API for use in different contexts, whether that’s Unix pipes and filters or in user interfaces such as Xbox, web, phone, and voice. The work the shopping service is doing in all those UIs should still be the same because it is about owning that idea. There might be separate components to handle what’s distinctive about each of those platforms on which you expose the shopping capability.

After you have this arrangement, test whether they are MECE. You do this by forming the names at the same level into a single list and checking whether they are Mutually Exclusive and Collectively Exhaustive.2

Start Opposite the User

Do everything in thinking about the user, the personas, their needs. Then forget about them for a while and move to other users like the maintainers.

Design for the programmer first because they will become your factory for making designs. So start with what is most useful to them. The programmer is a big user and stakeholder in your design concept and the attendant guardrails you put in place to shape the system’s possibilities. You are shaping work for the programmer, making their work friction-ful or easier, more pleasant, and clearer.

So, design the deployment pipeline first because the programmer will build and deploy their code a thousand times in the course of your project as they create it. Design framework interfaces. Design the monitoring so that you get used to understanding and interpreting and listening to your application more and more throughout the process so that by the time you launch, you have a well-understood repeatable process. Start with the fire escape, the furnace, the mundane parts that have little that seem specific about this business problem so that you create the best opportunity for repeatability, which begets predictability, which begets insight and understanding and reliability.

Platforms

We know that we don’t know how people will need or want to use our systems.

When making a product, consider the larger context (the chair in the room, the room in the house). Consider how it would work as a platform.

The platform is the unified ecosystem of services that enable products. Focus on creating the context, the place where the stated requirements could come to be true, not simply directly building the stated requirements themselves. Work with your partners in product management to set expectations properly, of course.

Tech blogger Jonathan Clarks helps build the argument here:

Platforms are structures that allow multiple products to be built within the same technical framework. Companies invest in platforms in the hope that future products can be developed faster and cheaper than if they built them standalone. Today it is much more important to think of a platform as a business framework. By this I mean a framework that allows multiple business models to be built and supported. For instance, Amazon is an online retail framework. Amazon started by selling books. Over time they have expanded to selling all sorts of other things. Apple iTunes started by selling tracks and now uses the same framework to sell videos.

A platform could be your smartphone; that is, it has its own device form factor and its own ability to interconnect with other software streams, therefore it’s a platform that you can do other things with that were not originally envisaged at the time of its initial design

Disappearing

Make the software or the system disappear as much as possible. Consider the progress of the web search engine: it has been on a path of disappearing. 

In 1997, an early search engine, Hotbot (Figure 3-3), had an advanced “SuperSearch” that let you fill out many complex Boolean phrases, and its UI had many checkboxes. Over time, the web refined into directories with Yahoo and others, eventually tracing to Google’s single field that lets you type anything. Now, even that is disappearing as intelligent digital assistants let you search with your voice. The aim is the same, the use case is the same.

Hotbot search engine in 1997.
Figure 3-3. The popular Hotbot search engine in 1997

It’s more powerful than ever, but less present. Make your user the center of the power, and not your software.

Now in command of this theoretical frame, in the next part we explore the more practical application and artifacts involved in semantic software design.

1 See https://bit.ly/2qo8mHB.

2 For much more on this important concept, see the companion book to this one, Technology Strategy Patterns: Architect as Strategist (O’Reilly, 2018).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset