There is No Right Way to Develop Software
dlo.me
dlo.me
For example, if you're developing a web-based payment processor, you should have unit tests everywhere and possibly additional runtime tests ensuring transactions are completing properly and are stored in the database, etc.
If you are developing the software for a pacemaker, unit tests just aren't going to cut it - you will need to logically prove all parts of the software work. You will need to test each piece of hardware to ensure it meets requirements. You will need to do hundreds of hours of physical testing to ensure everything works in different environments and with different electromagnetic interference. Just doing a bit of TDD is laughable here.
Lean startup validating an idea? History shows that simply shipping and having something that users can try to use is more than enough. If it breaks and goes down for hours? No problem - customers will sit there hitting F5 for hours for the chance to use it again. If nobody wants to use it, your tests are wasted anyway. In this environment, having something that partially works is better than something that isn't done yet.
There are millions of other cases, each of them unique. Software development is not building bridges. Please never use that analogy - a bridge is a fixed, known, and obvious requirement and solution. Software is the very opposite of this - if you compare 'software' to the combined industries of fabrics, farming, engineering, carpentry, electrical work, industrial building, home building and many more, then your analogy is closer to the truth.
For example, you may think that your ideas to develop good software in payment processor are right, but they aren't really right. You have no evidence that such way of developing this particular type of software leads to more reliability and security than every other way. Same goes for every other example you mentioned.
So, if you cannot prove that it's right or better, why do you say that it is? I think this is the point of the article.
This ties into a similar issue in management academics in which, for decades, people tried to prove a 'best way to manage a company'. Management academics have now moved on from this and all management recommendations are always very rooted in as deep a specific as possible. Software best practices need to make the same transition now.
Simply saying 'TDD is best' is the same as saying 'performance linked compensation is best'. Awhile back, a number of idealists very strongly touted the performance linked compensation angle in the same way that a number of software idealists are touting TDD. There is nothing wrong with either idea when used pragmatically and in the correct situations, but the important part for the future and for software as a whole is to discovery the situations in which TDD shines, and the situations it doesn't. Only by breaking it down as specific as possible can we get any real value from TDD recommendations.
So, if you cannot prove that it's right or better, why do you say that it is? I think this is the point of the article.
What I'm trying to get at is that if we can drill down to the specifics we may be able to actually prove things in very specific industries/team structures. We must move away from debating 'software development' as a whole before we can arrive at anything useful though.
I remember seeing a matrix/graph in a book, maybe 'code complete' or some other popular book. It basically had complexity on the y axis and risk on the x axis. The point being that high risk, and high complexity projects would justify the most discipline, testing, proofs etc, and the low risk low complexity projects justify minimal process. Something like an inventory management system for a t-shirt shop would be the latter, and sending a pacemaker to the moon would be the former.
I went into a golang irc channel, and was labeled as "ruby brainwashed" because of the way I approached my questions on Go syntax and concepts. I admit I had a hard time mapping object oriented concepts I had come to love in ruby to the different OO model of Go. These guys genuinely thought I was doing things wrong! - it has been a been a wake up call to the many different approaches and opinions.
Kudos to you for doing this.
There clearly is a correct way to develop software. It's just not clear that we've got enough experience with it to a) have found it, b) to recognize it, and c) to correctly confirm it to a reasonable degree.
As I commented on the article, the whole thing sounds a lot more silly if you replace "software development" with "building bridges" or the equivalent civil engineering task. There are clearly better, safer ways to construct bridges, and I'm fairly certain the same is true of software.
The best we can do is have enough experience and intelligence to choose methods appropriate to the context. That means hiring good developers...because process won't save us!
Ironically, if your company uses a lot of junior talent, the appropriate development methods might just require things like enforcing a JIRA ticket before code, always use TDD, etc.
Perhaps what I'm saying is the one true way to develop software is to choose your methodologies to maximize the effectiveness of your specific team to fulfill its specific end goal.
> Most speculated that a bridge would cost over $100 million.
> Joseph Strauss, who had designed nearly 400 bridges, claimed it could be built for $25 to $30 million.
> "Strauss was a strange, at times almost a self cancelling mixture of conflicting traits: promoter, mystic, tinkerer, dreamer, tenacious hustler, publicity seeker, and recluse. He was not a member of the American Society of Civil Engineers nor was he a graduate of a college of engineering."
Creating software is much more similar to creating a legal system. Lots of legacy, nothing ever seems to work quite right. Vested interests.
SO what's the correct way to create a legal system that just works?
That is not at all "clear" to me. I've come across lots of wrong ways, to be sure, but that doesn't point to a singular correct path.
The article is valuable in pointing out that most purported "best ways" are dogmas, and, despite claims of being scientific, they tend to veer off into pseudoscience.
And yet, if you don't have a plan, if you don't apply the best available tools, and if you don't have expertise and experience, you're going to have a bad time.
That leaves software development as something less than engineering, and more like a craft. You can't make it happen, or manage it, without expertise, creativity, and intellect.
Attempts to stuff it into a contained, measurable space almost always result in perverse incentives and efficiency comparable to a Soviet 5 year plan.
But that doesn't mean that a best way doesn't exist, or that it will never be found.
pragdave gave a great talk on this very subject a few years ago: http://www.infoq.com/presentations/Developing-Expertise-Dave...
Then I realized that you did both for me. So, thanks, lawl.
TDD and FORTRAN are completely orthogonal concepts....
> not throwing up our hands with some relativist "oh, whatever works for you must be the right way, there are no absolute truths".
Yep, that's what works in practice. Ideologues don't ship.
False. The testing I've seen heavy Fortran math frameworks go through would probably make the average frontend coder's face melt. Just because it ain't easy doesn't mean it ain't done.
The colloquial meaning of "orthogonal" seems to be "all combinations of these things exist or could exist in theory". That's all good and well, but there's a more faithful way to translate the mathematical concept of orthogonality: "uncorrelated". (Correlation is scaled covariation, which is basically dot product.) Adopting this usage might add some signal to online conversations, e.g. when one hears something like "TDD is orthogonal to Fortran", one could reply "hmm, that's not strictly orthogonal, the real-world correlation seems to be nonzero and negative, which means some real phenomenon must be causing it".
I originally had some other examples in that sentence - we'd never have invented OO, we probably wouldn't have any notion of a programming methodology at all. My point was that if some ways of programming weren't better than others we would never have invented another programming language.
>Yep, that's what works in practice. Ideologues don't ship.
Citation needed. I've seen more projects doomed by "pragmatism" (oh, we don't need to make these projects consistent, we can ship quicker if we just leave those two similar-but-slightly-different functions the way they are) than any other factor.
Sources for that phrase:
http://bobsutton.typepad.com/my_weblog/2006/07/strong_opinio...
http://www.saffo.com/02008/07/26/strong-opinions-weakly-held...
WHen someone says, hiring remote workers is necessary they are talking about it in certain context. Although they might fail to mention that context, or may even fail to notice that underlying context. Not noticing the context doesnt make them fundamentalist, it means that they are not much rigorous or they reached the particular conclusion by trial and error.
However to believe in any such conclusion without trying to understand the context or just not being aware to the fact that there might be a context is a folly on your part and not someone who mentioned a particular strategy which worked for them.
There may not be a single right way to develop all software, but as with questions of morality, there are certainly better or worse ways, and in principle, we can find them through science. Hopefully we can at least come to some definitive conclusions about "worst practices", if not best practices.
Partial list of bugs I've found before, that (for at least some definitions of "prove") would not be detected by what you suggest. Note that rigorous testing can (and, in fact did) find these.
* CPU Bugs (Including one that was unknown to the CPU manufacturer after nearly a decade of deployment)
* Memory Bugs
* Standard Library Bugs
* Compiler Bugs
Regehr even gives an example of a proven correct C compiler generating incorrect code (due to an incorrect system header), which was uncovered by testing.
[edit] Lest people misunderstand my position, I still think TDD (as it has been explained to me) is BS, but testing, in general, is a necessary part of making reliable software.
EDIT: Oh ok, so the system header was not proved mathematically correct :)
There exists many context-related local maximas.
and furthermore, the best way to write an essay is to organize a meticulous outline in advance. and then _stick_ to it, executing it faithfully.
and the best way to take a trip is to _plan_it_, with maps and tourist books, and not waver from the schedule you made, even if (especially if!) you're lured to a bar by someone you wanna boink.
stop doing it wrong!
-bowerbird
Which is one reason I love the start-up scene. You start out with a plan, but the challenges come when you have to make important decisions in a moment.
-bowerbird
That's how I feel about software development (and business operations in general). Is there an inflexible, one-size-fit-all, "right" methodology? Hell no. Even open allocation (which isn't really a methodology) isn't right for every company out there. There are, however, a ton of wrong ways to do things. The sad thing is that, because most people are driven by a mix of ego and incompetence, wrong ways of doing things are the most common.
You're Doing It Wrong if:
* managers have more power than engineers.
* mutually positive contributions (good for engineer and for firm) are disallowed for political reasons.
* people can't get shit done because of too much pointless process (to start writing code, you need a Jira ticket).
* stand-up takes 45 minutes and people sit down.
* people are micromanaged and start doing things badly, or overmonitored (the hidden danger of too much Jira activity) and start panic-coding.
* designs are made by incompetents.
* ... and many, many more.
Some things are obvious (designs made by incompetent designers), but then giving the example of "No code without a Jira ticket" is almost certainly your personal pet peeve.
I have a lot of pet peeves, because I've seen so much done wrong. Competent software managers are extremely uncommon. Maybe 1 in 20.
In the '90s, people who studied day traders found that they were reliably making money on their core strategies, but those were generally only available for a small amount of time, and that most of them lost their shirts through "boredom trading" outside of their core competence that had zero-to-negative expectancy and only added noise. Boredom trading occurs because ego, combined with a need to feel active, results in a lot of activity that cuts away at the profits earned during one's good hour or two per day.
Managers are a case of trader boredom. They'd actually be quite effective if they scaled back to 1/10 the amount of process and interference, but their trader boredom just causes them to throw everything out of whack. If managers were socially permitted to work 5-10 hours per week instead of being expected to fill time by bothering people, they'd probably do a much better job.
1.) Open web browser 2.) go to your JIRA url 3.) enter your username/password 4.) enter your password again because you mis-typed it 5.) find the project page for that particular project and wait for it to load 6.) find the place where you add new tickets and wait for that to load 7.) type in a bunch of bullshit on a long form and submit that 8.) Hopefully you get to assign the bug to yourself. God forbid you have to have a PM do the actual assignment! 9.) pull, make the change, push 10.) go back into jira and open the ticket 11.) write a description of how you fixed the "bug" 12.) close the ticket
Ok, so that's the worst case, but the only real work you should /need/ to do is #9. The whole process of creating/assigning/closing the ticket probably only takes a minute or two, but it's probably unnecessary in most software systems and, over time, adds a ton of frustration where none is needed.
Also, "type in a bunch of bullshit on a long form and submit that" - like I say, I don't know Jira, but I doubt that it forces you to type a long bit of bullshit. I'm sure that "correct spelling" would do. And I'd also expect that you'd be doing something similar in your source control system so that someone looking through the code at some point in the future can see why (or when) the particular change was made.
And how often do you make this kind of change as opposed to actually working on bugs/improvements that are coming in through JIRA?
I'm sure that there are occasions when your tool gets in the way of getting the work done, but from your description I'm not sure it sounds like it's a major inconvenience most of the time, which needs to be balanced against the benefit you get from having a centralised place to track, prioritise and allocate the work.
I agree that there should be a centralized place to track, prioritize, and allocate work. But the comment I was responding to was about having a ticket for every code change, which is absurd if you take it to the extreme. If I'm working on feature X, but come across a typo, do I have to have a ticket to fix the typo or can I just fix it as I go along?
Again, we are taking things to the extreme in the examples.
In a sane workflow, someone prioritizes a list of tasks, someone (hopefully the group) divides up the tasks, and then we work on them one at a time. All of that is in a central place and developers generally don't have a problem tracking like that.
But what about the case where you find a bug (especially a small one)? In larger teams you probably want to indicate that you fixed something so that the testing team can have something to verify against. In a small team you just fix it and go on without the overhead of making a ticket for every one of those you discover.
An example from today. I just came across some code that was
"unless @blah.blank?", but it should probably be turned around to "if @blah.present?", so I made the change. If I had to write a ticket for that I would quickly want to strangle someone. And that's what the original comment I responded to seemed to be asking about.
> In larger teams you probably want to indicate that you fixed something so that the testing team can have something to verify against. In a small team you just fix it and go on without the overhead of making a ticket for every one of those you discover.
I think you may have hit the nail on the head there. "to start writing code, you need a Jira ticket" isn't a bad process per se. It's a bad process if you're working on certain types of project e..g. in a small team where everyone intimately knows the codebase and all of its uses.
And I think that's what the article was about - blindly applying a process designed for one type of development to an entirely different type.
9a.) Make a Crucible review 9b.) Refresh a few times because Crucible isn't loading correctly 9c.) Figure out who to invite to the review 9d.) Wait 3 days until the PM notices the review and signs off on it 9e.) Close the review 9f.) Wait another day because the tools team decided they'd upgrade all the Atlassian tools today
Is this shit really common? I thought it was just where I worked.
When I think of "no code without a Jira ticket", I usually don't mean "create a Jira ticket for the code", I mean "find the Jira ticket that links closely to the code you're writing".
I do agree that creating Jira tickets all over the place creates unnecessary work for everyone - even those trying to read the reports.
It is helpful, however, to know the general area and background for the code you've written e.g. what the feature is and any comments on it. Stuff like "developer X was working on feature Y when he wrote that code".