Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Thoughts on Software Quality (facebook.com)
69 points by daveman692 on April 18, 2011 | hide | past | favorite | 20 comments


Resisting the knee-jerk urge to rewrite a piece of software from scratch is something that has taken me a while to master. I'm much more levelheaded about it now. I try to think through whether or not there is a legitimate reason for the rewrite. Sometimes that reason certainly exists, but I've found more often than not that doing so is overkill. It's a lesson that has certainly saved me a lot of time since and allows me to focus on more important tasks.


Out of curiosity, what would you say are some legitimate reasons for doing major rewrites? I'm currently going back and forth on whether or not a rewrite is a good idea, and would like to hear what some people would consider good reasons.


Joel ("On Software") Spolsky might say never. If you have a system that is smelly but working, then rewrites of individual subsystems lets you evolve the working system into something cleaner without any discontinuity of service.

http://www.joelonsoftware.com/articles/fog0000000069.html


Yeah, I've read that before, and other articles like it. Does the feeling of 'this code sucks, needs rewritten' ever go away after inheriting an old, smelly, but working codebase?


"Sustained software quality is an extremely difficult challenge." - (from the article)

Quality can mean a lot of different things. Elegant, simple to understand code. Adherence to current best practices. Modular. And the list goes on...

But the most important part of quality for actual users is that your software is solid -- it isn't going to break and cost them time or money. That kind of quality isn't particularly complicated to obtain -- it takes hard work, discipline, and prioritization, but there's nothing magical about it.

"When you’re a carpenter making a beautiful chest of drawers, you’re not going to use a piece of plywood on the back, even though it faces the wall and nobody will ever see it. You’ll know it’s there, so you’re going to use a beautiful piece of wood on the back. For you to sleep well at night, the aesthetic, the quality, has to be carried all the way through."

- Steve Jobs


Unfortunately most developers don't want to put the effort to maintain quality.

They just want to write a code, skipping writing automation test, and call it "magically done by me, the greatest hacker in this company, for under 1 hour".

Forgive me with the sarcasm but that's apparently quite common.


I would counter that with the argument that most people paying the bills do not want to pay the extra short-term costs associated with doing things more correctly. I know that I'm probably preaching to the choir here when I say that this is obviously a false-economy and you are deferring costs and building technical debt by working like that, but clients often want to save a quick buck. Good clients understand that this isn't wise, and are golden to have as customers.

Of course, there is often no real need to build code to be any more than 'just good enough' in the same way that many people are quite happy to purchase a plywood-backed piece of IKEA furniture instead of a solid mahogany hand-crafted piece. It serves their purposes just fine and saves them a ton of money. A good developer will similarly be able to determine what the precise definition of 'good enough' is for any given project scope/budget/time constraints.


I agree with you. I did not mention the bar of quality expected by the client.

That is fall under the "negotiation" phase between the client and the service provider. There should be some sort of agreeable quality other than "I just want the best of everything".

But the rule might be different for "product" based company than the "services" (consulting) based.


If you have $41m in investment gravy, er, I mean money, by all means, write lots of unit tests and automated test suites.

OTOH, if you have OTOOM of $1k or less, and only a few free hours per day or week to put into a project, or a drop-dead-runway of a few months, then tests are your enemy, because there's a lot of additional cost in terms of time and hassle in order to write them and maintain them as you go along. That's not to say that all tests are bad, or that tests never make sense. It's to say that having tests adds a cost, and so sometimes the upside of having them does not justify the downside.


One of the things that draws me to functional programming* is the relative freedom from side-effects. A poorly designed, tightly coupled system begs to be rewritten, but doing so would come at an enormous cost. If a system is designed to snap together, with easily interchangeable parts, it's easier to be satisfied with evolving the software one piece at a time.

Then, when the urge to rewrite something strikes, you can just rewrite that one component, knowing that everything else should work just fine.

* I haven't actually built anything substantial in a functional language, other than my blog (in Clojure), so I can't back this up with experience. But I think it's true.


> Then, when the urge to rewrite something strikes, you can just rewrite that one component, knowing that everything else should work just fine.

I'm pretty sure this was the promise of OOP, too. Or at least the promise of the OOP that was sold to me in (limited) school and on the job.


A main reason that it is hard or impractical to refactor a part of an OO system is that you cannot reason about its side-effects on the rest of the system without scouring all of its source.

When you are guaranteed that a subsystem has no side effects, you can gut its internals and as long as the interface behaves the same - your system will behave the same.

edit: a _stateful_ OO system anyway.


The author knows a lot more than I do. But I wonder. There's healthy frustration, which reflects a restless desire to fix _anything_ and thus can't measure the worth of anything, and unhealthy frustration, which despairs of ever making important improvement. Mistaking either for the other seems bad. If mature, talented people are losing interest in improvements because they seem futile, that seems like a danger signal to me.


Good points to sate someone like me who gets pretty upset over lack of quality


Sometimes software stinks because it IS bad. Perhaps the software he is using grew from simple to complex and nobody did any housework, thus the smell. Maybe it does need some work.


I think the point is that anyone's software would stink on some level when set against the toughness of some of the challenges a super-behemoth like Facebook faces. Some problems are much too difficult for even the best programmers in the world to solve and solve elegantly without multiple attempts. There's usually barely time for one attempt. But people still need to take on these problems, even if it makes them look bad, because eventually they will be ironed out, making way for new problems, bigger problems, and the circle goes on and on.


Coming back to the earlier examples, I think most of what we perceive as badness or decay are just emergent properties of a complex system in which we cannot focus on all aspects at all times

This is a key insight, and it usually takes banging your head against architectures you've created yourself a few times in order for it to sink in. Early on, you think that somehow there must be a "perfect" way of coding. So whenever the system gets a lot of cruft, you feel as if you made a mistake somewhere. The much more likely culprit is the impossibility of keeping enough of the thing in your head at any one time in order to keep it consistent.

I think FP helps with this a lot, and I think we're going to start seeing larger and larger systems moving to FP.

FP is going to bring it's own problems, though, which is why I think a hybrid FP/OOP model, with classes "growing" up from REPL constructs to meet contractual obligations is going to be the future. You'll code in FP, then wire in OOP.


Wouldn't a functional language better for wiring? Doesn't having function composition and higher order functions give you a much more expressive language for building systems?


Could you possibly give a brief pseudocode example that shows how this progression of functional to oo you're referring to works?


Agreed.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: