I have only skimmed the text but regarding GUIs specifically the list in the end is spot on.
With that being said, I firmly believe that all software (given that one is not already deeply familiar with the domain) is/can/should be written three times to end up with a good product:
1. Minimal prototype. You throw something together fast to see it can be done, taking shortcuts and leaving out features which you know you will want later(tm).
2. First naive real implementation. You build upon the prototype, oftentimes thinking that there is actually not that much missing to turn it into something useful. You make bad design decisions and cut corners because you haven't had a chance to fully grasp all the underlying intricacies of the domain and the more time you spend on it the more frustrating it becomes because you start seeing all the wrong turns you took.
3. Once you arrive at a point where you know exactly what you want, you throw it all away and rewrite the whole thing in an elegant way, also focusing on performance.
(1) and (3) are usually fun wereas (2) fast becomes a dread. The main problem is that in a work context you almost never are allowed to transition from (2) to (3) because for an outsider (2) seems good enough and nobody wants to pay for (3).
"Plan to throw one away. You will anyhow."- Fred Brooks, _Mythical Man Month_
A software engineering book written decades before I was born- my college assigned us the 25th Anniversary Edition- and yet I re-read it every few years and find some new way to apply its lessons to my current problems.
Personally, I’ve never found this lean methodology to work for me. I have a bit of a mantra that I’ve found works really well for me: “Put everything on the screen”.
Every feature every variant ever possible configuration and all future potential states. Don’t care about how it looks or how it feels just put it all there. Build out as much of it as possible, as fast as possible, knowing it will be thrown away.
Then, whittle away. Combine, drop, group, reorganize, hide, delete, add. About halfway through this step it becomes clear what I really should have been striving for the whole time—and invariably, it’s a mile away from what I started out to build.
One I have that, then I think step three stays about the same.
This isn’t really a critique of lean development, but after a decade of trying to do things leanly, I’ve just accepted that it’s not how my brain works
Hard agree. (2) is all about building out the test suite; once you have this (3) becomes a cake walk.
I've worked in a lot of places where end to end testing is performed manually by a SIT team who absolutely do not like to re-run a test once it's been passed. These people hate the idea of (3) and will overestimate the costs to the PM in order to avoid having to do it.
I agree completely with the idea of building something 3 times. As I get older, I tend to compress things more into 2 iterations, but that just because I like to think I’m getting better at coding, so step two is less pressing.
I think of the three iterations in these terms:
1) You don’t know what you’re doing. So this iteration is all about figuring out the problem space.
2) You know that you’re doing, but you don’t know how to do it. This iteration is about figuring out the way to engineer/design the program.
3) You’ve figured out both what you’re doing and how to do it. So now, just build it.
i would add that the reason no product manager wants to pay for #3 is because historical attempts to do so have overwhelmingly resulted in cost/schedule overruns; did-not-finish outcomes are common. Let he who believes otherwise demonstrate so with his own money, this is called a startup and note that virtually all startups fail i.e. run out of some critical resource without finishing! So what is a wisened product manager to do? No easy answers here - simply look to the industry to see what the average outcome is. And it is not for lack of trying. in my opinion software delivery is not a solved problem. but it is really hard to make money as a software delivery expert by going around and saying that you don’t know how to deliver software.
I hear what you're saying but my experience is that dwelling in #2 without seeing the bigger picture does very often just as much result in cost/schedule overruns, because shoving certain features or trying to improve certain aspects just collides with the status quo and sometimes cannot be easily accomplished if things are built "wrong" to begin with (wrong often just meaning that they were based on then-relevant prerequisites/assumption which are no longer relevant). Also, the cost of maintenance is often just not taken into account, which means that in the end you have to spend way too much time to shoehorn a half-baked solution into the status quo which has the appearance of delivering what was requested (but doesn't always, because you had to compromise, leaving everybody unhappy) while taking way too much time and at the same time just piling more bloated poo on top of what's already there, making maintenance in the long run even harder. I can't count how many times I've been in a situation where implementing something shouldn't have taken more than 30 minutes but because the codebase was in a not-so-good(tm) state took several days instead. This piles up exponentially, resulting in frustrated developers, a worse product and cost/schedule overruns. In a perfect world, code should improve over time, not deteriorate.
from the PM perspective, it makes little sense to transform from 2 to 3.
Those devs had spent weeks/months for this app, now they want to throw it all away ?, that means throwing money through windows. Also, the risk that the new app may not work like before, or missing deadline, etc. A safe bet would be reiterating (2)
I explained in another comment why it isn't throwing money out of the window. In my experience, it often costs a lot more money in the long run to not do it. The underlying problem is that most companies don't really think mid- or long-term and are happy with chasing fast money and eventually throwing it all away anyway because the product isn't competitive anymore and/or maintenance becomes too expensive. These are problems which definitely can be mitigated, but it requires a good team.
4. Now you arrive at a point where you really know exactly what you want, you throw it all away and rewrite the whole thing in a better more elegant and performant way.
With that being said, I firmly believe that all software (given that one is not already deeply familiar with the domain) is/can/should be written three times to end up with a good product:
1. Minimal prototype. You throw something together fast to see it can be done, taking shortcuts and leaving out features which you know you will want later(tm).
2. First naive real implementation. You build upon the prototype, oftentimes thinking that there is actually not that much missing to turn it into something useful. You make bad design decisions and cut corners because you haven't had a chance to fully grasp all the underlying intricacies of the domain and the more time you spend on it the more frustrating it becomes because you start seeing all the wrong turns you took.
3. Once you arrive at a point where you know exactly what you want, you throw it all away and rewrite the whole thing in an elegant way, also focusing on performance.
(1) and (3) are usually fun wereas (2) fast becomes a dread. The main problem is that in a work context you almost never are allowed to transition from (2) to (3) because for an outsider (2) seems good enough and nobody wants to pay for (3).