Best practices: Refactoring?

Hi Folks:

Xojo Blog: " Clean Coding in Xojo: Best Practices for Writing Maintainable Code" states:
" 7. Refactor Regularly
Refactoring is the process of improving the structure of your code without changing its functionality. Regular refactoring helps keep your code clean and manageable. It involves restructuring your code to improve its internal structure while maintaining its external behavior."

The other “Best Practices” are excellent, but, Ouch! this “practice” guarantees employment for software developers as we track down obscure, but well-intentioned, bugs in routines that have been running problem-free for years.
For instance,

  1. in Xojo, adding or removing a local variable that has the same name as a global variable can produce nasty side-effects that are hard to trace…

  2. Code that has never been flagged by anti-virus checkers is suddenly reported as false-positive malware. Of course, we report the false-positive to the anti-virus publishers but some are slow to fix the problem or never do. Meanwhile we have to use trial-and-error to discover the suspected code segment. What a waste of time and effort.

  3. Surely you can add your own similar experience …

The blog post is way too generic to be of much help.

Yes, I often refactor but only when I really notice code that is old and creaky. I haven’t had any bad experience with refactoring as far as I can remember. Instead I’m usually happy with my new and improved code.

There is lots of code that also could be refactored. But as long as I can read the code and making changes is not that bad I leave the code as it is. Only when I have troubles fixing a bug or I add a big new feature then I do refactoring.

1 Like

Good naming conventions should help prevent this. For example, prefix global variables with g and prefix class properties with m.

1 Like

Exactly, k.g. - so all the variable names are “refactored” to the “Corporate Coding Standards” du jour. How could anything go wrong? :upside_down_face:

Having Global variables is a bad practice. Why someone would need a global variable like numberOfBreadsProcessed? If they need something like that, there’s a reason, a shared purpose. So create a module or a class for this main purpose, and put this value there, not in global scope but module protected or class public, as BreadProcessing.TotalProcessedBreads
Its short name TotalProcessedBreads is only known inside that logic block, outside, “globally”, they need to refer it as BreadProcessing.TotalProcessedBreads

That’s the modern practice.

2 Likes

I think ‘refactoring’ is a very broad and misunderstood term. It’s not ‘rewrite’ necessarily but it could come into play. Let me explain.

First rule in programming it to get it to work. This can be kind of hack-ish and most likely you did a bunch of shortcuts to get there and didn’t do it ‘right’. Once it’s working you ‘refactor’ to make it better. This can mean a bunch of things such as making it easier to read. Better variable and method names. Adding documentation. Adding sanity checks on inputs. Add error handling. Do a better job of private vs public. Maybe it should be a class or classes. Maybe it needs to be in a thread to keep the UI working. There’s almost an infinite number of things in the first round of refactoring.

The second round might be optimization. If you found that the code is slower than you anticipated then you can look to see if your loops are poorly constructed. Maybe there’s a better way to do file and database i/o. Are you doing db transactions if you’re adding or modifying a ton of data? Maybe eventually you’ll add preemptive threading (which will require a ton of refactoring). Maybe you do some profiling and notice time spent in odd places. I think many people go into this round too soon and frankly spend way too many cycles doing this unnecessarily.

Essentially, do the things to your code that you need to do for long term sustainability after you got it working and then look at speed and efficiency. This, I believe, is what Martin was thinking when he says refactoring your code.

I’m nearing 25 years of using the product. This is my lifecycle on new code. You learn some things as you get better so the first pass starts to incorporate the things you’ve learned so you don’t have to refactor as much. Maybe you spend way less time on the first pass because you just know you have to do it. But I know I generally don’t care about the second round for most code. But it helps to do testing with large datasets to learn where the bottlenecks are. For example, databases act differently when you’re working with millions of rows of data then with a few thousand. So test with reasonably accurate data because it will match real world conditions. For many developers you’ll never have to worry about large datasets so your refactoring experience will be different than mine. Anyway, food for thought.

5 Likes

My aproach is refactor early and often. Any time you find yourself writing the same/similar code over and over, it’s a candidate for being a method. Fix the bug in it once, you fix it everywhere. The corollary is Make a Subclass. If you have common functionality you want in that textbox, subclass it and use that everywhere.

Now, I understand the concern of the OP. If you have speghetti code that is working, there is little cost/benefit in doing a wholesale change. Because you are essentially rewriting it. Bad things can happen. But if you’re continually refactoring as you go, it works in your favor.

6 Likes