←back to thread

362 points mmphosis | 3 comments | | HN request time: 0.633s | source
Show context
marginalia_nu ◴[] No.42168430[source]
I don't think these points are well justified. They're all on the format "do this or a bad thing will happen", where often it's not obviously clear why the supposed bad thing is bad.

1. The alternative to small commits (as motivated by the difficulty in reverting large commits) is to not revert the commit, but just add a new commit that fixes the bug. The merits of this is of course debatable, but it does consitute a gap in the reasoning.

2. "Big refactorings are a bad idea", why though?

5. "It's better to create a new independent construct than to jam it into an existing module where you know deep down it doesn't make sense", why though?

6. As a counter point to designing an API via unit tests, you can also just have a design session. Think about the problem for a moment, write some design documents down. When dealing with APIs and interfaces, database schemas, this type of up-front design tends to deal by far the best results.

7. There's no clear argument why having more than two instances of a function is bad. Yeah implementations may diverge, but is that necessarily a bad thing? Even if they started out the same, why do they need to keeps staying the same?

10. "Testability is correlated with good design" is not really motivated at all. I know many designs that are good but not easily testable, and many designs that are extremely testable, but also hideously convoluted (e.g. "uncle bob's syndrome").

replies(1): >>42168642 #
1. Aeolun ◴[] No.42168642[source]
1. Making a new commit is not equivalent at all to reverting a commit. I'm a fan of failing forward too, but reverting the exact commit you know caused the issue implies you know exactly what the issue is, which is invariably good.

2. For the same reason that 'lets rewrite everything from scratch' generally is a bad idea.

5. Because deep down you know it doesn't make sense? Nobody will import your 'awesomeUtilityFunction' from the 'WaarghComponent' file, but they might if it's in a file/module called awesomeUtilities, or just plain awesomeUtilityFunction.

6. Designing an API via unit tests is the equivalent of a design session with a different whiteboard. I like how you complain about things not being well justified and then just claim that your own suggestion leads to better results without any motivation.

7. I think it should be fairly obvious that you only care about this if you _want_ to keep the implementations the same.

10. No good design is 'not easily testable'. Easily testable is a requirement for good design. In my experience, when someone makes this point they try to imply that when you bend yourself into corners to make your test work (as given in the example), you should stop doing that and instead look at better ways to abstract your dependencies (dependency injection, mockable utility functions, lambdas etc.).

replies(1): >>42168847 #
2. marginalia_nu ◴[] No.42168847[source]
> 1. Making a new commit is not equivalent at all to reverting a commit. I'm a fan of failing forward too, but reverting the exact commit you know caused the issue implies you know exactly what the issue is, which is invariably good.

This seems like backwards logic. Even if reverting the commit implies you know (or think you know) exactly what the issue is, doesn't adding a new commit fixing the issue also imply this?

> 2. For the same reason that 'lets rewrite everything from scratch' generally is a bad idea.

I'd vehemently object to the two being equivalent. Big refactorings are more laborious for sure and all else being equal, smaller are arguably preferrable to larger, but there are worthwhile changes you simply can't implement in small steps. Big refactoring tasks are mostly a problem if you have too many people working on a codebase, as it requires some degree of freezing a part of the codebase for changes to avoid merge issues.

> 7. I think it should be fairly obvious that you only care about this if you _want_ to keep the implementations the same.

The scenario as being discussed actually goes into the case where their requirements do in fact diverge, and suggests adding parameters to coax the divergent implementations into still being the same code.

> Easily testable is a requirement for good design.

I'd ask in what sense you mean the design is good? The test suite surely serves the code, and not the other way around. Afer all, we've sent people to the moon with code that never saw modern testing practices. There are other ways of ensuring code does what it should than unit tests.

I agree there are some types of code that benefits from extensive testing, but it's far from universal, and the tools needed to provide testability are anything but free, both in terms of performance and driving software complexity.

In that case, an alternative to extensive testability is to design the code in such a simple way that there isn't many places for bugs to hide.

replies(1): >>42172755 #
3. plagiarist ◴[] No.42172755[source]
> In that case, an alternative to extensive testability is to design the code in such a simple way that there isn't many places for bugs to hide.

I like this as an ideal. But I struggle to see how code can be both so simple that it is hard to make a mistake and also difficult to unit test.

Most of what I have seen forcing tests to be overly complex and brittle has been coupling code that have very different responsibilities (for example, testing business logic requires testing UI components that perform it). Separating those out would have been better design and more testable.