
Winning is the worst thing that can happen in Vegas - mh_
http://37signals.com/svn/posts/3384-winning-is-the-thing-that-can-happen-in-vegas
======
tomdale
Where is this strong reaction to over-design coming from? Full disclosure: I
earned most of my salary in 2012 doing consulting. Fortunately, most of it was
from working on open source projects. But a component of it was going in and
getting our hands dirty in clients' apps.

Not a _single one_ suffered from over-architecture; indeed, the common thread
to all of the problems I saw is that people would intentionally put off the
"just in time" architecture improvements that DHH recommends in favor of just
one more feature.

By the time we got there, the whole thing was about to collapse under its own
weight.

And that's exactly my point: this seems to be a solution in search for a
problem. Under-architecture is much, much more widespread of a problem than
over-architecture, based on my own anecdotal experience and the horror stories
told by my friends over beers.

Software engineering is about striking a balance between choosing an
architecture that can grow with your project while being simple enough for you
to ship features _today_. The dogmatic approach from both sides in this
ideological war is bizarre. Remember that prescriptivism against
prescriptivism is still prescriptivism.

~~~
d4nt
I've experienced the problem of too much flexibility when working on some
enterprise software products at a former employer. We believed we were doing
the right thing by keeping the analysis phase short and just building a
generic capability for roughly what the customer needed. Boy did it cost us!
Testing, support and future rounds of analysis all took much longer because we
had to deal with all the flexibility that the system had. And the customers
didn't appreciate it much either, they were only concerned with their limited
set of use cases.

------
pavel_lishin
> _Every little premature extraction or abstraction, every little structure
> meant for “when we have more of this kind”, every little setting and
> configuration point for “things we might want to tweak in the future”. It
> all adds up, and at a dangerous rate._

My experience is exactly the opposite. Every time someone's told me, "A user's
account will only ever have one event associated with it", or "An order will
only be paid for with one credit card" or "A credit card payment will only
ever apply to one order", that someone is wrong, and it ends up costing us
days to fix.

~~~
RyanMcGreal
I came here to post something similar. YAGNI has burned me a lot more times
than premature optimization. Perhaps it makes more sense to draw a distinction
between designing for flexibility and what we might call _naive flexibility_ ,
or optimizing for use cases that a more experienced developer would know are
highly unlikely to be needed.

~~~
MartinCron
Of course, you don't (can't) see the times where YAGNI has helped you.

~~~
dasil003
This thread is confusing to me so I'm probably misunderstanding a few things.

First Ryan's post says he's saying something similar, except it appears to be
opposite to the post he's replying to.

Then you say you can't see the times where YAGNI helped you, but that's
neither true literally and also in spirt. Literally because it wouldn't be
YAGNI if you did actually need it. But more importantly I have often
discovered some architectural choice or unused feature stubbed out from years
prior that saved me a ton of time in the here and now.

~~~
RyanMcGreal
I was replying to pavel_lishin's parent comment, in which he noted that he has
been burned many times by _not_ optimizing early for flexibility:

<http://news.ycombinator.com/item?id=5003341>

My experience is similar to pavel_lishin's, and our experiences are contrary
to the author of the article.

I hope that helps to clarify the first bit, anyway.

------
fusiongyro
A lot like his post yesterday, this is really more content-lite self-branding
from DHH. I get it--you ain't gonna need it. Yeah, yeah--you're opinionated.
Cool.

~~~
dasil003
I'm not one for the usual HN cynicism, but I have to agree. DHH is much
smarter than these trite truisms. This would be an impressive article for an
18-year-old upstart, not someone who's ostensibly a thought leader in
programming.

------
benjaminwootton
Say you have a simple application and the only possible use case is to
increment an account by $100.

Should you write the function as

    
    
      account.credit_100_dollars()
      account.credit_dollars(100)
      account.process_transaction(new credit_transaction(100))
    

I have to say I prefer option 3 to option 1 even considering YAGNI. It's
better OO, it's more testable, there's more potential for reuse in other parts
of your application etc.

Interestingly, when I started as a developer I might have written something
closer to the first option. After a few years I would have gone for something
closer to the third option. Nowadays, I'd probably go for the second option as
I've hopefully learnt to strike a balance in the abstractions I create.

~~~
glenjamin
None of those three examples expresses intent. _Why_ are you crediting 100
dollars? Is it a refund, is it a loyalty reward, a signup bonus?

    
    
        account.award_loyalty_bonus()
        account.award_welcome_bonus()
    

This is closer to the first option, but will actually model the behaviour of
your application using domain terms.

~~~
rprasad
If I understand what benjamin is saying, these would be written as:

account.process_transaction(new loyalty_bonus(bonus_amount))

or possibly

account.process_transaction(new bonus(loyalty_bonus_amount))

depending on the business logic.

~~~
glenjamin
Not quite, the point is that the caller doesn't care how much the loyalty
bonus is, only that the bonus it is awarding is for loyalty.

The value of the bonus then gets captured in the domain object. If there is
enough related logic to justify having a loyalty bonus object, then you might
have

    
    
        account.award(LoyaltyBonus.new)
    

Or, if we're going to start slicing things up like this, we might go for:

    
    
        LoyaltyBonus.award_to(account)

------
ezl
Loved this post, but _"The casinos in Vegas are primed for this by making it
relatively likely you’ll win something early on."_ is false.

Casinos in vegas have no idea if you're deep into a gambling session or not.
They take small statistical edge on __every __transaction (or a rake).

~~~
simonholroyd
Also, the Nevada Gaming Commission frowns upon changing the odds of a game
while a gambler is playing (at least for slots -- I believe this is true for
most other games also): [http://www.lasvegassun.com/news/2008/feb/17/dont-
worry-your-...](http://www.lasvegassun.com/news/2008/feb/17/dont-worry-your-
slot-bets-are-still-safe/)

------
d0m
Funny writing coming out of an author of Ruby on rails. "The ability to say
No". So.. once upon a time, there was the decision to create web apps. Rather
than using the existing languages and tools, a whole new web framework was
created from scratch. Let's talk now about abstraction and _shit_.

Note that I am, by far, _not!_ against the creation of library and new
framework. It just so happens that this article is ironically funny concerning
that aspect.

~~~
cmccabe
Everyone loves architecture, just as long as they're the architect.

------
bornhuetter
This is incorrectly titled - should be "Winning is the _worst_ thing that can
happen in Vegas".

~~~
xuki
dhh did a typo, HN automatically picked up the old title. Maybe some mod
around here can change it.

------
DoubleCluster
You really can't be a good developer on rules of thumb. The best code just
does the minimum it needs to do (YAGNI) but still has the necessary
abstractions for for easy extensibility in the future. It's a fine line to
walk on.

------
rwc
Anybody get the sense that DHH's New Year's resolution was blogging more?

~~~
lukeholder
He has admitted all these posts have been triggered by the ruby rogues podcast
private mailing list where heated discussion is going on currently.

~~~
smacktoward
If only he would share some of that context in the actual posts. Reading them
is like watching someone argue with another person you can't see or hear.

------
ojbyrne
"The casinos in Vegas are primed for this by making it relatively likely
you’ll win something early on" seems like mushy thinking. Perhaps they make it
relatively likely you win at any time, but there's no difference between
"early on" and any other time.

~~~
e1ven
If a game can give way to win back small amounts frequently, but still lose on
the long-game, it can trigger this effect.

You're still likely to lose in the long game, but get small wins frequently
enough to keep you from quitting.

------
jrogers65
I think that there is a middle ground to be found in this aspect of
development. On the one hand, you don't want to overengineer your code. On the
other hand, requirements _will_ change.

Based on this, I personally design object models to be easily extensible. The
guidelines are simply best practices (separation of concerns, methods which
only do one thing, minimising side effects as much as possible). Nonetheless,
I agree that the minimum should be used given that things which should be
abstracted have been abstracted.

For example, I was implementing reports recently. Overengineering is coming up
with a complex reporting engine which managers can use to create anything they
want. Underengineering is writing each report from scratch. The golden middle,
in this case, was a lightweight framework where you extend a base class,
specify the query and you're done. Everything else is automagically taken care
of. So one need not worry about fetching the actual results, displaying them,
sorting them, adding the report to the menu, etc.

------
Encosia
I generally agree with his overall YAGNI message. Architecture astronomy and
smart complexifiers on projects that could be simple are a couple of my
biggest development pet peeves.

I'm not sure I follow how that equates to technical debt though. If anything,
unnecessary but well-implemented abstractions and over-architecture are the
opposite of technical debt, aren't they?

In my experience, it's all too easy to find developers who will "say no" too
eagerly, erring on the side of sloppy copy/paste duplication, inconsistent
structure, and poor maintainability overall. Given the choice, I'd much rather
walk into more projects with too much architecture than the one with little-
to-none which are more common.

------
grandalf
Just as many best-practices can be applied too early, they can also be applied
too late. DHH's rant could just as easily be aimed at too-late application of
such practices.

I've found that when I deliberate over these kinds of questions too much it's
usually because my design is not quite right, and that when I eventually
discover an elegant design the path to flexibility presents itself in an
optional and unobtrusive way.

Many designs are possible but the right design is often the one that is easy
to think about at various levels of complexity.

------
jasey
I agree with this ideology. However what I think what is missing from the post
and the comments is mentioning that if you are going with a under engineering
design philosophy you should be constantly be refactoring the code.

------
EGreg
Opinionated as usual, mr Heisenmeyer-Hansson. But his way is not always the
only (or best) way :-)

Still I respect his opinionatedness!

------
ianstallings
Poker players refer to the phenomenon as "winner's tilt". It will make you go
broke if you're not disciplined.

------
tokipin
unfortunately i think many people see that kind of "formal" architecturing
_as_ software engineering

related: <http://zedshaw.com/essays/master_and_expert.html>

------
michaelochurch
I'm not sure I like the title. It seems to be clumsily conflating casino
gambling with bad software practices. The first is not a good metaphor for the
latter, especially since most of those premature abstractions come out of FUD
and attempted risk aversion. (We won't be able to scale if we don't use design
patterns!)

However, the insights into premature abstraction are good.

Here's a beautiful, and relevant, essay from Steve Yegge: [http://steve-
yegge.blogspot.com/2008/08/business-requirement...](http://steve-
yegge.blogspot.com/2008/08/business-requirements-are-bullshit.html)

~~~
SatvikBeri
I strongly, strongly disagree with the idea that you should only build
products where you're the end user. There are many interesting problem domains
where the end users aren't suited towards building the solution.

My company does Machine Learning for Sales. There aren't a huge number of
people who can do both programming and statistics well. Add Sales to that
skillset and there are, what, 5 people in the world who can do all 3? The odds
of finding a sales person who wants a predictive sales tool and has the
capability and interest to write it are vanishingly small.

For a consumer-oriented example look at Coursera or other MOOCs. Andrew Ng is
not a Coursera user (i.e. student.) He understands students, and that's
enough-MOOCs provides enormous value because they solve an important problem.
Students would have had a much harder time creating Coursera than Ng.

~~~
michaelochurch
_I strongly, strongly disagree with the idea that you should only build
products where you're the end user._

I as well. Most software sucks because the people building it aren't
motivated. Building for oneself is one source of motivation, but it's myopic
to assume that it's the only source of motivation that works.

