
Software Architecture Is Overrated, Clear and Simple Design Is Underrated - signa11
https://blog.pragmaticengineer.com/software-architecture-is-overrated/
======
jaequery
First 1-3 years of coding, I just coded to get sht done. I got a lot of sht
done.

Next 4-8 years, I started getting cute with it and applied all kinds of design
patterns, Factory, Abstractions, DI, Facade, Singleton you name it. It looked
cute and felt good when it all worked but it was a juggling act. There was
usually like 2-3 files to touch just to do one thing. UserFactory,
UserService, UserModel, User, you get the idea. It got to a point coding now
felt like a burden and I started getting allergic reaction to any projects
that had more than 50 files.

Next 4-5 years, I made it a mission to only code in a pragmatic, minimalistic
way. Best decision I ever made, this have been the most productive time of my
career. I don’t look back and never going back again. A simple require and
requireAll with basic OOP is all I need on most cases. Most of my project now
have less than 10 “core” files minus the standard views/routes/etc. I enjoy
just working on code now it makes me happy and also any devs who joins loves
it too as they get it right away. I code almost exclusively in Sinatra now
btw. Express is great too but I think the ecosystem isn’t there yet for
developer happiness.

Keeping code simple is not easy. It takes a lot of trials and errors to know
what works and what doesn’t. I realize I code a lot slower now than in the
past and that I write much fewer lines of code. It’s both good and bad because
sometimes I’d even spend hours just trying to properly name a variable. But I
believe this pays off at the end.

You just can’t best simplicity.

~~~
feketegy
Most devs prepare for the abstraction nirvana. I see a lot of fellow devs
creating complicated code, because "in case we need to switch out the database
down the road" or "what if we want to run the web app in CLI"

In 20 years of programming I maybe seen one or two times a large application
switched database engines and I've never seen a client want to run his/her web
application in CLI...

The art in programming is to decide whether you need that abstraction or not.

~~~
Vinnl
It's not just programming, though. A large part of it is defining the product
roadmap: code can get a lot better if a product team has the guts to
unequivocally say that some features are not going to be part of the product,
ever, such as running the web app in CLI. That's not just a programming
decision - though I guess influencing the product roadmap could be seen as
part of the art in programming as well.

~~~
downtide
Yeah I had a manager that was quite good at throwing out functionality. Didn't
like it at the time, but they were mostly right - of course they were just
trying to save money.

~~~
james_s_tayler
I like this. Because time after time after time I have seen the opposite.
Managers saying "but we might need it again later" and...

We. Never. Have.

And even if we did... its still under source control if you really want to dig
it out.

~~~
codr7
Second that, after 34 years in the game I'm always on the lookout for dead or
dying code. Every line I can put out of its misery is one less to deal with in
the future.

And I find that removing dead code often unlocks further improvements that
become obvious without the noise.

Even if the functionality is needed down the line, it tends to require massive
rewrites to catch up.

------
d--b
Let’s see how the OP’s system looks in 20 years. Then we’ll see how clear and
simple it has remained.

The OP is railing against a culture that never existed. Banks software
architects are not in their offices smoking cigars and making UML diagrams
that they send to coders, only to realize later that they made the wrong trade
off.

What happens is:

You design a system for what it’s supposed to do. You do it the way the OP
says: nice ad hoc charts, talk to a lot of people, everybody agrees, all is
swell.

Then time goes by, new integrations are made, newer tech comes out, costumers
need change, business orientation changes. And what used to be neat starts to
become ugly. People cut corners by putting things where they don’t belong to
save some time. And then it’s all downhill from there.

There is a toilet analogy that works well. If you go to a bar and the toilet
seat is very clean, then you’ll make sure to clean it before leaving. But if
the toilet is already dirty, you’re not going to be the one cleaning other
people’s pee, so you just add your own and leave.

The same is true in software architecture, once it doesn’t look neat,
everybody just pile up their crap in the way that demands the least effort.
“The system is shit anyways”.

I find it a little easy to say: “ha look at those guys, they spend hours
trying to sort out system architecture, while all you really need is common
sense”.

~~~
bigbluedots
It's pretty rare these days that systems are maintained for that long. More
than likely there'll be a rewrite every few years anyway to keep up to date
with $EXCITING_NEW_TECH.

~~~
james_s_tayler
Hmm maybe in the Bay Area?

Everywhere else I've seen software that is on average a decade old.

~~~
gizzlon
That does not mean that typical service will live for a decade though. You
don't see all the ones that did not make it.

------
cryptica
This article has some contradictions:

>> Third, we had practically no references to the common architecture patterns
and other jargon referenced in common software architecture literature, such
as Martin Fowler's architecture guide. No mentions of microservices,
serverless architecture

Then a few paragraphs later:

>> Is your architecture split into different microservices? Mention why you
decided against going with a monolith, that might have some other benefits

Another contradiction (which mostly contradicts the general premise of the
article):

>> We created plenty of diagrams, but none of them followed any strict rules.
Just plain old boxes and arrows, similar [this one describing information
flow] or [this one outlining class structure and relationships between
components]

In the last link ([this one outlining class structure and relationships
between components]), the article says:

>> If you have previously worked with the [VIPER] architecture, then the class
breakdown of a RIB will look familiar to you. RIBs are usually composed of the
following elements, with every element implemented in its own class:

... and then it shows some kind of class diagram which looks vaguely like UML
in which the classes have highly architected names like 'Interactor',
'Presenter', 'View', 'Builder'... Nothing to do with the underlying business
domain. Doesn't look like simple design to me. The recommended approach looks
more like complex VIPER architecture.

~~~
kdmccormick
Good observations. I think a more accurate portrayal of the author's
experience would be "Clear and simple Architecture is underrated".

------
moksly
The value of Enterprise Architecture doesn’t come in to play until you’re an
actual Enterprise.

We operate more than 300 IT systems, from a myriad of different and switching
(courtesy of procurement) suppliers. These systems are operated by 5000-7000
employees, and range from making sure employees get paid and patients get the
right medicine to simple time booking apps. Most of these systems need to work
together, and almost all of them need access to things like employee data.

Before we had a national strategy for enterprise architecture, which defines a
standard model for organisation data, all of those 300 IT systems did it their
own way and most of them actually thought we liked that so they came with no
APIs. Imagine having to manually handle 5000-7000 users in 300 different IT
systems...

That’s the world without Enterprise Architecture, and we’re still paying
billions in taxpayer money to try and amend it. Because you don’t move 300 IT
systems, some of them running on COBOL on mainframes, over night. And that’s
just our municipality, there are 97 others with the exact same problems.

Don’t get me wrong, I get the sentiment of the article and I actually agree
with most of it. The thing is though, developers have very different opinions
about what “simple design” is, I know, because I’ve build a lot of the gaffa-
tape that integrates our 300 IT systems and not a single system has had
remotely similar APIs.

~~~
blub
I've seen you mention your organization and the challenges you're facing few
times and I'm curious what kind of architecture books or principles you'd
vouch for based on your experience.

~~~
moksly
It’s build around our own version of TOGAF, but I’m not sure I’d really
recommend that to anyone. It’s also more political than technical and suffers
from a lot of “not invented here” even in competition between different
government agencies and changing bosses.

A good example is the OIO standard we use to model most our abstract data
design. It’s basically a local standard, which means it’s different from the
EU standards that do the same. Which again means, that we had to work with
Microsoft to get OIOSAML working with ADFS and are still working with them for
Azure AD, and it may all be in vain when we eventually swap to EU standards as
the rest of Europe catches up.

The thing is though, we started the journey before there were EU standards,
and a lot of the decisions that seem bad today were right at the time. Over
all, it’s still a pretty huge benefit to what was before.

To get back to your question. The thing I’ve done that has been the most
useful in EA hasn’t been TOGAF or any of the other EA focused frameworks. It’s
been the year of political science I took at the university, I think it equals
to part of the American MBA but more focused on Enterprise Admin and HR.
Because Enterprise Architecture is mainly about understanding the business on
its terms and finding the compromises to make your tech sector understand it.
I think being able to communicate and understand your business is a lot more
important than whether you map things in X framework. I mean, your developers
are probably going to understand your PowerPoint drawing just as well as your
UML/ArchiMate anyway, and the less tech details you define, the better because
the article is actually right about developers knowing better how to build
things. If you tell them how the data is mean to be understood by any system
that receives a User object, then you won’t have to tell them how to handle it
beyond that.

------
bamboozled
In my career thus far, I can honestly say I've never, ever, ever seen an
"Architect" who actually provided valuable inputs.

Not trying to say they don't exist, but I've just never witnessed someone with
that title actually have a positive impact on any project I've worked on.

The only semi-positive value I've seen an architect have is when they counter
another architect to allow the engineers get on with their work without
interfering.

Maybe the issue with the job comes from the connotation that an architect is
someone with supreme insights? Where as most usually, they just over simplify
things and expect engineers to deal with the implementation details (the hard
part).

~~~
petjuh
We have a great architect right now, but he's really just an engineer
designated as the "architect". He also codes sometimes.

~~~
rumanator
> We have a great architect right now, but he's really just an engineer
> designated as the "architect".

Why is anyone assuming that an software architect is not supposed to be a
software engineer?

The software world is not divided as the civil engineering world, where
architects are responsible for meatspace UX and engineers are tasked with
bringing the UX to life.

In the software world, software architects are expected to be experienced
software engineers who are tasked with coming up with design decisions upfront
that render the software development project feasible and economical by
picking which technologies to reuse, which modules/services to develop
independently, and how to run in production.

Which of hear tasks is not the job of a software engineer?

------
drawkbox
A programmer, engineer, creative and product developers job is to create
simplicity from complexity.

The job is to tame complexity via simplicity, not make a complex beast that
needs more taming.

Sometimes engineers take something simple and make it more complex which is
against simplifying either due to bad abstractions or proprietary reasons or
obfuscation for job security or to ego flex. Anyone can make something more
complex, making something simple and standard takes lots of work and
iterations.

Nature is built with simple iterative parts that look complex in whole,
systems that work well mimic that. Math is built with simple parts that leads
to amazingly complex and beautiful things. Art is built with simple marks to
create something complex and beautiful. Humans as well, and they desire
simplicity so they can do more and build on that.

~~~
mikekchar
I'd make a slight caveat with this. The our job is to make something that is
as close as possible to the complexity of the problem. You don't want to make
it more complex for obvious reasons. However, you _also_ don't want to make it
less complex, because then you are removing fidelity. Let me aim a slightly
playful jab at the GNOME people for "simplifying" by removing features that I
actually need. Only slightly playful as it's the reason I had to give up
GNOME. ;-)

------
uber99953
Services at Uber are pretty much all stateless Go or Java executables, running
on a central shared Mesos cluster per zone, exposing and consuming Thrift
interfaces. There is one service mesh, one IDL registry, one way to do
routing. There is one managed Kafka infrastructure with opinionated client
libraries. There are a handful of managed storage solutions. There is one big
Hive where all the Kafka topics and datastores are archived, one big Airflow
(fork) operating the many thousands of pipelines computing derived tables.
Almost all Java services now live in a monorepo with a unified build system.
Go services are on their way into one. Stdout and stderr go to a single log
aggregation system.

At the business/application level, it's definitely a bazaar rather than a
cathedral, and the full graph of RPC and messaging interactions is certainly
too big and chaotic for any one person to understand. But services are not
that different from each other, and run on pretty homogeneous infrastructure.
It takes pretty strong justification to take a nonstandard dependency, like
operating your RDBMS instance or directly using an AWS service, although it
does happen when the standard in-house stuff is insufficient. Even within most
services you will find a pretty consistent set of layers: handlers,
controllers, gateways, repositories.

~~~
barrkel
What you describe is an architecture, of course, and it didn't happen by
accident.

~~~
uber99953
It's an architecture that's almost completely mute on how business-level
functionality should be organized.

~~~
barrkel
Generally software architecture solves for non-functional requirements, rather
than functionality. Product managers organize business-level functionality.

------
ryanjshaw
Uber is barely 10 years old. They can get away with this. Wait until it's 2 or
3 times that age, and its (present or future) regulators sign new laws into
place that require massive changes or reporting feeds across multiple systems
engineered and documented in this unprincipled fashion. Probably after a
couple more privacy breaches or self-murdering car incidents. Nobody will be
able to figure out how it all fits together, and the compliance team and
auditors are going to throw a fit.

That's when all those architecture processes, repository tools and languages
suddenly make a lot more sense. Uber deals with extremely sensitive personal
information, and the move towards self-driving cars means they deal with
highly safely sensitive systems. The dismissive attitude towards these tools
in what should be a highly disciplined engineering organisation disturbs me,
but I come from a highly regulated environment so perhaps I was just raised
that way.

~~~
_pmf_
> the compliance team and auditors are going to throw a fit.

I've never seen an auditor give a shit either way. They're just box ticking
robots.

~~~
hdfbdtbcdg
And if they can't tick the box? You fail the audit...

------
obstacle1
A big problem IME is people tend to define "simple" as "written in a style I
prefer". For example you can extract a series of 10 obviously-related methods
from some 2000-line God class into their own class, but have others who are
used to a more procedural coding style complain that the indirection is "hard
to read" because they need to open a new file. This despite the facts that
others find the God class "harder to read" because it contains 2000 lines of
code doing everything under the sun, and that class is objectively harder to
maintain/change for everyone because nobody knows what things are necessary to
change to achieve some goal, because there are no logical boundaries between
code functions so you can't tell what needs changing without reading
everything.

Cue endless bikeshedding in the name of "simplicity", which nobody is using an
objective metric to define.

~~~
stinos
_2000-line God class ... "hard to read" because they need to open a new file_

Might be me, but I've always found this a rather strange argument: either they
aren't using 'go to definition' which means that to be able to read the other
code they have to scroll through the file manually, leaving where they are,
and then go back. That's not really convenient? Or they are using 'go to /
peek definition' and then it doesn't really matter it's in another file?

~~~
goto_self
I have counterpoints on both ends here.

It's not always possible for a "goto definition" function to work in dynamic
languages.

If you're in a large file, it's quite easy to jump around with line marks (a
la vim), searching, etc.

~~~
stinos
Good point about dynamic languages. But line marks also work across files,
right?

~~~
goto_self
Yes. Line marks are amazing.

------
rumanator
I have a hard time understanding the author's point of not using UML but
somehow boasting that they used "plain old boxes and arrows" to create "plenty
of diagrams".

UML is nothing more than a bunch of "plain old boxes and diagrams", but which
have concrete, objective meaning that has been specified and thus help share
ideas as objectively as possible. UML is a language, and languages are tools
to communicate and share information.

Using ad hoc box and arrow diagrams invented as they go along means they
decided to invent their own language, which may or may not be half-baked, that
is not shared by anyone other than the people directly involved in the ad hoc
diagram creation process.

If the goal is to use diagrams to share information and help think things
through, that sounds like a colossal shot in the foot. I mean, with UML there
are documents describing the meaning of each box and each arrow, which help
any third party to clear up any misconception. What about their pet ad hoc
language?

In the end the whole thing looks like a massive naive approach to software
architecture, where all wheels have been thoroughly reinvented.

~~~
hdfbdtbcdg
This reminds me of the framework va libraries argument or ORM vs raw SQL. Yes
frameworks and ORMs can be constraining and limit clever solutions. But when
you need to add complex features to a complex project you are always glad that
every other programmer that came before you was constrained and that things
use a familiar pattern.

~~~
jillesvangurp
I've encountered spring/hibernate projects in the with lots of performance and
integrity issues that were easy to straighten out by just cutting out the orm
layer and replacing it with non magical, simple SQL. Magic is nice when it
works but when it stops working and you lack the skills on the team to make
sense of it, things get ugly quickly. This happens exactly when you are adding
complex features that stretch the abilities of the framework you are using as
well as the teams understanding of that framework.

I'm not a big fan of micro services. But one nice feature is that they are
small and usually quite easy to grasp. That makes putting new people on them
to do some changes a lot more feasible. A big monolith is much more complex.

I'm torn between building nice monoliths and doing micro services. IMHO for a
small team micro services are rarely worth the complexity and overhead and I
like the simplicity of having a nice monolith. However, with multiple teams in
bigger organizations, it's a better fit. The risk to watch there is Conway's
law where your org chart and architecture start resembling each other. The key
risk here is the constant staff changes that necessitate having a speedy
onboarding and ensuring there is a path forward when key people leave. Complex
monoliths are a risk in such situations.

Simplicity and predictability are key here. This does not have to translate
into ORM but it often does. IMHO with modern languages and framweorks, there's
a trend for more code that does what it says vs. annotation code where all the
magic happens in annotation processors that are opaque. This is playing out in
the Spring community right now where the latest trend is using Kotlin DSLs to
replace annotations and annotation processors. A side effect is that this
allows using the graal vm to get rid of JVM startup overhead.

Part of that is losing ORM. E.g. the experimental Ko-Fu framework for Spring
is taking that to the extreme: [https://github.com/spring-projects/spring-
fu](https://github.com/spring-projects/spring-fu)

~~~
james_s_tayler
I actually love magic, but boy oh boy are you right when it comes to hitting a
wall and getting absolutely stuck when magic happens.

I've spent a bunch of time thinking it through and I've come to the conclusion
that it isn't actually the magic that is the bad part. It's the lack of the
discoverability that is bad. I guess that's why it's called magic right?
Because you don't know what the trick is, yet it appears to work...somehow.

I call it dark magic. Magic that is not discoverable and makes no attempt to
help you discover it. On the other hand, if you put magic into a solution
because you are a wizard and you want to leverage the stunning super powers
that magic gives you, if you can also tell everyone how the tricks are being
done... it's actually possible to get the best of all worlds.

------
philliphaydon
I went to a course by Udi Dahan once, about CQRS. One of the people asked him
a question about CRUD. Something along the lines of how would you use CQRS for
simple CRUD operations. And Udi was like "just go to the database".

The guy kept asking the same question different ways like Udi didn't
understand the question. The response was always the same. Then Udi said, if
you need to go to the database, go to the database, don't over complicate
things.

It was like a lightbulb for me, having spend ages always trying to fix
everything into an abstraction of some sort instead of just getting stuff
done.

------
q-base
I am very much a proponent of simple and pragmatic design. It should be the
default, especially for small - midsize companies. I do however have my doubts
once you get to very large financial institutions for instance, where you have
a vast portfolio of products spread across numerous departments and
potentially countries. On top of which comes heavy regulation.

In order to keep this system-landscape somewhat coherent, then I can actually
see a need for enterprise architecture. Or put another way, I can't really see
how it should succeed without it. The default should still be simplicity, but
to keep every department from building their own version of components and
keeping security at the forefront you still need guidelines and direction in
my opinion.

Not that this necessarily is in opposition to the article though.

------
merlincorey
This resonates very well with my experiences throughout my career.

The best design experiences from an at-the-time and with hindsight typically
result in a collaborative document with a clear narrative structure explaining
most importantly what and why as well as how (and as the article mentions, the
trade offs involved) such that even junior engineers and potentially even non-
technical contributors can understand what we're doing and why.

------
cryptica
Design is part of architecture so it doesn't make to compare them.

The best architectures are usually the simplest ones which get the job done.

To design the simplest architecture possible, you need to know exactly what
"get the job done" means. Many software architects have no vision when it
comes to seeing all possible use cases for the product so they don't know what
are the minimal structural requirements. So either they underengineer or they
overengineer based on what is more profitable for them as employees of the
company.

Underengineering is also bad but it's rare nowadays because it usually doesn't
align with employee salary incentives so we forgot how painful it is to
maintain a code base which copy pastes the code everywhere.

~~~
SamuelAdams
Right, there's the concept of JBGE:

[http://agilemodeling.com/essays/barelyGoodEnough.html](http://agilemodeling.com/essays/barelyGoodEnough.html)

I think too many people want to apply a "silver bullet" to all projects: IoC,
Docker containers, auto-scaling, etc. But sometimes I'm just tossing data from
an API into a database somewhere. I don't need all that complexity.

Other times, I'm building an enterprise product with three fully-staffed agile
teams, spending a million dollars annually for five years. Architecture that
enables those teams to work in a cohesive way becomes very important, so an
IoC pattern might save us a lot of time down the road.

Great architects know when to underengineer and when to overengineer.

------
liha
It’s interesting how OP talks about the process as something unique and
groundbreaking. Honestly that’s how 90% of the tech companies handle
architecture and design - a bunch of people whiteboarding solutions and
drawing box diagrams and writing down notes. In 12 years I haven’t worked at
any company that uses the tools he mentions. Experience usually drives the
output and the result of the mentioned “process”. An experienced engineer in
the room is more likely to bring up non-functional characteristics and related
concerns such as performance, security, high availability etc. You can choose
not to have a formalized architecture process or review and you can also
choose to just draw boxes which link to each other without completely making
sense - like a class with an arrow pointing to a machine and another arrow
pointing to a process (which is fine until a couple of years later, someone
looks at a dangling process in the diagram and wonders which machine/container
it’s running on). Obviously Ymmv because it’s not some “predictable” process
and purely relies on drawing out the collective experience and intelligence of
the room

------
andreyk
Boils down to this: "So what is the role of architecture patterns? I see them
similarly in usefulness as coding design patterns. They can give you ideas on
how to improve your code or architecture."

The whole idea of patterns is to identify often useful, and possibly non-
obvious, ideas to be aware of when designing the solution. It's great to start
simple, but tricky to make things both simple and robust/powerful - and that's
what patterns are supposed to help with. This ends with:

"Software architecture best practices, enterprise architecture patterns, and
formalized ways to describe systems are all tools that are useful to know of
and might come in handy one day. But when designing systems, start simple and
stay as simple as you can. Try to avoid the complexity that more complex
architecture and formal tools inherently introduce."

What this misses that if you start simple and stay as simple as you can, you
may undershoot and be stuck refactoring code down the line; a fine balance is
needed, and patterns are definitely part of a toolset that a good engineer
should be aware of when trying to nail that balance.

~~~
james_s_tayler
I really agree about undershooting. I like to try and overshoot by about 15%.

It's definitely a big mistake to overshoot by say 50 or 100 or 200%. But
overshooting by just a little often leaves me feeling like "thank God I did
that" more often than it does "hmm I guess I really didn't need that".

Balance is absolutely key.

------
perlgeek
Despite the provocative title, the author argues for software architecture,
just doing it in a manner that suits the organizational culture.

He somewhat decries traditional software architecture material, which I find
off-putting. IMHO the best approach is to be aware of the
techniques/patterns/references architectures, and use just the parts that make
sense.

~~~
rumanator
> Despite the provocative title, the author argues for software architecture,
> just doing it in a manner that suits the organizational culture.

The problems demonstrated in the blog post go deeper than (and are not
explained by) organizational culture. They convey the idea that the task of
designing the architecture of a software system was assigned to inexperience
and ignorant developers who, in their turn, decided that they didn't needed to
learn the basics of the task, and winging it as they went along would somehow
result in a better outcome than anything that the whole software industry ever
produced.

There is a saying in science/academia that is more or less "a month in the lab
saves you hours in the library", which is a snarky remark on how people waste
valuable time trying to develop half-baked ideas that match concepts that were
already known, thought through, and are readily available if they only put in
the time to do a quick bibliographical review. This blog post reads and awful
lot like that.

~~~
lensopra
The saying in software is "Weeks of coding can save you hours of planning."

------
growlist
In my experience the further away from fierce commercial factors, the greater
the tendency towards cargo-cultism. Hiring for roles in government related
work in the UK is awash with acronyms and buzzwords, as if it's the case that
with enough methodology and certifications we can regulate failure away.
Problem is: things still seem go wrong in all the same old ways despite all
the latest greatest fancy new techniques. But hey, all our developers are
TOGAF certified these days, so that's something!

~~~
james_s_tayler
For some reason I read "methodology" as "mythodology" and I thought "That's
genius! That's the perfect portmanteau to describe the phenomenon of people
trying to learn and adhere to 'methodology' but then really just adhering to
the lore and the myth! I'm stealing that!"

Then I read it again and it didn't say that. But I think that should become a
new word. Mythodology.

~~~
growlist
Nice. Even better, use it as the name of a company hawking snake-oil
methodology consulting.

------
a_imho
_Engineers at higher levels, like staff engineers, are expected to still
regularly code._

As they should. The non coding software developer is one of my pet peeves,
call it architect if you want. I can appreciate the idea of collecting a
paycheck producing wiki entries, drawing diagrams and making slideshows, but
they are no substitute for leading by example. In fact, my empirical finding
is that the tendency to describe software in prose is usually inversely
correlated with the technical ability to create the executable.

------
jameslk
Sounds great for a tech company with highly skilled engineers. They can afford
the type of talent who will be thinking thoughtfully and have the time to do
so. Startups seem to attract similar talent, and when not, don't always have
the same problems anyway.

But what about the companies that can't afford the best engineers and don't
have the bottom up culture? What about the companies that hire overseas IT
agencies who do exactly what they're told and no more (it's safer that way
when communication and timezones are working against you)?

I've worked in companies both the former and the latter. I've seen the top
down "architect" role work better in the latter.

The author even seems to admit this, although briefly:

> To be fair, these same companies often want to optimize for developers to be
> more as exchangeable resources, allowing them to re-allocate people to work
> on a different project, on short notice. It should be no surprise that
> different tools work better in different environments.

This best summarizes it. Different approaches work better in different
scenarios. That's really what the title and article should be about.

~~~
rumanator
> Sounds great for a tech company with highly skilled engineers. They can
> afford the type of talent who will be thinking thoughtfully and have the
> time to do so.

The blog post says nothing of the sort. It focuses on two aspects of software
architecture which are entirely orthogonal to the design process: using a
common language and tools to communicate and describe their ideas (UML,
documentation) and leveraging knowledge and experience to arrive at a system's
architecture that meet the project's requirements.

Deciding to invent their own personal language (their "boxes and arrows") and
take a naive tabula rasa approach to software architecture does not change the
nature of the task.

A rose by any other name...

------
Hokusai
> However, no one person owned the architecture or design. The experienced
> developers did drive this.

The lack of formality does not mean a lack of the role. If "experienced
developers" are the ones doing the design. They are de-facto architects.

> No mentions of microservices, serverless architecture, application
> boundaries, event-driven architecture, and the lot. Some of these did come
> up during brainstormings. However, there was no need to reference them in
> the design documents themselves.

So, the teams were thinking in patterns to discuss and express themselves.
But, then decided to hide that and do not show the reasoning in the
documentation, for reasons. That makes the job of understanding the
conclusions of the discussion harder for people from outside their group.

I am all for transparency. If your company has architects but calls them
"experienced engineers". If you use patterns and then remove them from your
documentation. Your company is going to lack the transparency to allow
everybody to participate.

Everybody has seen this with on-line rants. People raises and falls by
politics. When they are one of the "expert engineers" they talk about cool
company and meritocracy. When politics make them fall, then there comes a rant
and how now the company "is not at it used to be".

I like to spend my time doing software engineering instead of politics and
gaining upper management favor or fighting peers. Clear responsibilities help
with that when a company is big enough. Like any system, a quantitative change
- number of employees - may lead to a qualitative change that needs a change
of approach. To try to run a 1000 people company like a 50 people startup is
like trying to design in the same way a small server with a few queries per
minute and a critical server with thousands of queries per second.

To each problem its own solution.

~~~
closeparen
Central, top-down architecture is _extremely_ political. You have to fight
with bigwigs who don't know your problem domain and don't live in your
codebase to make it reasonable, or even possible, to solve the business
problems on your plate when they inevitably don't fit the 10,000 foot 5-year
plan.

Pushing down architecture responsibilities into the hands of senior engineers
with specific problems to solve / features to build eliminates that form of
politics. They are not disguised architects, because designing the
architecture is only phase of the project. They also have to live with the
architecture. This is a _great_ thing.

~~~
jbn
architecture is political because an architecture (or a system) always ends up
mirroring the organization that produced/operates it. A well-known fact in OB,
and one reason why one wants to engineer (i.e. architect) the organization
simultaneously with the system, otherwise you create silos or disjoint systems
that can't talk to each other.

------
blub
Interesting that this mentions Uber.

The way I understand it, in automotive companies have to prove that they
carefully designed their systems based on the appropriate standards and they
have to have the documentation to prove it in case there's a complaint from
customers. A simple document won't cut it.

Then there's Uber, which is mentioned by the author and which killed a person
through their gross negligence and then got away with it scot-free. I wonder
how good their payment systems really are.

Can anyone from Uber comment whether sometimes they get a little bit less
money or duplicate payments? Do transfers still work in conditions of poor
visibility?

------
Maro
I agree with the post, and this works at companies like Facebook and Uber,
which have very high hiring bars, impact-oriented internal cultures and can
afford to pay a bonus if you help the company be successful.

The interesting question is, what should all the other companies do? They
cannot hire the best people, that aren't cash-rich, so cannot incentivize
people. If you rank companies, what about the ones hiring the bottom 25%? They
also want to write software to help run their business.

I'm not saying software architecture is the answer, but the [hidden]
assumptions in the post break down and don't apply.

------
vnorilo
I think the underlying art is in striking the right balance between the
specific and the general. In studying PLs for almost a decade now, I always
ask PL designers I meet to try and distill their wisdom in one sentence.
Andrew Sorensen said something along the lines of "Avoid all abstraction".

That shocked me, because my pet theory at the time was that abstraction was
basically a force multiplier: good abstraction makes everything exponentially
better, while bad abstraction makes everything exponentially worse.

Nevertheless that quote stuck, and later I've started to appreciate it in
terms of the YAGNI arguments.

Regarding abstraction, I've come to believe that a common anti-pattern is
_deductive abstraction_ : working down from a general pattern towards a
specific implementation. This resembles what a sibling comment called
"applying all sorts of design patterns from books to my code" (and not getting
great results).

The opposite, _inductive abstraction_ , is starting from a specific task and
introducing gradual abstraction. Abstraction in lambda calculus is a beautiful
example of the concept. Now make that thing a lambda term!

There's a Bret Victor classic that touches these themes [1].

[1]:
[http://worrydream.com/LadderOfAbstraction/](http://worrydream.com/LadderOfAbstraction/)

------
Michielvv
I personally feel that software architecture isn't so much overrated as too
much focused on abstract patterns instead of how to best solve common
problems.

e.g. last year I needed to model an invoicing system, although this has been
implemented hundredths thousands of times, there is very little generalized
information on how to best do that so that it doesn't fall apart next year.

The areas that currently are better at this are mostly related to security and
operations.

------
agentultra
This is great... but one thing I think we _do_ need to change a bit is around
_specification_. Knowing when to use blueprints as opposed to a sketch on the
back of a napkin (or on a whiteboard). UML diagrams are not helpful to a lot
of projects. But if you're dealing with concurrency or hard problems involving
liveness or safety -- having a model one can verify and check goes a long way.

My litmus test for knowing when to bust out a TLA+ or Alloy model is: _what 's
the worst that could happen if we get this wrong?_ and _are there behaviors we
cannot allow the system to have_?

I find many developers, especially senior ones, develop a misplaced confidence
in their knowledge and skill. And usually this is justified. We can generally
get the majority of the system correct enough to be useful within a couple of
iterations. Once that system is in production however it can become too
difficult for even the most genius among us to find that one behavior of
billions of possible ones that keeps triggering our SLOs.

That's because once we break down our behaviors into discrete steps and
variables we find that many systems have behaviors that are 50 or more steps
long involving several variables. The bad behavior that we didn't account for
is there and we didn't know it existed until it went into production and
started frustrating our customers.

I don't suggest we specify entire systems using formal methods like this, but
for the important parts, I find it's worth avoiding the trouble than it is
tolerating the risk and frustrating users.

Nice article though -- consensus building among peers is one of the least-
taught skills and one of the most important.

------
sid1138
I have been coding for over 40 years and have designed many systems from small
embedded systems the size of my little finger to huge, globe-spanning
telecommunications systems. For all of those systems, the various teams'
designs were basically as Gergely Orosz talked about. A few times I did some
UML drawings, but the time to get them "right" was not worth it.

So, what is my role as an architect (I have been doing that role for about 15
years)? For various start-ups, I made sure that designs were compatible with
each other (primarily through APIs and protocols). This was especially
important at the startups since each team was running full speed to get a
project done and often forgot the company's big picture.

For larger companies, I would be the interface between the customer and
engineering to ensure both sides understood the requirements, expectations,
and deliverables.

In all cases, I would also continue to code as well as document. An architect
who doesn't code quickly loses sight of what is real and what is important in
the ultimate expression of the design - the code itself.

------
vemv
> No mentions of microservices, serverless architecture, application
> boundaries, event-driven architecture, and the lot.

I see why one would want to escape the mindless name-dropping that can be
prevalent elsewhere, but at the same time, things have a name/fame for a
reason.

There is pragmatic value in studying patterns (especially from good sources),
and citing them in your internal documents so everyone is on the same page.

------
jacquesm
Clear and simple design _is_ optimal software architecture. Oversimplification
and architecture madness are sub-optimal.

~~~
vemv
> Oversimplification and architecture madness are sub-optimal.

Let me point out, you are essentially saying "bad things are bad" here.

~~~
jacquesm
That doesn't seem to stop people from building systems in exactly those two
ways. Yes, bad things are bad. Now stop doing bad things, it would make my
professional life a lot easier.

Cobbled together Filemaker pro software running major factories; a million
lines of code and 40 people to solve a problem that would take 3 people and
10% of the LOC if properly architected, and so on.

~~~
vemv
Probably I agree with you.

I was mostly pointing out the weak writing: over<x> and <y> madness are
_always_ sub-optimal, for all values of x and y.

------
PeterStuer
"I know of banks and automotive companies where developers are actively
discouraged from making any architecture decisions without going up the chain"
... "So these architects create more formal documents, in hopes of making the
system more clear, using much more of the tools the common literature
describes."

Having consulted in such environments you have to remember that most of the
large projects there are implicitly expected to fail, so CYA has become
ingrained very deeply into the culture.

I stopped taking these jobs once it fully dawned on me that getting results in
terms of on budget, on time, delivery while delighting users was never the
prime objective, but using each project as a battleground in a perpetual
internal jousting match for power grabs was.

------
cestith
As a developer I find I'm paid very little for lines of code. I'm paid
primarily for making decisions and for recording those decisions clearly.

Application source code is one way those decisions are recorded. Call graphs,
data flow graphs, help text, application documentation, API documents,
troubleshooting guides, monitoring code around production applications, tests,
configuration and build management files, and commit messages are others.

Given that point of view, here's my advice.: Make the source and the other
artifacts as simple as possible, but no simpler. Cross-reference where it
helps most, but not excessively. Compose things from modular pieces rather
than building monoliths when you can. Document the parts and the whole.

------
mpweiher
Software Architecture just _is_ , regardless of how you rate it.

Your software is going to have an architecture, whether you make conscious
decisions about this architecture or not.

In the absence of a coded/codified architecture, your architecture is going to
be implicit in the code. Currently there is very little choice in this, as we
don't really have a useful way of putting the architecture in the code.

So your choice is either (a) implicit in the code or (b) implicit in the code
+ explicit in non-code documents. Neither of these are good choices, opinions
differ about which is less bad, and those opinions also vary with the project
and with experience.

Of course, the choice would go away if we architecture were a code artefact.

------
psychoslave
The safest general characterization of the non-continental software
architecture tradition is that it consists of a series of footnotes to the
quote "Simplicity is the Ultimate Sophistication[1]"[2].

[1]
[https://quoteinvestigator.com/2015/04/02/simple/](https://quoteinvestigator.com/2015/04/02/simple/)
[2] [https://www.age-of-the-
sage.org/philosophy/footnotes_plato.h...](https://www.age-of-the-
sage.org/philosophy/footnotes_plato.html) if you didn't get it already. ;)

------
kissgyorgy
One of the best design decision we come up with for a cluster configuration
synchronization feature between nodes of our appliance born during an ad-hoc
conversation between 3 senior engineers. We made the decision in like 2 hours.
No long and unnecessary meetings with architects or week-long planning. It was
made for a 1 million dollar deal and we finished in a couple of months. You
could probably guess how the "architecture" looked like; we downloaded the
config files from a web server running inside the cluster. That's it.

------
barrkel
A clear and simple and sufficient design is good architecture; an unclear,
complex or insufficient design is bad architecture.

The article seems like a bit of a tautology to me.

------
cryptozeus
Good article but some parts are outdated like who uses UML these days ? Saying
you did not create diagrams using any architecture tools is but obvious, no ?

~~~
SamuelAdams
I just started grad school this fall (September 2019). My "systems analysis
and design" course spends three weeks on UML, Data flow diagrams, and CASE
tools.

This would have been a great course, 20 years ago. No sane business uses these
tools today. The military might, but that's about it.

~~~
cryptozeus
Yeh schools are way behind real world!

------
MertsA
Overcomplicated designs is like the rocket equation for software engineering.
Adding unnecessary abstractions, caching layers, abstract business logic, etc
isn't an additive effect, it's a multiplicative one. This is how you take
something that could have been a million dollar project and turn it into a
billion dollar project that is completely broken on launch like healthcare.gov
was.

------
ccanassa
As a Python developer, I always fell that I am talking to aliens when I have a
conversation with Java developers. I've already built several large systems in
Python/Django and nobody in our field talks about these patterns. We tend to
follow more broad and philosophical principles like DRY, "we are all
consenting adults" or the "Python Zen".

------
zarkov99
It changes. When you don't understand the problem, yes, simplicity is your
best bet. Keep the code clean, clear, because you are going to have to change
it a lot. As the understanding of the problem increases, and this does not
always happen since sometimes the problem changes too quickly to be
understood, then a good architecture can make an enormous difference.

------
l0b0
Reading (OK, skimming) about this is a bit like a time machine. It's the kind
of realization I expect people had in the early 2000s after fads like UML
imploded massively. Is anyone taking architects like these seriously these
days? Makes the article seem a bit like patting themselves on the back for not
being bonkers.

------
eternalban
Is the OP claiming that he/uber built systems that have no discernible
architecture?

Confusing methodology with architecture is not helpful. Even the simplest
system has 'architecture'. Now this can be arrived at via: happenstance
methodology, or expression of internalized well known types, or via a more
formal process.

------
repler
I feel like people get hung up on UML conventions and try to follow every
process exactly and create every piece of documentation perfectly.

That was never the point. The point was to be able to communicate complex
concepts in a way that people could understand and work with.

Bravo for having done that!

------
cuillevel3
I remember reading somewhere, that it's wise to avoid naming your classes
after design patterns. It only leads to discussions about technicalities.

Makes sense to apply this to bigger designs, discussing the concepts is more
important than following the book by the letter.

------
jmull
Hm... good software architecture is always clear and usually simple. So I
think the title here is self-contradictory.

I do agree with usually using custom diagrams rather than, e.g., UML ones.
Diagrams need to communicate. The problem with the formally defined ones is
that they communicate what they are specified to communicate, not what you
need to communicate. As a result you end up with perhaps multiple diagrams to
cover the concept, or you need to add text or an ill-fitting custom overlay or
custom exceptions, etc. Also, people who don’t create these diagrams regularly
(a large part of your intended audience) have trouble remembering all the
intricacies of the diagram language, so important concepts are made obscure
rather than clear.

Anyway, you want to be focused on communicating certain concepts, not building
a correct diagram.

------
tradichel
Make sure you are preventing data breaches when you skimp on architecture via
proper threat modeling and best practices. Some recent breaches result from
poor architectural choices. @2ndsightlab

------
oftenwrong
Nobody sets out to build something that is over-engineered. Over-engineering
happens in pursuit of a "clear and simple" solution.

------
ahaferburg
I read one paragraph, and don't even know what it's about, and I get pestered
to sign up for something with my email. Not cool.

------
dqvsra
Just don't mix view with any business logic, keep them separated, and things
will go right! ;)

------
foobar_
OOP is overrated. OOP programmers are the equivalent of bible-thumping
evangelicals.

------
mrpickels
I read the comments and see there are two types of engineers - conservatives
and liberals, those who work for big corporations, draw UML diagrams with
factories, bridges and facades and throwing arguments that because of some
regulations or privacy policies your architecture can change and you need to
be prepared for it. Those guys are right.

More liberal engineers are saying that keeping code simple is the key and to
keep it simple you need to be smart and creative. Those guys are right as
well.

Now back to reality, the conservative developers will always work on the code
that was written by liberal developers because the latter deliver sh*t in time
that works and carry the business on their shoulders, where the first makes it
work in another scale.

Conclusion - there are different types of engineers and our responsibility is
to accept that humans are not machines and somebody likes to CREATE vision and
value, others like to manage huge system that are complex.

~~~
Gibbon1
30 years ago? I talked to an project manager that designed and built
factories. He said there were three kinds of engineers and techs he hired.
Design, Construction/Shakedown and Maintenance. Design requires being creative
and methodical. Construction and Shakedown requires the ability to gleefully
beat chaos into submission. And Maintenance is the methodical following of
rules and procedures. He hired three different groups for these tasks because
they would go insane or be overwhelmed if they were doing the wrong job for
their temperament and skills.

------
known
Unlike Simple Design, Redundancy is built into Software Architecture

------
_pmf_
If I had more time, I would create a cleaner and simpler design.

~~~
kmote00
"I apologize for the length of my letter. I'm afraid I did not have the time
to write a shorter one." -Blaise Pascal (et. al.[1])

[1] [https://quoteinvestigator.com/2012/04/28/shorter-
letter/](https://quoteinvestigator.com/2012/04/28/shorter-letter/)

------
Richard_East
This is why ex-startup-founder product managers are so in-demand if they ever
go back as employees. Releasing your own software to the market, even with the
help of a small team, demands a level of design finesse which is difficult to
realise in a big corporation. The results in terms of customer feedback,
market fit, product functionality are also easy to evaluate for hirers
compared to NDAd or vague prior work experience.

Markets are not fair or uninfluenced by luck, and not every product or startup
will succeed financially or provide the lifestyle the founder desires. But
I've found that ex-founders make excellent picks as employees since they have
the ability to work seamlessly across an organisation, particularly with
software devs, and understand fundamentally which product features and
developmental changes are worthwhile pursuing.

