Live data from Hacker News

Refactoring: How do I even start?

socalledprogrammer.com

31–40 of 41 posts

Re: Refactoring: How do I even start?

#31
post #26
post #22

Earlier quoted context omitted.

You can't always rely on for-loop mechanics to do branching. Also, having an implied "conditional" that must be extracted by reading the head-portion of a loop is very very unreadable. I'd reject your submission on a code-review. Instead, you should do something like below. I assume that your example is contrived, so for the sake of argument, assume I have all sorts of business cruft around mine. I.e. should_process…

I can't follow. The code I showed is already processing masterlist and decides if it should process masterlist[z].list2 for every z: 0..masterlist.length. I fully agree that the code in my post is very bad, I took it from the article.

The main point is that you shouldn't rely on an implied rule that comes from the oddity of the length being 0 on a list.

If I'm looping through a list, it's because I want to loop through it and process its items. I'm going to return/skip earlier due to whatever reason, and not rely on the "logic" for processing being built into the length of the list, or whoever populates the list.

Re: Refactoring: How do I even start?

#32
post #30
post #29

Earlier quoted context omitted.

This. The problem is that in some cases, the legacy system is really messed up and making it unit testable is a big refactoring task on it's own. In these cases, I try to write some functional tests first (such as calling restful endpoints and checking the response, or using a headless browser). Not great but much better than nothing. Any ideas on how to do it better?

The closest thing I've seen to an actual definition of "legacy code" is "code that's very difficult to unit test." It's a shitty catch-22.

Feathers defines legacy code as code without accompanying tests in "Working Effectively with Legacy Code". Even to the point where someone he knows said of a particular shop, "they're writing legacy code, man!"

Re: Refactoring: How do I even start?

#33
post #11

Worth noting: some shops will summarily reject on code review any refactor that isn't part of the ticket/issue.

Along the same lines: it's considered good practice to perform a refactoring in a separate commit from code which changes behavior. This makes it much easier to review the code, as you can look at the changes in isolation. If you refactor and then change behavior in a single commit, it can result in a very confusing change.

Some shops reject commits that are refactoring. "Deliver value, don't just goof off". :-)

Re: Refactoring: How do I even start?

#34
post #33

Earlier quoted context omitted.

Along the same lines: it's considered good practice to perform a refactoring in a separate commit from code which changes behavior. This makes it much easier to review the code, as you can look at the changes in isolation. If you refactor and then change behavior in a single commit, it can result in a very confusing change.

Some shops reject commits that are refactoring. "Deliver value, don't just goof off". :-)

Sounds like they'd be awful places to work.

Re: Refactoring: How do I even start?

#35
post #18
post #13

Earlier quoted context omitted.

My word, something can be redundant (not conceding that point) and not "just plain wrong." Your language hate and insistence that the programmer himself is one of the "problems" is why people don't do code reviews, and why people get overly defensive if you offer constructive criticism of code. Your criticism is not constructive. If you are in a position of power or mentorship I suggest you take a moment to think how…

> My word, something can be redundant (not conceding that point) and not "just plain wrong." I think we can agree to disagree. I'm strictly against redundancy if it doesn't serve a well-defined purpose. > Your language hate and insistence that the programmer himself is one of the "problems" is why people don't do code reviews, and why people get overly defensive if you offer constructive criticism of code. Your criti…

> I would phrase my criticism entirely different if the recipient was someone who asked for my commentary and not someone who felt confident enough to write a blogpost on how to start refactoring code.

Right, because we should seek out excuses to be nasty to others. How about we just try to be constructive as much as possible?

Re: Refactoring: How do I even start?

#36
post #12
post #10

Earlier quoted context omitted.

He then proceeds to iterate over the list using zero based indexing. The loop would not execute once if the list had length zero, making this check just plain wrong. I know an even lower level language (C++, C) that doesn't have the problem of things which make no sense to be NULL (list elements). The problem is that Java did away completely with value types and made everything pointer only. That has been recognized…

> I know an even lower level language (C++, C) that doesn't have the problem of things which make no sense to be NULL (list elements) You must null check a lot of things in C, especially since there is no graceful error handling (try/catch blocks)... C certainly allows things to be null (or garbage) values. > The problem is that Java did away completely with value types and made everything pointer only. I'm not sure…

> I'm not sure what you are saying here -- the very notion of pointers do not exist in Java. This decision was made while creating the language, and avoids an entire class of programming errors. Java is strictly pass by value.

To clarify: the GP is probably referring to boxed and unboxed data types. IIRC, Java has some unboxed data types ("primitive" types?), but mostly everything is boxed behind a pointer.

Re: Refactoring: How do I even start?

#37
post #29

He missed step #1: write some tests that will provide feedback if you broke something, or assurance that you didn't.

This. The problem is that in some cases, the legacy system is really messed up and making it unit testable is a big refactoring task on it's own. In these cases, I try to write some functional tests first (such as calling restful endpoints and checking the response, or using a headless browser). Not great but much better than nothing. Any ideas on how to do it better?

Actually, I typically surround legacy code with functional tests instead. Unit testing is only really useful on blocks of code that you can safely wall off from the rest of the code base. Big balls of mud by their very nature don't really have that.

Much of the necessary refactoring for legacy code involves decoupling, which inevitably means changing method signatures and even replacing entire methods. If you surrounded those methods with unit tests which will break even when the functionality doesn't, you've made the code more resistant to refactoring, not less.

Re: Refactoring: How do I even start?

#38
post #12

Earlier quoted context omitted.

> I know an even lower level language (C++, C) that doesn't have the problem of things which make no sense to be NULL (list elements) You must null check a lot of things in C, especially since there is no graceful error handling (try/catch blocks)... C certainly allows things to be null (or garbage) values. > The problem is that Java did away completely with value types and made everything pointer only. I'm not sure…

> I'm not sure what you are saying here -- the very notion of pointers do not exist in Java. This decision was made while creating the language, and avoids an entire class of programming errors. Java is strictly pass by value. To clarify: the GP is probably referring to boxed and unboxed data types. IIRC, Java has some unboxed data types ("primitive" types?), but mostly everything is boxed behind a pointer.

> but mostly everything is boxed behind a pointer.

Behind a Reference would be more accurate. It's just a reference to a spot in the heap. Other than similarly "pointing" to a place in memory, the comparison between Java References and C Pointers stops there. One cannot pass a "pointer" in Java, nor can the pointer be free-form manipulated like in pointer-arithmetic.

Re: Refactoring: How do I even start?

#39
post #38

Earlier quoted context omitted.

> I'm not sure what you are saying here -- the very notion of pointers do not exist in Java. This decision was made while creating the language, and avoids an entire class of programming errors. Java is strictly pass by value. To clarify: the GP is probably referring to boxed and unboxed data types. IIRC, Java has some unboxed data types ("primitive" types?), but mostly everything is boxed behind a pointer.

> but mostly everything is boxed behind a pointer. Behind a Reference would be more accurate. It's just a reference to a spot in the heap. Other than similarly "pointing" to a place in memory, the comparison between Java References and C Pointers stops there. One cannot pass a "pointer" in Java, nor can the pointer be free-form manipulated like in pointer-arithmetic.

My statement is perfectly accurate in the context, which is discussing the representation of Java types.

Java doesn't hold a monopoly on the word "pointer." For example, Go has pointers but doesn't allow pointer arithmetic in safe code. Similarly for Rust.

Re: Refactoring: How do I even start?

#40

He missed step #1: write some tests that will provide feedback if you broke something, or assurance that you didn't.

I actually wrote this! I can't believe tests slipped my mind, that's usually the FIRST thing I do because I'm always scared of breaking anything. I'm going to edit this post and add a test.
Post reply on HN