
Poof and then Rails was gone - ryansouza
http://patmaddox.com/2014/05/15/poof-and-then-rails-was-gone/
======
stiff
The problem with software is that it is too easy to get it working. If you
would do completely stupid shit while designing an analog electronic circuit
you would get completely stuck in your "inventions" very soon and would not be
able to deliver anything working beyond the simplest stuff, the difficulty
would just force you to adapt a sensible design approach or resign from doing
any electronics in the first place.

In software engineering, on the other hand, the kind of wankery presented here
lives on for years because there is no reality check - as long as a group of
people feels good about themselves inventing fancy words and "techniques"
without putting in too much effort into anything of substance, fads of this
kind can live on. They can even deliver products written in this manner and
get paid, for the projects work, as far as most business projects are
concerned, it is simply that the code is just awful to look at.

Meanwhile, serious software from "firmware" for space shuttles, through huge
game 3d engines, compilers, operating systems, to scientific software manages
to get developed without having any need for this sort of thing. Somehow it's
always the rather trivial software that gets those super-"architectures".

~~~
angersock
All of your examples don't exactly make the point you're trying to make:

Ask anyone who's had to debug game engine code, compilers, operating systems,
or the worst of the lot, scientific code.

Most of those systems would actually _benefit_ from proper design and
architecture, but people like you decrying their "wankery" have relegated such
introspection to the dustbin.

And _that_ attitude is why software engineering is mostly a dark joke.

~~~
timr
I've written more scientific code than most people here, and the OP is right:
it's the last place you want wanker abstractions.

KISS applies to scientific code in spades. The concepts are hard enough to get
right without all sorts of meta-logic muddling your thinking. Only when
applications are truly trivial (i.e. "boring") do developers go on
architecture spaceflights to keep themselves entertained.

~~~
angersock
The best way to keep things simple is to keep them small and composable,
right? Like, say, in the Unix way?

I'm all for brutally-efficient and single-minded code in domains like
mathematics or simulation modeling, where things like object encapsulation
maybe don't make a great deal of sense (classic array-of-structs vs struct-of-
arrays sort of thing).

That said, keeping that stuff neatly boxed and then moving everything else out
(say, file I/O, logging, whatever) into neatly abstracted boxes makes sense.
More sense than most of the monolithic piles of Matlab and Java and C and
Fortran I've seen, because people were rushing to finish a paper.

But hey, it's not like the next generation of grad students has anything to do
_but_ spend long hours debugging poorly-documented and poorly-designed code,
right?

And it's not like there is any sort of commercial financial or reaction
modeling software that needs to be anything other than inscrutable monoliths,
right--you know, something which could actually hurt somebody physically or
fiscally. Performance is king, after all.

(Hint: people who sacrifice engineering and design for performance or
simplicity deserve neither.)

~~~
timr
The choice is not _" monolithic piles of Fortran"_ or abstraction hell...there
is a middle ground.

All of your comments on this thread seem to be predicated on the assumption
that this blog post is an example of something _good_. It isn't. It's a
complicated, overwrought non-solution to an imagined problem.

Nobody here is arguing against abstraction, but abstraction needs to be used
judiciously, and the best abstractions don't stray far from the application
domain. It's a subjective thing that comes largely from experience, but you've
likely gone off the path to enlightenment when you start creating
("hexagonal") meta-frameworks to create framework frameworks.

~~~
angersock
You and I know there is a middle ground, but there is something very appealing
about deriding the (hard) work of building abstractions and meditating on
design principles in favor of "get shit done" coding.

This article was an interesting little exploration--mostly point out that by
not using rails but by conforming to the interfaces you could do some
interesting things. It was a harmless little piece, not something you might
want to do in production but interesting nonetheless in its own right.

The tone of my comments is in regards to the top-level objections and phrasing
these people are using--"wankery", "architecture astronauts", etc.

Look, I get it; most of us at one point or another have dealt with
JavaEnterpriseFactoryBridgePatternAdaptorAnnotationAnnotationFlyweights and
have had to meander through scores of abstracted calls to finally figure out
something that should've been a direct function invocation. The dot-com bubble
hurt many programmers, sure. Enterprise Jabba is a bloated king in a crumbling
castle; whatever floats your boat.

There _are_ people--in this very thread!--who _are_ arguing against _any_
abstraction. They do so in the name of performance, and in the name of domain
modeling, and in the name of a dozen other half-articulated little fears and
inconveniences.

I've had to deal with code written by academics that implemented brilliant
solutions to some problems, and yet remained impenetrable. If asked, "figure
it out yourself". These are the same chucklefucks that don't comment their
code, that are uncooperative on projects trying to clean up and make libraries
out of their work, and generally are people who think that making it out of a
doctorate program with a paper about their tiny slice of new human knowledge
somehow grants them any weight whatsoever in discussion about software
engineering or working on teams.

It makes sense that they'd be against abstraction--them and the trading folks
and game developers and everyone else whose livelihood depends on
excruciatingly-specific implementation details which are nothing more than an
artifact of their time, a form of technical arbitrage which pays for their
miserable existence.

Of _course_ they hate abstraction, because it is very hard to convince
somebody of something when their livelihood depends on them not understanding
it!

------
ubernostrum
So... poof, and then Rails was J2EE?

I have a deep dislike for overabstracting a system merely because someone has
a list of hypothetical use cases. And make no mistake: it is always about
supporting the hypotheticals, never about supporting what's actually really
needed by the system.

Down this road lie dozens of layers of abstracted factories and strategy
implementations which exist just in case someone wants to "persist" a
relational object over a serial printer line. YAGNI.

~~~
adamors
I don't understand how _anything_ on HN that discusses a more complex software
architecture is immediately called J2EE/enterprisy and dismissed.

Is this because the majority of the community is self thought? Or is this
because most of you only build MVPs which are mostly CRUD apps (and therefore
don't know from first hand experience the benefits of a modular system)?

The constant negative reaction to anything a little more complex is frankly
laughable.

~~~
jdminhbg
Similarly, any criticism of overcomplexity is immediately met with a dismissal
as anti-intellectualism rather than a justification of why it's necessary.

> Or is this because most of you only build MVPs which are mostly CRUD apps
> (and therefore don't know from first hand experience the benefits of a
> modular system)?

This is what I use Rails for, and its entire reason for existing. It's a set
of conventions for CRUD apps, not a general-purpose language for building
distributed databases and coordinating space missions.

The problem with these complex software architectures is that they're
decoupling Rails from the database, but why in the world would you want to do
that? Rails is great because it manages the the meeting point between web
requests and relational databases in an elegant, repeatable, commonly-
understood way. If you need a complex, general-purpose system that only
sometimes will talk to a database for persistence, why in God's name did you
use Rails?

~~~
ryanjshaw
> Similarly, any criticism of overcomplexity

Come on. Nobody is defending "overcomplexity", which is by definition a rather
indefensible position. The issue is the frequent arrogance exhibited here by
commenters who insist that certain commonly and successfully used design
patterns have no place in the world.

~~~
jdminhbg
Of course I mean defending against the charge of overcomplexity rather than
defending overcomplexity itself.

I am sure there are arrogant commenters around, but these commonly used design
patterns applied in this case have made his code worse for next to no
practical benefit. Besides test speed, there's no reason you'd want to divorce
your Employee model from the database it lives in -- the fact that
ActiveRecord reflects against the database to decide what attributes an
Employee has should be a clue that coupling to the DB is the point of using it
in the first place.

------
jowiar
When I read code like this and find that half of the tests are, more or less,
a typechecker, it reduces to an argument for static typing.

~~~
voxtex
Completely agree with you. Many of the tests don't do any kind of assertion,
simply ensure that an exception isn't thrown on the invocation of a method. An
interface defined in a static language would render the majority of these
tests unnecessary.

------
carsongross
Having once been a platonist about this sort of stuff, I've rarely seen heavy
code architecture work out well in practice (not so with _system_
architecture.)

I'm reminded of the various Evolution Of a Programmer jokes which end with the
master programmer writing the same code as the beginner programmer.

~~~
sanderjd
I've always read into those Evolution of a Programmer jokes that what the
master learned through their evolution is the right and wrong _time_ for all
the complicated stuff they did in the earlier phases, and that anything simple
enough to form the basis of a joke is merely the wrong time.

------
jdminhbg
Excellent. Proof that you can make your code an unapproachable mess to a new
team member by throwing out Rails conventions, and in return you get the much
greater benefits of shaving 100 ms off your test run times and the ability to
run it from the terminal.

------
scottschulthess
I actually think that the authors rspec code is too abstract (at least for
me). Unfortunately I think he's proving DHH's point.

------
ChrisGaudreau
This code is painful to read. As somebody new to a team, how can you "extend"
code when you don't have a clue how the rest of the system works because
somebody else decided it'd be a good idea to unit test controllers and
abstract everything away because "we might need it someday"?

------
jrochkind1
I'm not a huge fan of Rails architecture neccesarily, but I have to admit I
have trouble following the 'hexagonal architecture' stuff, even in simple
examples like this.

It does seem to be a lot of abstraction. Of course, with abstraction comes
flexiblity, that's the point, I get it. But with (some kinds? all?)
abstraction also comes complexity and cognitive load for the developer. If
you're not careful, you end up in Java FactoryGeneratorFactory land.

(I hope the next step in the 'hexagonal architecture' isn't using an XML file
to specify all the linkages and concrete classes in use. How else do you
specify what concrete @db etc your controller is instantiated with?)

~~~
edwinnathaniel
... and of course for those who applies modern Java development patterns, we
no longer see plenty FactoryGeneratorFactory.

I find it a bit odd that the community who has railed Java hard suddenly came
up with something more complex than... _gasp_... the solution in Java-land.

~~~
jrochkind1
I didn't mean to imply that everything in Java was over-engineered, just that
certain historical common Java practices were examples of what happens when
you over-abstract and over-engineer. Certainly over-abstracting and over-
engineering happens in every language too though, it's a hazard of the trade.

What community is it that you think has "suddenly" come up with what solution
that's more complex than what "the" solution in Javaland? I'm not even sure
what you're talking about. There are of course many solutions in Javaland,
naturally, and in every other code land.

I think engineering code, especially code shared between multiple
developers/installations, is a constant tension between simplicity and
abstraction/flexibility. It's sometimes possible to optimize both, but it
requires a lot of skill and a lot of domain experience, and domain experience
especially seems to be under-valued and under-present in the current
environment. (Plus if the domain changes fast enough, nobody ever has enough
domain experience!)

I think individual developers, as well as teams and communities (language-
based or industry/domain-based) often swing from end to the other. This legacy
thing is too complicated, let's start over with new principles to keep it
simple! This simple thing isn't as flexible as I want, let's add in some
abstraction to make it possible to do what everyone needs; then do it again;
then do it again; then start over at 0.

------
lobster_johnson
Like others here I'm not sure if this is a joke post or not, but... the
TerminalAdapter example is not an abstraction. It's simply reimplementing a
very specific protocol that implements "render" and "redirect_to". This
protocol is not something that could automatically be adapted to other
scenarios than HTTP — say, to a mobile app or to a desktop GUI app. The
terminal, for one, might "render", but it cannot "redirect".

------
mercer
I might just not be very good at this programming thing, but to me these kinds
of articles on testing often (not always) remind me of my annoying tendency to
implement a comprehensive productivity approach (often combined with buying
yet another task app) that, on paper, really should help me keep track of my
life. Usually it's a variation on Getting Things Done, which stands out in its
exhaustive, all-encompassing, fine-grained approach.

In practice the whole falls apart after a week or so because I forget to do
things the right way or because I don't feel like processing my 'inbox'...

Instead, I seem most effective when I write down my top three tasks of the day
on a piece of paper.

Maybe I get that feeling because I've mostly experienced companies where
testing didn't really seem to have much of an effect. Whenever I asked about
this lack of efficacy, the answer was usually "that's because we're not
implementing it completely!"

Which is exactly what I hear (and suggest) whenever I or someone else falls
off the GTD wagon.

Am I completely wrong about that feeling? I mean that as an honest question,
as I truly don't want to be negative and I'm way to inexperienced to be
cynical about these things :-).

------
htp
Cached version, as the site is currently down for me:

[http://webcache.googleusercontent.com/search?q=cache:0-I-y0x...](http://webcache.googleusercontent.com/search?q=cache:0-I-y0xrctsJ:patmaddox.com/2014/05/15/poof-
and-then-rails-was-gone/+&cd=1&hl=en&ct=clnk&gl=us)

------
jhuckestein
I love thinking up intricate software design patterns as much as the next guy.
They'll cater not only to the current requirements for my project, but also to
all possible future eventualities. It'll allow me to, by simply changing one
or two lines of code, change my entire database backend, implement system-wide
magic caching and to expose my HTTP service as a custom telnet protocol.

The issue I have with posts like this is that they are decidedly NOT just
about thinking up wild new designs. Instead, they claim that these designs are
somehow BETTER. Unless you can give me a real world use case, I won't believe
you.

------
abk
I kind of skimmed the post, so maybe I'm missing something, but what exactly
is the "architecture" described here? Dynamically-typed languages will allow
the passing around of objects of different types as long as they implement the
necessary methods. This is a nice property in some cases, but a lot of times
I'd prefer to have static-typing and well defined protocols. It seems like
that post ignored the more important parts of the discussion.

------
briantakita
Frameworks are like cookbooks. They teach you how to make meals.

It's way more fun and tastier to make your own meals.

------
JoelMcCracken
This is one of the cooler blog posts I've seen in a while. Very nice.

------
Dorian-Marie
Poof and your site hosting is gone

~~~
daviding
The delivery of the page has been abstracted via protocols, and is keeping the
application logic independent of persistence and UI implementation details.
The 50X is just a side-effect. :)

------
wnevets
and PHP keeps on ticking

