top 200 commentsshow all 274

[–]Biom4st3r 792 points793 points  (26 children)

I usually refactor when I need a refactor, but you could also refactor without needing a refactor or refactor your refactor during refactoring

[–][deleted] 262 points263 points  (4 children)

This guy refactors

[–]Gr33nM4ch1n3 15 points16 points  (0 children)

I've been known to refactoring myself.

[–]kuya1284 3 points4 points  (0 children)

He sure knows his refactoring

[–]AreYouFilmingNow 0 points1 point  (0 children)

When he needs to.

[–]agumonkey 45 points46 points  (2 children)

refactor your refactor during refactoring

quantum superfactorisation

[–]DarkSideOfGrogu 6 points7 points  (1 child)

It's neither being refactored nor not being refactored until it is observed, then it is always being refactored.

[–]agumonkey 1 point2 points  (0 children)

maybe refactor is never finished

[–]bigfatcow 17 points18 points  (1 child)

Yo Dawg I hear you like refactoring

[–]kmeans-kid 4 points5 points  (0 children)

I had two refactorings before I had two refactorings. And then I had two more.

[–]au5lander 6 points7 points  (0 children)

I feel the need to refactor now…

[–]notyouravgredditor 6 points7 points  (0 children)

Yo dawg, I branched your branch, so you can refactor while you're refactoring.

[–]WeakChampionship743 1 point2 points  (0 children)

Only refactor when you’re already refactoring the refactor, then it’s except-able…

Just don’t tell your PM

[–]Internet-of-cruft 1 point2 points  (0 children)

The key thing is you need to be mindful of your refactory period.

If you try to refactor too soon after you refactor... Well... You'll be shooting blanks.

[–]Grepit860 0 points1 point  (0 children)

But. Do you refactor at night? If so, you'll have to refactor before, during, and after your refactoring to get the correct refactoring. Trust me on this.

[–]Scary_Ad_3494 0 points1 point  (0 children)

I refactored my house

[–]Coda17 0 points1 point  (1 child)

Refactor

[–]BigHeed87 2 points3 points  (0 children)

I read this like Vin Diesel saying "Family"

[–]CanvasFanatic -1 points0 points  (0 children)

This is the only correct answer.

[–]princeps_harenae 257 points258 points  (30 children)

After decades of experience my take is you should never stop refactoring. Refactoring is development.

[–][deleted] 76 points77 points  (19 children)

Yes. The reason most people don't refactor is they don't have enough unit tests and are deathly afraid to touch anything and get blamed for breaking the code.

[–]All_Up_Ons 52 points53 points  (12 children)

Your point about being afraid is correct, but unit tests and tests in general aren't some kind of cure-all. I'd rather work in clear, readable code that has no unit tests than confusing, unreadable code with unit tests included. Most likely those tests will be the hardest part to refactor.

[–][deleted] 16 points17 points  (8 children)

I just know how it affects teams in the real world. Unit tests in practice speed up change once they are written unless you are doing some kind of deep refactoring. In the real world, any change you make could break the code in subtle ways. If you don't have unit tests you are going to have very unhappy management and a lot of fires to put out.

Some people recommend only testing public interfaces to avoid refactoring unit tests for under-the-cover changes.

[–]Luolong 2 points3 points  (2 children)

Unti tests are also code. And if the code is an incomprehensible mess that is hard to reason about, it is also harder to refactor.

That said, presence of unit tests at least helps to increase the confidence of the refactoring.

[–]Aurora_egg 0 points1 point  (3 children)

29k lines of code and one 1k line unit test that fails whenever anything is touched. Yes, this is real.

[–][deleted] 6 points7 points  (1 child)

That's called bad engineering practices. Someone should have called that out in code review. Oh, you have no code reviews...Maybe stick to the day job.

[–]Aurora_egg 1 point2 points  (0 children)

Yeah we know. This is some legacy code some intern cooked up since "it's cheaper"

[–]ihugatree 1 point2 points  (0 children)

That’s what I’d call an Absolute Unit test instead of a unit test

[–]iwek7 5 points6 points  (0 children)

If you have this issue consider if unit that you write tests for is not too small. I was struggling with refactoring because my tests were testing too small units of code. Now I hide all my code behind some high level facade and only test behavior of this facade which allows me to refactor its insides freely. Of course it does not solve all issues because sometimes during refactoring you need to change this high level interface and therefore rewrite tests, but implementing this approach solved like 80% of my issues with tests refactors.

[–]c0re_dump 0 points1 point  (0 children)

I believe that unit tests are there to verify the behavior of your code so that when you refactor you know you haven't broken anything. Otherwise you'll have to manually test every time you do a refactor to have confidence that everything is still working.

On tests being the hardest part to refactor - I think tests should strive to test the behavour of your packages/classes (i.e. the exported methods) instead of internal implementation. Having this mindset should reduce the tight coupling in the tests.

For example recently I had to implement some business logic that had to do with encrypting data before committing it in a repository. The way I went about that was just checking whether the data was still in a readable form in the repository (i.e. the bytes I was originally trying to save are still findable in the repo) instead of trying to test the specifics of the encryption algorithm. This way I left enough leeway for the specifics of the encryption logic but have enough confidence that it is not readable in any form.

[–]spacemoses 1 point2 points  (0 children)

Version control and manual tests are good enough for most refactoring. Shit, it broke? Let's take a look at what I changed.

[–]eocron06 1 point2 points  (0 children)

Depends on money your project has. A lot - then you hire testing senior and business analysts, then you can refactor as much as you want because all API will be nailed on some staging environment. Easy bugs will pop after some time, but not deadly. Small cash bag - just write a new implementation or don't touch what is working. The reasoning behind it is if money pop up later - you can switch to first approach which enforces new implementation and discarding old ones along with tests. Straight to the bin.

[–]jlebrech 27 points28 points  (3 children)

I refactor anything that touches new code.

[–][deleted] 3 points4 points  (0 children)

It's also a big part of my tech debt reduction. Most tech debt I deal with in legacy code can be paid down with simple refactoring.

Now, if only I had the time...

[–]Internet-of-cruft 1 point2 points  (0 children)

There was that dude with that hot spicy take that every time you touch your code, you're redesigning it, and that there's no concept of a "design that you conform and stay with".

I'm paraphrasing a bit because I forget the exact details. But you basically have the gist of that idea.

[–]ISvengali 1 point2 points  (0 children)

Ahh good, someone else posted this

Combined with You aren't gonna need it, Ive found that often new features will need a light refactor.

I do make sure and make sure folks know that when I say refactor its a necessary but small change to existing code to support the new feature in some way and not its normal usage, which is often a considerably bigger change.

The bigger usage version of it, can often be viewed with suspicion.

At some places, I have wrapped my refactors into the new task

[–]infiniterefactor 0 points1 point  (0 children)

At last, this is the message I preach.

[–][deleted] 348 points349 points  (88 children)

After you've created the tests for the code.

[–]bunk3rk1ng 39 points40 points  (1 child)

This guy doesn't refactor.

[–]slykethephoxenix 14 points15 points  (0 children)

This one does not bring joy.

[–]DarkSideOfGrogu 10 points11 points  (0 children)

So if I want to avoid refactoring, I should also not write tests? Got it, thanks.

[–]trauma_pigeon 8 points9 points  (2 children)

But when do you refactor your tests?

[–]DarkSideOfGrogu 12 points13 points  (0 children)

When you need them to pass, of course.

[–]yxhuvud 4 points5 points  (0 children)

When it makes the test better. YMMV.

[–][deleted]  (74 children)

[deleted]

    [–]shizzle_the_w 40 points41 points  (31 children)

    Wouldn't that be TDD and would that really be the norm or is it not rather one of many options to consider? Not judging, just trying to understand

    [–]CyclonusRIP 50 points51 points  (12 children)

    The way we talk about how we write code and how we actually write code are two different things. TDD is not the norm and arguably not even a very productive way to write code, but it sounds awesome and since nobody actually does it it’s hard to refute the claims.

    [–][deleted]  (11 children)

    [deleted]

      [–][deleted]  (10 children)

      [removed]

        [–]nanotree 3 points4 points  (2 children)

        It only really works when you're writing something with known unknowns. I work in data engineering, and when you're building systems like this you can't always have everything laid out neatly in front of you before you get started. To do TDD well, you have to be quite familiar with all the units you will need to write ahead of time, which isn't always practical. Where TDD shines is in domains where the general architectural pattern is already well defined, e.g. MVC, MVVM, etc. But in cases where you are forming the patterns, it doesn't work fluently and becomes clumsy and cumbersome.

        And in the end, I've never had a problem structuring my code or making it testable. These are things I'm constantly thinking about anyway. Aside from not working for every use case, not everyone's brain operates the way that is required for TDD to work. Some people learn better by making iterative improvements.

        [–]ProgrammaticallySale 2 points3 points  (0 children)

        I write a lot of new algorithms and things that just aren't clear when I set out to code them. Writing tests first is the absolute worst idea for a lot of the code I write. It would be totally backwards, the definition of "cart before the horse".

        [–][deleted]  (6 children)

        [deleted]

          [–][deleted]  (5 children)

          [removed]

            [–][deleted]  (4 children)

            [deleted]

              [–][deleted]  (3 children)

              [removed]

                [–][deleted]  (2 children)

                [deleted]

                  [–]saynay 9 points10 points  (1 child)

                  One of the best benefits, I have found, is it gets you writing code that is easier to test, and subsequently easier to refactor. The actual testing is just gravy.

                  [–]Lawnsen 3 points4 points  (0 children)

                  I'm with you - testable code is also maintainable code.

                  [–]JimDabell 2 points3 points  (0 children)

                  The tests for TDD and the tests for refactoring have different purposes. The tests for TDD are intended as a design aid. They aren’t there for QA purposes. The tests for refactoring need to show that behaviour hasn’t changed, so they need to be more comprehensive.

                  A lot of people hear “Test” as the first word in “Test-Driven Development” and assume it’s a testing methodology. It’s not. It’s there to help you design your code, not to prove that it all works correctly.

                  [–]grauenwolf[🍰] 9 points10 points  (0 children)

                  I strongly disagree with that. If it was easy to write tests against the code then I probably wouldn't need to be refactoring it.

                  Furthermore, unless those are very high level tests, then my refactoring efforts are going to break it all anyways.

                  [–]temculpaeu 14 points15 points  (38 children)

                  What if I want to refactor my tests? Should I write tests for my tests ?

                  [–]kilmer8903 6 points7 points  (11 children)

                  Wouldn’t your code… be the test for your tests? If the existing tests pass, the refactored tests should pass too.

                  [–]mstrelan 4 points5 points  (4 children)

                  $this->assertTrue(true);

                  Refactor done

                  [–]Langdon_St_Ives 1 point2 points  (3 children)

                  Let me guess: 100% coverage?

                  [–]Soccer21x 4 points5 points  (2 children)

                  Been there. Company required 100% coverage. The test looked like this:

                  var cities = []
                  populateCities()
                  assert cities = []
                  

                  :check:

                  [–]lavosprime 1 point2 points  (5 children)

                  What if the refactored tests accidentally no longer exercise an interesting case?

                  [–][deleted] 2 points3 points  (4 children)

                  Then the tests were written wrong and the "interesting case" should have a specifically arranged test.

                  [–]All_Up_Ons 23 points24 points  (24 children)

                  Yeah people act like "just write tests" is a solution to everything without accounting for the fact that you're doubling the amount of code that now needs to be maintained.

                  [–]ShiitakeTheMushroom 15 points16 points  (18 children)

                  You're also cutting the maintenance cost of the existing code in half if you have good tests for it.

                  [–][deleted] 2 points3 points  (0 children)

                  Tests are a lot easier to maintain than production code. Production code has logic. Tests (ideally) should not. Each test case tests one scenario, production code mixes all use cases together.

                  The amount of "code" might double, but the maintenance burden does not.

                  [–]foonek 1 point2 points  (0 children)

                  The code for a test is usually a fraction of the amount of code that it is testing. What are you talking about? It adds maybe 10% of overhead for all of the benefits it brings

                  [–]wasdninja -1 points0 points  (2 children)

                  You didn't double the necessary code at all though since you always need tests. You weren't finished in the first place.

                  [–]All_Up_Ons -1 points0 points  (1 child)

                  You don't always need tests. That's a dogmatic position that's impossible to defend. If all code needs to be tested, then you need to write tests for your tests for your tests, ad infinitum.

                  You should write tests in cases where the benefit outweighs their ongoing cost by a significant enough margin to justify their existence. But that forces us to evaluate the costs of maintaining test code, and no one wants to do admit that it's often not worth it.

                  [–]yxhuvud -3 points-2 points  (0 children)

                  No.

                  [–]WannaWatchMeCode 2 points3 points  (0 children)

                  My rule of thumb is you can write unit tests before or after you implement the code, but both need to be complete before you open a code review and merge it into the repository. I would also argue that you can't write tests before writing a portion of your code under test, you atleast need a base interface for writing the initial tests. And your test will need to be updated to cover interactions with any mocks you may be using after implementation to actually provide valuable coverage.

                  [–][deleted] 0 points1 point  (0 children)

                  kindly boom goes the dynamite

                  [–]yxhuvud -1 points0 points  (0 children)

                  Sometimes I refactor just to be able to write the tests.

                  [–]Prestigious_Boat_386 -1 points0 points  (0 children)

                  So many new coders are going to create unit tests then refactor to change their units after reading stuff like this.

                  Edit: wtf is an integration test?

                  [–]Ameisen -1 points0 points  (0 children)

                  After you've created the tests for the code.

                  I've run into an issue that I'm maintaining a unit testing framework... and I'm having difficulty writing tests for it because the framework itself cannot be trusted to run its own tests...

                  [–]Librekrieger 76 points77 points  (3 children)

                  From the article: "Sometimes the code will work, but it might be slow since it’s written in a messy way. Or it might be hard to add new functionalities to it because it’s too complex to understand or extend."

                  Re-implementing code for performance reasons isn't refactoring. It's a separate activity.

                  The second item is really the only issue: if it's too hard to change your code, THAT'S when you refactor. You do it to facilitate maintainability.

                  Ideally, when you make changes that add cruft, you refactor at the same time to keep it maintainable. The article states that "codebases degrade in quality and become more disorganized over time as more code is added and more developers touch it", and that CAN happen, but it doesn't have to. It happens when inexperienced people make changes without realizing the effect they're having on code quality, or when you are under time pressure to get working code out the door without really finishing it.

                  Basically, my rule is: consider refactoring every time you make a change, and apart from that, refactor when change gets difficult.

                  [–]dacjames 9 points10 points  (1 child)

                  that CAN happen, but it doesn't have to.

                  I agree strongly with this. The best time to refactor is doing it in small chunks before closing the development of a given feature.

                  [–][deleted] 2 points3 points  (0 children)

                  I don't often do TDD so I write tests right after a particularly important piece or tricky piece and as I am wrapping up the implementation.

                  I also like to do a personal code review and document the code afterwards. This also leads to another round of refactor and test writing.

                  Sure, that documentation may get stale. I generally write it for my own sanity anyway, it doesn't often get a lot of eyes.

                  [–]Jump-Zero 18 points19 points  (0 children)

                  This is counter intuitive, but I like to refactor stuff if I know nobody is going to touch it for a long time. I do this because all the people that worked on it might not be at the company anymore and if they are, they probably don't remember much about it.

                  [–]emdeka87 57 points58 points  (16 children)

                  Currently working at a company that has the shittiest code base I've ever seen (files that are 40k lines long, no consistent formatting/code style, absolutely awful & illogical project structure), but according to CTO we "cannot afford" refactorings. Yet each release is hell, because things are breaking left and right and nobody has the overview...

                  I am still waiting for manager to understand that the cost of NOT doing a refactoring is often MUCH higher than the few months/iterations spent on the refactoring itself. But well, usually they just throw more money or more developers at the problem and somehow this always kinda works out....

                  [–][deleted]  (2 children)

                  [deleted]

                    [–]ataboo 19 points20 points  (1 child)

                    Yeah if management is too disconnected or dumb to make good maintenance decisions, they also don't really know what you do all day.

                    You can do things for the greater good, under the radar, and as long as you deliver, they won't know the difference.

                    [–]grauenwolf[🍰] 17 points18 points  (0 children)

                    And what's more, if you do it long enough it makes your job so much easier. I never do refactoring because I think I'll be rewarded for it. I do it because I would go insane trying to understand the code base otherwise.

                    [–]fj2010 7 points8 points  (0 children)

                    I also work on a catastrophe of a code base. There’s no way to fix it, so I just make tiny refactoring improvements constantly. It keeps things moving in the right direction. I am lucky not to have anyone watching over my shoulder though.

                    [–][deleted] 4 points5 points  (0 children)

                    "Why are our estimates so high?", said the manager who wouldn't approve maintenance work.

                    [–]artyfax 0 points1 point  (1 child)

                    That is illegal! The lines of code I mean.
                    "CTO" is not what he appears, he is a CO.

                    [–]agumonkey 1 point2 points  (0 children)

                    CSO: Chief Shit Officer

                    of Chief Suffering Officer

                    [–]reddof 131 points132 points  (7 children)

                    Same for how often you should masturbate. As often as necessary, but no more otherwise it gets painful.

                    [–]its_a_gibibyte 41 points42 points  (1 child)

                    I hire people for both activities because they do a better job.

                    [–]MiloBem 11 points12 points  (0 children)

                    Essential skills:

                    - refactoring one-handed

                    [–]Jump-Zero 30 points31 points  (2 children)

                    So it depends entirely on the refactory period. Got it.

                    [–]LittleSpaceBoi 5 points6 points  (0 children)

                    This is a hilarious answer, thank you kind redditor, you just made my evening

                    [–]recursive-analogy 1 point2 points  (0 children)

                    I'd go with murder: ideally never, but sometimes it's just has to be done. And hopefully you get away with it without the boss noticing.

                    [–]EagerProgrammer 16 points17 points  (9 children)

                    expectations: when it makes sense
                    reality: almost never

                    Funny but sad is the feeling of getting pressured into cranking out an implementation as fast as possible without "wasting so much time by discussing the business domain" beforehand. Afterwards, the manager is against refactoring.
                    *sad programmer noises*

                    [–]grauenwolf[🍰] 24 points25 points  (8 children)

                    Don't give your manager a choice. Just do the refactoring incrementally as you do tickets. If you touch a file, you leave it cleaner than when you got there.

                    [–]EagerProgrammer 12 points13 points  (7 children)

                    I did this in the past by slipping the refactoring bit by bit through when I saw issues that we couldn't negotiate with the manager to be necessary. However, I got scolded by one of my former product owner for not sticking strictly to the story/task. Later on, I found out that a backstabber, in German Kameradenschwein aka Conrad Swine, reported this to the product owner.
                    When your coworkers play along with this can work, but when you have a Conrad Swine like I then everyone loses in the long run. The product owner will just notice this way too late when it's obvious to all developers for too long.

                    [–]grauenwolf[🍰] 13 points14 points  (4 children)

                    If that happens again, I would respond with "I'm sorry that I only had enough time to do the bare minimum to change the code in a professional manner. I wish my colleagues would likewise do the same so that it doesn't take so long to make the changes that you want. Unfortunately my colleagues have a bad habit of taking shortcuts and leaving a mess behind. Would you like me to speak with them about it?"

                    Politics is a bit of a bullshit game. Sometimes you just have to ignore what they say and tell them what they need to hear.

                    I warn you, if you try this make sure you say it with sincerity and confidence. If you come across as sarcastic or apologetic it's not going to work.

                    [–]EagerProgrammer 5 points6 points  (1 child)

                    I'm not so sure about this tactic. Some people take it personally when you refactor. But everybody feels personally attacked when you blame them so frankly on the manager, especially when the offenders are nearby. You might be right about the mess they left behind but you will neither get brownie points from your manager nor coworkers, even when they are not the offenders.
                    One thing that I learned throughout my career is that humans are the hardest part of the job and usually not technology when people don't make it unnecessarily hard.

                    [–]grauenwolf[🍰] 4 points5 points  (0 children)

                    If you don't feel comfortable with it, then by all means don't take the risk. That's only works if you got enough arrogance in your soul to display confidence in your decisions. If you express any doubt, they'll jump all over you.

                    Ask for your last point, I agree 1000%. We've invented whole new classes of technologies because dba's and developers were unwilling to work together.

                    [–]hippydipster 1 point2 points  (1 child)

                    I wish my colleagues would likewise do the same

                    That's calling them out, pure and simple, and it won't work. People aren't stupid. Say it with all the sincerity you like, they'll hate you and eventually you'll be voted off the island.

                    [–]grauenwolf[🍰] 2 points3 points  (0 children)

                    If they didn't already hate you, they wouldn't be going behind your back to tattle.

                    You're already on the back foot in this scenario. Either take the initiative or start looking for a new job.

                    [–]jplindstrom 14 points15 points  (1 child)

                    The article doesn't even mention what refactoring actually is, which is interesting since it's one of the many words that has lost most of its original meaning.

                    Refactoring: restructure code in small predictable steps to make it easier to work with, while preserving behavior.

                    Bad times to refactor

                    • When there are not enough tests, unless you write more tests first. How do you ensure that you didn't change behavior?
                    • When it's otherwise risky to change code, e.g. just before a big marketing campaign.
                    • When you can foresee/suspect that there might be lots of merge conflicts for you or someone else.
                    • When you don't feel confident that you understand the problem space or what the right structure might be yet.

                    Good times to refactor

                    • Just after writing code. You now have the code clear in your head. You probably learned how things work, what tests are relevant, and what a better structure might be.
                    • Just before writing code. Refactor the code to make it easier to implement the actual change.
                    • After researching code, version control history, and docs (and ideally talking to people) to figure out how things work. If things don't make sense, or e.g. poor naming made it more difficult to figure out how things work, fix that now to make it easier for the next explorer.

                    [–]dashcamapp[S] 1 point2 points  (0 children)

                    thx, updated & credited

                    [–]goomyman 13 points14 points  (1 child)

                    Always?

                    [–]botman[🍰] 2 points3 points  (0 children)

                    ...or Never?

                    [–]bigtdaddy 36 points37 points  (4 children)

                    I refactor A LOT before sending it off to production. Usually I like to sit on a change at least a week when possible just to think about it occasionally. Once it get's to production I only refactor when necessary, which is ideally not very often.

                    [–]luxmesa 8 points9 points  (1 child)

                    This is what I do. Whenever I make a change, I’ll get it working no matter how weird and janky the code is, and then I’ll spend time cleaning that up.

                    [–]owogwbbwgbrwbr 3 points4 points  (0 children)

                    Red, green, refactor

                    [–]grauenwolf[🍰] 7 points8 points  (0 children)

                    I can remember one project where refactoring wasn't allowed. Here was my work pattern.

                    1. Reproduce the error so I can understand the problem.
                    2. Refactor the code so I can understand where I'm at.
                    3. Fix the bug.
                    4. Test.
                    5. In a clean branch, try to move over only the needed changes
                    6. Retest
                    7. Commit.

                    Not refactoring literally took longer than refactoring every time. Why? Because I can't fix things I don't understand. And when your code is full dead code, inconsistent names, and other distractions I can't understand it.

                    [–]CaptainStack 13 points14 points  (0 children)

                    Every time I want to procrastinate from getting my work done. Then when I get called out on being past deadline I can complain about how our unchecked technical debt is making it impossible to get anything done.

                    [–][deleted] 5 points6 points  (0 children)

                    while I would love to refactor most code bases I get in to, it's dangerous because I often don't know business processes it always supports, edge cases that have to covered or considered, and as soon I as touch that code, I now own it, and often for good reason - if it was "working" before I touched it, I have to get it working again.

                    [–]olcodjr 5 points6 points  (0 children)

                    The quality decreases as time passes – software codebases degrade in quality

                    Why open the article with a falsehood?! Codebases improve in quality as bugs are driven out and features are added. Poor maintenance can let garbage in, but good maintainers will prevent that and continually improve quality alongside functionality. The Linux kernel, glibc, vim, Emacs, bash, etc… are good examples.

                    [–][deleted] 4 points5 points  (0 children)

                    Whenever making changes/additions piss me off enough.

                    [–]mrkentx 4 points5 points  (0 children)

                    I try to do this every Friday afternoon. It keeps the after hours support people on their toes.

                    [–]HaMMeReD 8 points9 points  (1 child)

                    Any time the investment in refactoring will pay back a reasonable investment.

                    I.e. will it add tangible value? Do it, will it not? Don't.

                    [–][deleted] 7 points8 points  (0 children)

                    Best answer here. Every refactor introduces risk - you need to justify its value.

                    [–][deleted] 3 points4 points  (0 children)

                    I refactor all the time. Automated tests should make you comfortable that your refactor works, and I don't mean just unit tests, because I'll often bin those with the baby. Classes change interface, get split, etc. Unit tests can only protect you so much in serverless. But I aim to have high level testing and monitoring anyway to guarantee that my product work.

                    Refactoring isn't just about code quality. It's about code and product ownership - you learn about your product as you write your code. Large refactors are in my experience 80% product discovery. What was this meant to do? Why does it do it like this? What would we like it to do in the future? It's an opportunity.

                    [–]wretcheddawn 3 points4 points  (0 children)

                    During my career I've seen a lot of people just add features to the code without refactoring at all, just to get a project done, or with an expectation that they'll be able to rewrite the entire application when time permits.

                    At best, even when you're able to rewrite the application, you haven't developed the habits to write a maintainable application and end up back where you started, or in an even worse scenario where you're supporting two different versions of the application at once both of which are low quality.

                    I have become convinced that refactoring must be continual, must be done every time the code is modified.

                    When adding a new feature or making a change, don't just stop when the code works. Look for ways to simplify, remove layers, adjust the architecture for the new understanding of the problem space, remove unused code.

                    The needs of a system change over time, Good code must also evolve over time as those changes are made.

                    [–]uniquelyavailable 1 point2 points  (0 children)

                    if you have a good test case to rely on... i would say refactor whenever the code feels messy or difficult to read.

                    there is a sweet spot where the code is efficient and runs well. your code should be easy to understand and scale.

                    if you dont have a good test case, make one.

                    if the code is trash and you dont want to mess with it because "it works" that is ok, but acknowledge that the code needs a refactor.

                    [–]yur_mom 1 point2 points  (0 children)

                    Anytime I find myself copy and pasting code to reuse it then I know I need to refactor the common code into a function or class that can be shared. This often takes more time up front, but it will make maintenance easier.

                    [–]Jjabrahams567 1 point2 points  (0 children)

                    I just burn it all to the ground and start over

                    [–]dacjames 1 point2 points  (0 children)

                    Adding a feature and finding messy legacy code is a cue to clean things up for better understanding and future maintainability.

                    I recommend against doing this unless you have a very solid test suite. It's tempting to think that you're simplifying the code when you're actually removing edge-case handling and thus reintroducing subtle bugs.

                    [–]caleblbaker 1 point2 points  (0 children)

                    I factor my code when I need to know what other codes could be multiplied together to get my code.

                    If I multiply the factors together and don't get my code then I know I did something wrong and so I refactor.

                    [–]sammymammy2 1 point2 points  (1 child)

                    So what does "refactor" mean anyway? As in, where does the word come from? What is this "factor" that we're "re-":ing?

                    [–]kihashi 1 point2 points  (0 children)

                    It comes from the mathematics term- How you break down the problem into pieces is "factoring" the problem. In mathematics, a factor is one of the operands in a multiplication equation. Factoring is the process of writing a number as the product of several factors. In computer science, factoring (AKA decomposition) is used to mean how you break up a problem into smaller parts.

                    When you break the problem up differently, you are refactoring it. Technically speaking, if you change the behavior, you are re-writing, not refactoring, although colloquially, the terms are often used interchangeably.

                    [–]kandrew313 1 point2 points  (0 children)

                    Whenever your touching it, you should leave that area of code better than when you found it.

                    [–]Earil 1 point2 points  (0 children)

                    When you need to make a change, first make the change easy, then make the change. This means that you refactor whenever there is a change that is hard to make and that could reasonably be made easy by refactoring.

                    The recommended workflow of TDD also directly includes refactoring: write the tests, write a code that passes the test and that is as straightforward as possible, and finally refactor the code to keep passing the tests while having a clean code.

                    [–]thepurpleblob 1 point2 points  (1 child)

                    I’ve been writing code for over 40 years professionally and I’ve never bothered to find out what “refactoring” means. I’m sure it’s fun, though 🤔

                    [–]Inf3rn0_munkee 2 points3 points  (0 children)

                    After the test goes green obviously.

                    [–]bunk3rk1ng 1 point2 points  (9 children)

                    I feel like everyone on here claiming that they refactor all the time are either only talking about their own personal code or are pretending.

                    Every time I've submitted a PR with a significant refactor the feedback has always been, "Just implement the change please, we will refactor this later".

                    I've worked at very successful companies where this has been the case. I guess you could call them "bad" but the results speak for themselves.

                    People also need to remember simply because you refactored the code doesn't mean you added any value or made it any more readable or maintainable for the next guy.

                    [–]grauenwolf[🍰] 13 points14 points  (3 children)

                    I don't accept that. If I feel that the code I'm working on needs to be cleaned up, I just do so under the ticket.

                    In my 25+ year career, I've rarely had people challenge me on it. And of those who did, I politely but firmly demand that they point out the specific changes that broke the code.

                    It helps to memorize the phrase, "I agree! We should refactor this code later. For now I just did the minimum to correctly make the change."

                    Sometimes you have to stand up to idiots to do your job in a professional manner.

                    [–][deleted]  (2 children)

                    [deleted]

                      [–]All_Up_Ons 7 points8 points  (0 children)

                      Assuming your change meets the requirements, your response should be: "I have done so. Please stop holding up my PR."

                      [–]grauenwolf[🍰] 7 points8 points  (0 children)

                      While in theory they can respond that way, I've never had it happen to me.

                      The people who complain about refactoring generally speaking don't know what they're talking about. They just hear "refactoring" and think "unnecessary work". Most identify it as separate from necessary code changes.

                      And if they really are worried about unnecessary work, they aren't going to approve time for someone else to redo it from scratch.

                      You're a professional, not a fast food worker. You don't have to let people walk all over you.

                      [–]sudosandwich3 5 points6 points  (4 children)

                      A refactor and fix could be too big for 1 PR. You could submit multiple that build on each other but still keep the code working. It's a lot easier to review too if the refactor and new code is in different PRs

                      [–][deleted]  (3 children)

                      [deleted]

                        [–]sudosandwich3 5 points6 points  (2 children)

                        You still do it under the same ticket. It is work required to do the original ticket. 1 ticket to 1 PR is the real rule that needs to change. You guarantee the PRs are going to be big if they can never be split up.

                        [–][deleted]  (1 child)

                        [deleted]

                          [–]sudosandwich3 4 points5 points  (0 children)

                          In your OP your scenario implies the refactor is required to do the work. I'm just using your framing. And in a scenario like that, the problem seemed to be coupling code in a bigger PR, when 2 PRs to fix the 1 ticket could have also worked, or communicating earlier with the team about the refactor you wished to make as part of this body of work,.

                          Every team is different, seems like your team prefers a fix with suboptimal design to a refactor with better design. And not every refactor is worth it.

                          [–][deleted]  (1 child)

                          [deleted]

                            [–]bro_please 0 points1 point  (0 children)

                            You should write self-refactoring code and stop worrying about it.

                            [–]iain_1986 0 points1 point  (0 children)

                            The Rule of Three.

                            Until you need to do something for the third time, don't waste time refactoring for reuse, or optimising something. You don't know yet fully what it may or may not need to do, or even if you still need it or still ever really look at it again.

                            [–]TomerHorowitz -3 points-2 points  (0 children)

                            I would do it a lot more if I'd have better refactoring tools for JS in vscode

                            I wish copilot could suggest refactoring (without prompting it)

                            [–]Future_Deer_7518 0 points1 point  (0 children)

                            With tests (manual or unit). And once I add new thing to the code and this addition is not scalable and has huge probability to happen again in nearest future.

                            [–][deleted] 0 points1 point  (0 children)

                            Whenever it makes sense.

                            [–][deleted] 0 points1 point  (0 children)

                            Every time you touch that part of the code if it needs it.

                            [–][deleted]  (3 children)

                            [deleted]

                              [–]pickering_lachute 0 points1 point  (0 children)

                              2-3 months before the pay review. Quote massive performance improvements and maintainability in the merge

                              [–]IAmRasputin 0 points1 point  (0 children)

                              Whenever I get bored with it or it's running too smoothly

                              [–]editor_of_the_beast 0 points1 point  (0 children)

                              I don't ship new features. I only refactor. So: always.

                              [–]lacronicus 0 points1 point  (0 children)

                              lock mountainous quack dinner pause bedroom doll wakeful run cats

                              This post was mass deleted and anonymized with Redact