4 ms·
I've made peace with the fact that rewrites are almost a necessity, however well you do it the first time. Currently I'm rewriting a well-designed and written p
by karmakurtisaani 4y ago
I've made peace with the fact that rewrites are almost a necessity, however well you do it the first time. Currently I'm rewriting a well-designed and written piece of code, which just was abstracted in a way that couldn't support new business requirements.
I've embraced this approach in personal projects too, and don't suffer from analysis paralysis or gumption traps as much as I used to.
You want to make something nice? Prepare to do the same thing at least two-three times, each time being better than the last.
- club_tropical 4y ago100% agree. Rewrites are great and easier than untangling and surgically updating prior code. Far more motivating, too.
- pmontra 4y agoThis week I worked on the code of a customer that was passing an object into a command / service hierarchy and extracting some attributes of that object in the lowest level of the hierarchy, where a method is doing the real job. Unfortunately the new feature I worked on needed most of the methods of that hierarchy but didn't have that object because it doesn't have more than half of the data needed to build it. So, passing individual attributes as arguments instead of the object would have been the right implementation and the assumptions the code was based on were wrong for this new use case. I derived a class from the first level of the hierarchy with only the methods I needed, redefined as empty the ones that were using the attributes I didn't have and ended up with code that passed tests. No time to refactor all the code into the correct abstraction. Time to understand how the class hierarchy worked: too much. Was it overengineered? Yes. I prefer simple straightforward code with few files to navigate to understand how it works.
- karmakurtisaani 4y agoAh, the good old time constraint driven programming. The worst of them all.
- throwaway290 4y agoTCDD can be OK if you control the scope. "We must deliver a functional thing in 2 weeks, it may be small and advance us 2% towards the goal but it must be done in 2 weeks and it must work. Now let's see what we can do well in that timeframe..."
- pmontra 4y agoWell, in this case it was Wednesday and I'll be working for another customer on Thursday and Friday (they know it) so that feature must be completed by Wednesday night. They accept that the quality of a feature worked on for one day will be less than the quality of a feature worked on for two or three days. Costs.
- ChrisMarshallNY 4y ago> I prefer simple straightforward code with few files to navigate to understand how it works. My files tend to be fairly large. I'll often have classes, structs, enums, or even protocols, that do a lot. I use // MARK: comments to provide a "poor man's ToC," to the code editor.
- ChrisMarshallNY 4y agoI write in layers and modules. Each one is well-done, fairly insular, and coupling is as loose as possible. A lot of my refactoring is about reducing coupling, and increasing autonomy. Bottom layers can often be left alone for years, while top layers can see almost constant change. Right now, I’m working on the home stretch of an app (backend/native iOS frontend) that has been under development for a couple of years. A lot of the reason for that time, is because the people I’m working with, didn’t really know what they wanted, when we started (sound familiar?). It has undergone several massive pivots during this time, but we have settled on an operational model, and it’s been pretty much pure refinement, for the last three or four months. I just rewrote a major backend driver[0], to make the server connection smoother and have a simpler asynchronous behavior. It will also make it easier to integrate other types of backends, in the future, but I know better than to think it is “future proof”; however, it affords a structure that will be quite amenable to change. The main app is closed-source, but many of its components are open. It took about a month to write the driver, and it was sort of akin to reconstruction of a bridge, while traffic was going over it. If I hadn’t done the original design, in a modular, API-driven manner, it never could have been done, but I’ve also done exactly this, numerous times. The old design[1] was too restrictive, and is one of my older projects. I wanted to get it out of my app (even though I wrote it). The big deal about this project, and the key to being able to pivot, is that it has been released through Apple TestFlight, since it was about a month old. I’m coming up on a thousand TestFlight releases. This allows the non-tech stakeholders (the ones that don’t know what they want) to run the app, as a release-quality application, and provide really meaningful feedback (like “gee … I really thought it was a good idea, but you’re right. It sucks.”). Sometimes, there’s no substitute for giving someone what they want, to convince them that it’s not what they want. Needless to say, a great deal of high-quality work has been binned, but we haven’t been running a brand-destroying lashup MVP. The project has been internal-only, this whole time. I am quite aware that this method of development is not commercially friendly, in today’s development environment, but we have the luxury of the Principal (Yours Trooly) working for free, and knowing full well, what he signed up for, when we started, and designing accordingly. The end result will be an application that will enjoy almost jaw-dropping Quality, out the door, with many thousands of test runs, on shipping code, for two years. We’re finding the “rough spots,” now that we are in the home stretch, and still have the cosmetics (theme, aesthetic design, interface, etc.) to go before widening to our first test phase (which will also be TestFlight). Since the “team” doing the lion’s share of the work consists of one person, the Quality is of paramount importance. It’s a pretty big project, and this scope is usually implemented by a much larger team. When I write something, I can generally leave it alone, until I decide to revisit it, on my terms. [0] https://github.com/LittleGreenViper/LGV_MeetingSDK https://github.com/LittleGreenViper/LGV_MeetingSDK [1] https://github.com/bmlt-enabled/BMLTiOSLib https://github.com/bmlt-enabled/BMLTiOSLib
- mbrodersen 4y agoNot my experience at all. I simply refactor/improve the code one small step a day guided by auto tests and eventually end up with clean and highly maintainable code. I am managing a very large C++ application and haven’t had a bug in production for 5+ years. Which means that I spend almost 100% of my time adding new features instead of being in debug hell.
- karmakurtisaani 4y agoI was actually including refactoring and small improvements in this rewriting idea. It just helps me mentally if the bar to re-do code is low.
- mbrodersen 4y agoFair enough. And let me add that sometimes refactoring for me means completely rewriting a sub-module or sub-system. It is safe to do as long as I have good solid tests to compare before/after.