Live data from Hacker News

Write code that is easy to delete, not easy to extend (2016)

programmingisterrible.com

61–70 of 113 posts

Re: Write code that is easy to delete, not easy to extend (2016)

#61
post #28

Earlier quoted context omitted.

More like a variant of the Peter principle: all code tends to be refactored to its level of unrefactorability.

Having just completed a change that should have been small, but ended up spanning ~75 files, I can attest to this. It would have been small, up until the point where one of the excitable members of the team discovered Uncle Bob and got excited. Which, disclaimer, I generally like what Uncle Bob has to say. But there's this thing, and I don't quite understand how it happens, where it seems to be really easy to impleme…

I have seen many a TDD enthusiast create many more problems in terms of test maintenance than they solved in code quality. Doesn't mean TDD is bad, it just means like anything it is not a silver bullet

Re: Write code that is easy to delete, not easy to extend (2016)

#62
post #20
post #10

I wholeheartedly agree with "don't immediately jump on the modularize and abstract everything right away". I think that "modularization and abstraction is always and uniformly good" is one of the big lies of our profession. It’s easy to see how it’s attractive : programming is intellectual work, and displaying capacity of abstraction is rewarding. I was extremely enthusiastic about that stuff when I was young, too. T…

> Very clean. Also, changing the slightest things required to go through 5-6 files. Martin Fowler's "Refactoring" is a great book (I only know the 2nd edition from 2019). From a naive understanding of the "clean code" school of thought one might assume that splitting up everything into small functions, classes, modules is always the way to go. But Fowler's advice is much more nuanced than that. His list of bad code s…

I remember coming across Refactoring after having already adopted it for some years. I wish I had come across it sooner. But with my initial experience under my belt I was able to realize what a gold mine it is. Anyone working in a higher level OOP language especially should give it a read

Re: Write code that is easy to delete, not easy to extend (2016)

#63
post #41

Earlier quoted context omitted.

If you have to change in 5 places to change one "thing", the code is probably not DRY.

You have 5 places in code where you draw a blue rectangle: drawRectangle("blue", x0, y0, x1, y1); Do you refactor them into drawBlueRectangle(x0, y0, x1, y1)? It seems you removed the duplication but you didn't. Because if you now have the requirement to draw red rectangles instead you surely won't leave it as def drawBlueRectangle(x0, y0, x1, y1): drawRectangle("red", x0, y0, x1, y1) So instead of changing 5 places…

Yeah, the idea of DRY is simple, but it doesn't change the fact that you have to use your judgement, do and learn from mistakes etc. Nothing ever does.

I'd tweak your code example to this:

     def drawHighlightingRectangle(someDecidingFactor1, someDecidingFactor2, x0, y0, x1, y1):
         def highlight_color(factor1, factor2):
             if factor1 == something && factor2 != somethingElse:
                 return "red"
             else:
                 return "blue"

         color = highlight_color(someDecidingFactor1, someDecidingFactor2)
         drawRectangle(color, x0, y0, x1, y1)
This doesn't Repeat the drawRectangle() call.

Re: Write code that is easy to delete, not easy to extend (2016)

#65
post #28
post #15

Earlier quoted context omitted.

It is like the Murphy's law of deletable code "Anything that can be made hard to delete will be made hard to delete".

More like a variant of the Peter principle: all code tends to be refactored to its level of unrefactorability.

I was thinking this too, but on closer scrutiny I don’t think it’s true unless the “goal” of code is to be rewritten. If the goal of code is to work as well as needed and no more, then it won’t move in that direction.

The “goal” of employees in a corporate environment can be to be promoted and get paid more, on the other hand, leading to the Peter principle.

Re: Write code that is easy to delete, not easy to extend (2016)

#66
post #61

Earlier quoted context omitted.

Having just completed a change that should have been small, but ended up spanning ~75 files, I can attest to this. It would have been small, up until the point where one of the excitable members of the team discovered Uncle Bob and got excited. Which, disclaimer, I generally like what Uncle Bob has to say. But there's this thing, and I don't quite understand how it happens, where it seems to be really easy to impleme…

I have seen many a TDD enthusiast create many more problems in terms of test maintenance than they solved in code quality. Doesn't mean TDD is bad, it just means like anything it is not a silver bullet

I certainly don't think TDD is bad; I do it myself. Though I will say that the Classicism vs Mockism debate is alive and well, and it is my (a classicist's) opinion that test-induced design damage is largely a by-product of getting so caught up in the red-green-refactor flow that the tests start to become an end in and of themselves. At which point maintainability has taken a back seat to mockability.

I'd rather have a slow test that doesn't unnecessarily concern itself with implementation details, than a test that is fast, but achieves its speed by getting its dirty little fingers all over the implementation details, and throws a tantrum and refuses to let go of them every time you attempt some spring cleaning.

Re: Write code that is easy to delete, not easy to extend (2016)

#67

I think that one possible problem with the 'O' in SOLID (open closed principle) is spending excess time second guessing future modifications to the code. The examples are always clear cut, but in the real world it sometimes doesn't work out that way. OTOH I'd say that the 'L' is worthwhile (Liskov substitution principle) as inheritance can be abused as a kind of 'version control' for functionality, and LSP helps guar…

Some time ago I worked exposing an API that, given that it was constantly evolving and different partners adapted to it at different paces, we had to support a wide range of versions of it, which was basically what you say as version control. I'm not gonna say it was pretty, actually from a design perspective it was disgusting, but from the perspective of handling a dozen versions of the same code in the same applica…

Sounds reasonable, I should really have said 'informal version control' where it's used to get stuff out the door and piles on technical debt as well :-o

Re: Write code that is easy to delete, not easy to extend (2016)

#68
post #10

I wholeheartedly agree with "don't immediately jump on the modularize and abstract everything right away". I think that "modularization and abstraction is always and uniformly good" is one of the big lies of our profession. It’s easy to see how it’s attractive : programming is intellectual work, and displaying capacity of abstraction is rewarding. I was extremely enthusiastic about that stuff when I was young, too. T…

"Each class in his own file...."

I think there's a subtle trap where programmers think their code isn't nicely organized unless they themselves have written all those abstraction layers.

But one of the virtues of picking up a framework is precisely that it's already there for you. Hopefully it matches what you need. But within reason, if you pick a good framework for your task, you don't then need to layer on another set of abstractions... it's already got them!

It's completely sensible to pick up a framework and bash out 2000 lines of code that simply spends the abstraction budget of the core framework. It's half the value of the framework in the first place. Obviously if you're going to build another 100K of lines on the framework you may need to bring some additional organization to the party, but the space of "framework + 2K lines of code" is a pretty rich one.

Re: Write code that is easy to delete, not easy to extend (2016)

#69

The unfortunate side effect of this (very good) advice is that all code that's easy to delete will eventually be replaced with code that's hard to delete (and thus will eventually be impossible to delete in order to be replaced with something better).

I think the one thing we do wrong with code is when we document it, we write what the function does. Code is largely self-documenting and this because stale quickly anyway.

IMO, the thing we should be doing is documenting WHY this function needs to exist. That is the question that is hard to answer three years later.

Re: Write code that is easy to delete, not easy to extend (2016)

#70
post #41

Earlier quoted context omitted.

If you have to change in 5 places to change one "thing", the code is probably not DRY.

You have 5 places in code where you draw a blue rectangle: drawRectangle("blue", x0, y0, x1, y1); Do you refactor them into drawBlueRectangle(x0, y0, x1, y1)? It seems you removed the duplication but you didn't. Because if you now have the requirement to draw red rectangles instead you surely won't leave it as def drawBlueRectangle(x0, y0, x1, y1): drawRectangle("red", x0, y0, x1, y1) So instead of changing 5 places…

I think you should ask yourselves why you are drawing blue rectangles. What is their purpose? Do they just happen to be blue? Or are they blue because they have they all "do the same job"? Maybe you should have

drawInlineHelpBox(x0, y0, x1, y1)

or

drawEnergyShield(x0, y0, x1, y1)

We can see from the language that unlike your example this is a true abstraction. You went from color parameter to a specific color. It's both phrased in terms of colors.

But here we go from color to ui elements. The terminology is completely different.

     def drawEnergyShield(shield_capacity, incoming_dps, x0, y0, x1, y1):
         hue = incoming_dps / shield_capacity
         alpha = shield_capacity / 200
         drawRectangle(hsva_color(hue, 1, 1, alpha), x0, y0, x1, y1)
And I think you should embrace having business logic in there.
Post reply on HN