Live data from Hacker News

Evolutionary couplings between files reveal poor software design choices

ergoso.me

31–40 of 85 posts

Re: Evolutionary couplings between files reveal poor software design choices

#32

Am I the only one who disagrees with the premise that two files that tend to change a lot together indicate poor software design choices? If you change an API, you will have to change consumers of the API. Does that mean that your code is bad? This exists even in a low level examples: if you change a c++ class, you will need to also change the corresponding header file. Or perhaps, am I misunderstanding the concept?

The author noted there were "legitimate" linkages such as files and test files for those files, header files would be another such case. Eliminating those (which should be moderate to trivial) will leave files that really have no business knowing about each other's internals

Re: Evolutionary couplings between files reveal poor software design choices

#33

Am I the only one who disagrees with the premise that two files that tend to change a lot together indicate poor software design choices? If you change an API, you will have to change consumers of the API. Does that mean that your code is bad? This exists even in a low level examples: if you change a c++ class, you will need to also change the corresponding header file. Or perhaps, am I misunderstanding the concept?

Ideally, with good encapsulation and individual files keeping to single responsibilities, you would more often get away with just changing implementation and not changing API. Although you could take the size of the change into account to penalize API changes in other files less than implementation changes in both files and ignore header files if you didn't want to clump consumer changes into the same code smell. If the API has to change, you may have exposed too much implementation to the consumers.

Re: Evolutionary couplings between files reveal poor software design choices

#34
post #30
post #12

Earlier quoted context omitted.

> This is a clear indication of how TDD will slow you down. Not shown: the part where the critical production bug you introduced was caught by your test suite, thus saving you countless hours of agony, angry customers, and lost revenue.

Instead of writing tests in a separate file, why not express the same logic in the form of types in the lines directly above the code which implements that logic? This has the added benefit of making your code self-documenting and giving rise to powerful tools such as type-guided implementation inference and search.

Because you probably don't have a type system which comes anywhere near close to what you need to express (I doubt that's even possible).

By all means do leverage your type system as much as you can, avoid writing tests for what you know your type system handles, and (if your type system is expressive enough) use property-based testing to further leverage your type system into essentially fuzzing your functions.

But you'll still need to write tests.

Re: Evolutionary couplings between files reveal poor software design choices

#35
post #12

Earlier quoted context omitted.

> This is a clear indication of how TDD will slow you down. Not shown: the part where the critical production bug you introduced was caught by your test suite, thus saving you countless hours of agony, angry customers, and lost revenue.

"Not doing TDD" absolutely does not mean "not doing testing". You can definitely still test your software, even if you your development process is not test-driven like that. I can't quite understand why this is an issue.

But then you find yourself back to mempko's inane issue: you'll have to edit your test files alongside your code files, even if you edit the tests after the code.

Re: Evolutionary couplings between files reveal poor software design choices

#36
post #4

I think it is a mistake to think of coupling caused by TDD to be a false positive. What this outlines really is that TDD will force you to edit two files instead of one for many changes. This is a clear indication of how TDD will slow you down.

> This is a clear indication of how TDD will slow you down.

This is a classic problem of externalities. You can only quantifiably judge what you are quantifiably measuring.

In this statement, you are only measuring the file couplings. I hope it's obvious that there are many other factors at play.

For example, let's look at a "typical" development iteration for a feature.

---

With TDD:

1. you write the automated test

2. run the test

3. if the test passes goto 6

4. edit the software

5. goto 2

6. finish

---

With manual testing:

1. edit the software

2. manually test the software

3. if the software does not do what you need it to do, goto 1

4. finish

TDD gives you a quick feedback loop, since the verification step is automated, at the cost of up front time spent on writing the test.

There's also automated regression testing, which is useful to prevent regressions when you change the software system.

---

When the software becomes complex:

* regression tests offer a quick feedback loop that scales almost linearly

* manual tests have a slower feedback loop and are often given to the QA staff, which involves communication overhead, scheduling, meetings, etc.

Re: Evolutionary couplings between files reveal poor software design choices

#37

Am I the only one who disagrees with the premise that two files that tend to change a lot together indicate poor software design choices? If you change an API, you will have to change consumers of the API. Does that mean that your code is bad? This exists even in a low level examples: if you change a c++ class, you will need to also change the corresponding header file. Or perhaps, am I misunderstanding the concept?

agreed; those kind of linkages are not necessarily due to bad design but are, on the contrary, intrinsic to the design of the language you code in. Ideally I should consider these kind of things and exclude such pairs (X.cpp X.h) from the final results, but this is still pretty much work in progress.

Good catch, though. Thanks.

Re: Evolutionary couplings between files reveal poor software design choices

#38

There was another recent HN post that showed an analysis of IntelliJ's architecture using a source code analyzer [1]. Does anyone have more information on these types of tools? There seems to be a genre of tools that are used to inspect the architecture of a program, and I have no idea where to start learning about them. [1] http://t.co/Ja6uOLRGkQ

Thanks for the pointer; didn't know about that plug-in. As a long term Intellij Idea user, implementing this as a plug-in to Intellij is one of the things I would like to do in the short term. Would be really great to make the tool let you know about possible coupling as you work on the project.

Let me know if you can get your hands on a list of related plug-ins, I am really curios to see them in action.

Re: Evolutionary couplings between files reveal poor software design choices

#39

Am I the only one who disagrees with the premise that two files that tend to change a lot together indicate poor software design choices? If you change an API, you will have to change consumers of the API. Does that mean that your code is bad? This exists even in a low level examples: if you change a c++ class, you will need to also change the corresponding header file. Or perhaps, am I misunderstanding the concept?

The OP does not really define "bad" software. I'm also not convinced of the concept of "good" vs "bad" software.

When reviewing code, we tend to judge how the final output looks based on the reviews' aesthetics. There is almost no emphasis on the process of building the software nor is there much emphasis on how long it takes & how reliable the software is.

While aesthetics & clarity are important the notion of "good" or "bad" software depends on the context of the judgement. Is it good/bad for the programmer? Is it good/bad due to the costs of development? Is it good/bad based on it's flexibility toward changing requirements? Is it good/bad based on the flaws in deployed system? Is it good/bad based on the feature velocity?

Why is software productivity so difficult to measure? Software is complex & software is created in complex situations. It is tough to get an "apples to apples" comparison when comparing complex contexts. It's like comparing two people. Is one person better than another? Usually it depends on the context...

Re: Evolutionary couplings between files reveal poor software design choices

#40

That looks really interesting, and I'd love to run it on my own projects. I'm curious though, why do you think you need to make it a web service? And why tie it to github? I would like to run it on a local git repository and output the results into a local file. That seems like a good small program.

I'd also like to run this on our software, but being a web service tied to GitHub kills it for me.

right now, it is not really tied to GitHub; but only expects you to give a git repository URL. Coupling it GitHub will allow more information on the system, for example knowledge on commits that resolve issues on the tracker. That is a long-term goal of this project.
Post reply on HN