
Analysis of Software Architectures - fatagun
http://www.firatatagun.com/blog/2016/01/09/analysis-of-software-architectures/
======
alexandercrohde
This analysis brings to the front a personal frustration, and I imagine it's
not unique to me.

This article discusses some architecture techniques, but moreover, it buys
into a Culture of Architecture that we don't have a word for yet. This CoA is
predominant among Java engineers who worked at large, slowly-dying companies
(e.g. IBM).

The issue with the CoA is that it cares more about buzzwords than quantifiable
claims or objective measures. CoA was once addicted to microservices, when
that model failed it'll be "all about" another, and so on. Rife with academic
good-sounding CoA words that nobody can argue with like "SOLID" and such.

To be a little more concrete, "Broker topology" is a 25-cent word for a 1-cent
idea (and it's not the only one, see every keyword in bold in the page, it's
almost like a college textbook). There seems to be an implicit assumption in
CoA that there is a finite number of architecture patterns and they must be
learned by name.

Again, to be more concrete, "layered" architecture is an oversimplification of
a fundamental idea (abstraction) in engineering.

This textbook-esque presentation also really misses the spirit of coding. It
presents a UML (another CoA must) of "Event-Driven" architecture, then one of
"Layer" Architecture, without really explaining if these can be combined or
are mutually-exclusive (of course they could be combined). But by treating
them as named nouns it creates a misleading and complex language around
fundamental ideas.

~~~
skrebbel
I _violently_ agree, and I suspect most of HN does.

There's an associated danger though: I find that many startup hackers actively
dismiss good ideas (and even entire programming languages) simply because they
smell a bit of CoA.

Even the CoA crowd occasionally comes up with truly good ideas that have way
more substance to them than the meaningless patterns mentioned in this
article.

As an example: My personal pet peeve is the startup world's ignorance of
Domain-Driven Design and CQRS (Command-Query Responsibility Segregation). If
you want to make scalable backends, I really recommend you read up on CQRS,
it's practical and it fits modern ideas. Most examples are in C#, but _you 'll
survive_.

For frontenders, CQRS is basically Flux on the backend, kinda sorta. It ought
to be super hip right now but it isn't, and I suspect that's only because it
comes from C#-o-world and has a ridiculous unpronounceable acronym.

~~~
perlgeek
> As an example: My personal pet peeve is the startup world's ignorance of
> Domain-Driven Design and CQRS (Command-Query Responsibility Segregation). If
> you want to make scalable backends, I really recommend you read up on CQRS,
> it's practical and it fits modern ideas. Most examples are in C#, but you'll
> survive.

Most starts never become successful enough to have to worry about scalability;
in fact, if they do, it's almost a luxury.

I don't have experience with CQRS and event sourcing, but it does seem to come
with its own share of problems, for example dealing with changes of the data
model, which I suspect would happen often in young businesses.

~~~
Terr_
It's very easy to do CQRS without Event-Sourcing. ES is really a separate kind
of architecture-piece that's concerned with how you _mutate_ your persisted
data.

For example, at work I've got a CQRS system where the MySQL database looks
pretty much like you'd expect from any other system. (Customers table, one row
per customer, etc.) It's still CQRS because writes and reads occur through
different paths, and writes can have side-effects to proactively-build
readable data. For example, "Top 100 Happiest Customers" might be its own
table--managed by application code--rather than view or query.

~~~
perlgeek
If you do it that way, you don't get the famed scalability; it's still limited
by the scalability of the mysql backend.

~~~
Terr_
Not sure exactly what capability you're referring to with the "famed"
scalability, but my point is that CQRS in no way requires Event Sourcing, and
offers its own set of benefits. (It's also a helluva lot easier to do, or un-
do.)

In particular, CQRS helps you make a sane architecture for "read models",
where certain features (say, a homepage showing a hard-to-calculate
leaderboard) are simple queries against a data-source designed specifically
for that feature. The backing data-source is kept up to date by application
code as a side-effect of your "real work".

This means you can substantially reduce the runtime load on the database as
well as reducing how much application-logic "leaks across" in
triggers/procedures/views. Since your database is often the "bottleneck of
last resort", this means better scalability.

------
perlgeek
This articles makes the assumption that features are easier to develop if
subsystems are broken up into separate components, with separate data sources
and deployments.

But experience shows that this is only sometimes the case. Monolithic
applications with a big SQL engine as the backend have the advantage that you
can do joins very easily. If the data is split into three microservices, you
spend much more time thinking about how to do the these cross-service joins
more efficiently, narrowing down the amount of data you have to fetch from the
other services and so on.

People argue that cross-service joins should not be necessary, but that's also
easier said than achieved; in reality, they tend to show up, no matter how
carefully you partition the services.

~~~
amelius
I guess that not just the joins become more difficult in a partitioned system,
but especially transactions. Maintaining transactional consistency across
multiple services seems to me like a nightmare. Even writing tests that
address consistency could be very difficult.

~~~
virmundi
Often you don't worry about transactions across services. I know that someone
will say we have to have them. In such cases, fine worry about them. In
everything else, either isolate the write side of a transaction in one service
or don't require them.

~~~
paulddraper
"don't require them".... Transactionlity is principally dicated by the
requirements to the architecture design, not the other way around.

" isolate to one service " Yep, a single service with a single database, as
mentioned.

My point here, like the earlier one, is that there are a lot of situations
where multiple services don't fit the domain. In fact, very many, given the
extreme complexity around transactions.

------
lordnacho
Does anyone find this a bit contrived? When you build a complex piece of code,
there's always more than one way to draw a diagram of it. For instance, I've
written trading systems.

\- It's event based because there are publishers and subscribers.

\- It's layered because there's a UI that draws stuff from the business layer,
which takes data from a database

\- It's plugin because it uses a DI container, which decides exactly which
services to run on which machines.

------
userbinator
As someone who worked briefly on "enterprise" software (in Java), this article
brings back memories of preposterously complex and uncomfortably bureaucratic
monster-systems that were a nightmare to work on. It also reminds me of
[http://www.joelonsoftware.com/articles/fog0000000018.html](http://www.joelonsoftware.com/articles/fog0000000018.html)

~~~
geodel
Good for you. I keep working more or less on similar kind of systems where an
2 line change in a method turns out 20 code + 5 config file change.

------
kisstheblade
Regarding microservices. They sound nice in theory, and certainly work for
some cases. But what is the common pattern to handle a situation like this (in
a performant and "scalable" way).

Say you have two (completely separate micro-) services:

\- Order service \- Customer service

Now when a customer buys something, it is stored in the order service. But how
is the customer information referenced in the order service? Do you store just
some "customer id" and let the clients of this service worry about what it
means? Or do you store some customer information also in the order service (in
memory cache or in the services own datastore, both solutions which then need
to synchronize this data somehow)?

Eg. how about a situation where you want to display a sortable list of orders,
and it includes the columns for the customers first and last names. How can
you sort on these columns if the order service doesn't know anything about the
customer other than some "identifier"? Especially if the list is paged so you
can't look up all the needed customer's information.

Just thought about this because this article (and many others) tout
microservices as some kind of silver bullet.

~~~
perlgeek
Denormalization is often a practical answer; the order service keeps an
(immutable) copy of the customer's name and delivery address.

If the customer changes the address, it will only matter for new orders.

One can argue that this is actually a sensible behavior, because there's a
point after which you can't change the delivery address anyway (once it has
been handed over to the delivery service, for example), and this behavior of
copying the address just moves the point a bit.

Likewise, when a customer buys a product, a copy of the product description
and price is included in the order; if the price changes between the checkout
and the delivery, it's good if that isn't reflect in the amount that is
invoiced. After all, the checkout established a contract that cannot be easily
changed retroactively.

~~~
Terr_
Right, I think this is an example of the importance of good requirements and
scenarios before coding.

While programmers may prefer to create denormalized "model of everything at
once", some business processes require copies and snapshots. Not as
implementation details, but directly.

------
TeeWEE
I think the article is not bad. It just mentions some patterns and compares
them. of course they can be composed.

While I agree an "architectural astronaut" approach to software engineering is
wrong, we still have to understand the main underpinnings of software
engineering. data, separation of concerns, composability, state vs non
stateless.

recognizing patterns in granular code as well as in system composition is
important. And naming them makes communication easy. PubSub, Visitor, Mvc, etc
are still useful names.

What I think is funny is that the java implementations are often big compared
to the same solution in functional languages.

Static OO languages often need "software patterns" such as wrapper objects,
where they are nonexistent in functional languages. imho

------
icebraining
Related: "The Architecture of Open Source Applications"
([http://aosabook.org/](http://aosabook.org/))

They've recently released new chapters of the upcoming fourth volume.

------
koide
This analysis is a badly regurgitated copy of the free O'Reilly e-book about
software architectures by Mark Richards located at
[http://www.oreilly.com/programming/free/software-
architectur...](http://www.oreilly.com/programming/free/software-architecture-
patterns.csp)

It's a lot worse than the original.

------
stcredzero
This website badly needs editing. There are a lot of bad sounding and awkward
sentences.

"For several years now, many enterprises and companies employed this
architecture in their projects and it almost became the de facto standard
therefore it is widely known by most architects, developers and designers."

"Layers don’t have to know about what other layers do, in example: business
layer doesn’t have to know how data layer is querying the database, instead
business layer expects some data or not at all when it invokes certain method
in data layer."

"Some of the features and functionality doesn’t need to go through all the
layers"

"If you have 20 percent of requests just passes through layers and 80 percent
of requests does real processing, it is fine, however if the ratio is
different then you are having sinkhole anti-pattern syndrome."

"Event mediator doesn’t do or knows any business logic, it just orchestrates
the events."

------
hnruss
The chart at the bottom of the article is incorrect in at least a few spots:

\- The article does not identify difficulties with testability or development
of the MicroService architecture.

\- The face shown for Layered architecture's "Development" is colored
incorrectly (since it is a smiley-face and the article text supports that).

