Tag Info

Hot answers tagged

67

Last time I tried to start a refactoring with unforeseen consequences, and I could not stabilize the build and / or the tests after one day, I gave up and reverted the codebase to the point before the refactoring. Then, I started to analyze what went wrong and developed a better plan how to do the refactoring in smaller steps. So my advice for avoiding ...


52

Is it just a symptom of my previous classes depending too tightly on each other? Sure. One change causing a myriad of other changes is pretty much the definition of coupling. How do I avoid cascading refactors? In the worst sort of codebases, a single change will continue to cascade, eventually causing you to change (almost) everything. Part of ...


21

Programmers aren't the limiting resource. Learning a new language is easy compared to all the domain and program-specific stuff you have to learn when starting at a new company, and people move to new companies all the time. You're talking a language with 300 keywords versus a program with hundreds of thousands of functions. It's not even close. Hardware ...


16

It sound like your refactoring was too ambitious. A refactoring should be applied in small steps, each of which can be completed in (say) 30 minutes - or, in a worst-case scenario, at most a day - and leaves the project buildable and all tests still passing. If you keep each individual change minimal, it really shouldn't be possible for a refactoring to ...


15

Funny you should ask that. My father is a COBOL programmer. Graduated from college, got a job at a large insurance firm. Worked on the same app for his entire career (the same physical mainframe for 30 odd years of that). Spent the last 4 years remotely teaching a team of new graduates in India how to write COBOL. He retired last year. I wouldn't count ...


11

How can I avoid this kind of cascading refactor in the future? Wishful Thinking Design The goal is excellent OO design and implementation for the new feature. Avoiding refactoring is also a goal. Start from scratch and make a design for the new feature that is what you wish you had. Take the time to do it well. Note however that the key here is "add ...


8

From (the wonderful) book Working Effectively with Legacy Code by Michael Feathers: When you break dependencies in legacy code, you often have to suspend your sense of aesthetics a bit. Some dependencies break cleanly; others end up looking less than ideal from a design point of view. They are like the incision points in surgery: there might be a scar ...


8

It is naive to assume that more modern languages are somehow preferable to older ones for a given problem domain. Beyond the issues of risk and the immense cost associated with such modernization is the fact that many legacy environments have their own ecosystem, and have evolved symbiotically with it. These solutions are often the best elixir for a ...


6

It sounds like (especially from the discussions in comments) you've boxed yourself in with self-imposed rules that mean that this "minor" change is the same amount of work as a complete rewrite of the software. The solution has to be "don't do that, then". This is what happens in real projects. Plenty of old APIs have ugly interfaces or abandoned (always ...


6

Languages, such as COBOL, don't require exotic hardware. The only resources that might run out are staff. But as long as there are money to be earned, people will learn necessary skills. Some companies today are rewriting their systems into more fashionable languages - but hey, I had an offer last year from a bank which seemed to be rewriting from C++ to ...


6

PHP isn't a language I have much experience with, but as I understand it both loops are trying to filter the set of keys, so you can extract the structure of the loop into another method that accepts the conditions for filtering as an argument in the form of a function: private function getKeysWhere($entity, $allKeys, $condition) { $result = []; ...


4

Maybe this is somehow useful to you, I will present one way I work on legacy code. There are many more like extracting fields first. It depends, it is different for each piece of legacy code. If it doesn't work the first time, go back one hour (revert changes), try it a second and even a third time, you will get experience at that, under which conditions to ...


4

A simple fix would be to replace the internals of your wrapper to use Threadlocal. So the format() changes from: private DecimalFormat format = new ...; private final Object lock = new Object(); public String format(double value){ synchronized(lock) { return format.format(value); } } to private ThreadLocal<DecimalFormat> format = ...


4

This is sort of problems intended to be dealt with using Template method pattern: ...behavioral design pattern that defines the program skeleton of an algorithm in a method, called template method, which defers some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure... Applied to your ...


3

If you've already used JSP in part of your application, don't rewrite it into a different framework. Chances are, the team you're working with already has some knowledge of JSP, and you'll be able to build on the existing core of pages that utilize it, limiting the amount of work to be done and the subsequent number of bugs needing squashed. Remember your ...


3

How are organisations planning to replace dead languages? In ways that are likely business secrets. When I was last working for a bank they were facing 3 issues: They had hired a new Core system programmer once in the last 20 years an all others were retiring The language was more dead than Cobol. The core system was on a mainframe, which are incredibly ...


3

So just for other PHP guys that may be struggling with functional programming I want to register here the steps I did following Jack's answer. First I refactored each method to extract the condition so I could have an identical code base in both (note how the condition was extracted in both): public function getKeysToInvalidateOnCreation($entity, $allKeys) ...


3

Automated tests. You don't need to be a TDD zealot, nor do you need 100% coverage, but automated tests are what allow you to make changes confidently. In addition, it sounds like you have a design with very high coupling; you should read about the SOLID principles, which are formulated specifically to address this kind of issue in software design. I'd also ...


2

Refactoring is a structured discipline, distinct from cleaning up code as you see fit. You need to have unit tests written before starting, and each step should consist of a specific transformation that you know should make no changes to functionality. The unit tests should pass after every change. Of course, during the refactoring process, you will ...


2

You seem to have some sort of mental block going on. If you want a design that eliminates the duplication, you're going to have to change your design somehow, which you seem resistant to do. You need to look past your current design. Some ways to eliminate the duplication, some of which are better than others: Put the common stuff of the models into a ...


2

Yes, many people consider Service Locator to be an anti-pattern. Depending on how it is implemented it can be difficult to unit test code that uses it, it reduces flexibility because clients can only have a single implementation of each interface, and it relies on run-time type testing so various errors can only be detected at run-time (often only during ...


2

Is it just a symptom of my previous classes depending too tightly on each other? Most probably yes. Although you can get similar effects with a rather nice and clean code base when the requirements change enough How can I avoid this kind of cascading refactorings in the future? Apart from stopping to work on legacy code, you can't I'm afraid. But ...


1

It all comes down to risk management and gut feeling. Try to estimate the following: How big are the costs of the mistake as it is in the code right now. Does it cause recurrent costs? Or costs in form of a risk that it might turn into a bug in the future? What is the cost and the probability of that bug? How big are the costs of fixing it right now: Risk ...


1

Somewhere in your code you have to store the specifics of each product. In your example, the natural place for this seems to be the Specs class, since I guess it is something like the "configuration" of your library. I would extend that class, for example, by an attribute "calcFactor", so your calcVar function will look like this: public function calcVar() ...


1

...I refactored the project to add the feature. As said @Jules, Refactoring and adding features are two very different things. Refactoring is about changing the program's structure without altering its behavior. Adding a feature, on the other hand, is augmenting its behavior. ...but indeed, sometimes you need to change the inner workings to add your ...



Only top voted, non community-wiki answers of a minimum length are eligible