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 ...


45

Is there some kind of cultivatable behaviour [...] that can help me at least reduce such kind of mistake Absolutely, it is called four-eyes-principle. If you had you shown your crontab entry to a second person (a person knowing cron, of course), chances are high the mistake would have been avoided. In programming, when it comes to this, people mostly ...


17

The variable n ensures the generated code doesn't fetch the array length for every iteration. It's an optimization that might make a difference in run time depending on the language used, whether the array is actually a collection object or a JavaScript "array", and other optimization details.


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

You don't need ADHD to have this problem. It might be that you are working in environment where you get interrupted often or where you have to work on many things at the same time. So loosing track of your progress or making small mistakes is almost guaranteed. There is one thing you can do to reduce those errors : tests based on specification. First, you ...


12

You always have to be at least two steps away from disaster. That means you never directly push something you just wrote into production. You either test it, or you have it tested, or you have it reviewed, or figure out some other way to have a two step path to disaster. Sometimes I will leave something for the next day and review my work again before ...


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 ...


11

First thing : A pure JS code in a separate file will be cached, reducing the amount of data transfered on each request. Unless you have a very small, page specific JS code, you shouldn't inline it. Other valid reasons are already pointed in Mike's answer. If you have to pass some values from the server to the JS, what you can do instead of injecting JSP ...


9

Two very essential things to understand are that: You can never anticipate every change a customer may ask. I had a customer who decided to switch a two months project from PHP to ASP.NET one week before release and was convinced that this would be an easy change. Any change will have a cost. It doesn't matter if you are using Agile or if you have clean ...


8

What you're talking about is called mutation testing, and there are a number of implementations available. I've not tried either, but there are at least two javascript versions: grunt-mutation-testing, and mutandis


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 ...


7

It depends of the actual meaning of a, b and getProduct. The purpose of getters is to be able to change the actual implementation while keeping the interface of the object the same. For example, if one day, getA becomes return a + 1;, the change is localized to a getter. Real scenario cases are sometimes more complicated than a constant backing field ...


7

There are two primary reasons: Separation of concerns - by having the code in a separate file it is separate from the HTML and may be changed without touching the HTML file. If used in multiple places it allows for a single place to make the change. DRY - Don't Repeat Yourself By having it in a separate file you don't have to repeat the code in several ...


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

Despite established wisdom in writing unit tests, Martin Fowler has said that his idea of a unit is generally "a bunch of closely related classes and treat them as a single unit. Rarely I might take a subset of methods in a class as a unit." So there's no real reason why you shouldn't be unit testing a couple of tightly related methods as one unit. ...


6

It's not exactly clear what you are asking. You can always prove a program correct, if you want. This is independent of the language. The question is, can you get the computer to do the proof for you, or at least check a proof given by you? And the answer is: Yes! In fact, the Curry-Howard-Isomorphism states that there is an isomorphism between logic and ...


6

Previous answers mentioned two points: Reviews. Testing. but there are also three additional elements which may help: Better visualization. By using tools which let you better visualize what you do, you may catch errors earlier. This is particularly illustrative with the cron jobs. Imagine you have a visualization tool which shows you, graphically, ...


5

It's all about understanding. You don't really have to memorize code or something (besides syntax and control statements of course which come in handy sometimes) but you basically want to "memorize" concepts. For example "How can I save memory?" or "How can I parallelize my algorithm?" and/or "How to design a large software such that it is maintainable?" ...


4

If a field value is one of a list of predefined values, your domain will have a real-world value that you can correspond to NULL. All you have to do is look for it. If the Status is not completed its result could be 'NotFinished', 'Unavailable', 'DoesNotExist' or 'Unknown'. Think about this in a non-code way. If you print something and ask a colleague to ...


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

You could always use an interface or an abstract class to define the contract where you have generalized behavior for the ColorText class, but you need to keep the method name the same (AddColorText) public interface IColorText { public abstract void AddColorText(string text); } public class RedColorText : IColorText { public void ...


4

I've never yet seen a customer who asked for poor-quality software. However, what they do want is the cheapest software, and they want it as soon as possible. The cheapest and quickest way to develop software is to throw something together as quickly as possible, then debug it until it does pretty much what you wanted, and doesn't crash too often. At that ...


4

Memorizing code for programming purposes makes about as much sense as memorizing Lord of the Rings if you want to write a fantasy novel.


4

Of course - it's not very effective to reinvent the wheel. If someone else has already solved the problem and made it freely available, why not take advantage of that? However, that road is full of pitfalls. If you don't truly understand what the code is doing and how, or it's a trusted and well known library, you don't want that in your production code. ...


3

It's important to understand that a single method may not be your "unit". To give a contrived example, if (for some reason) you created a class with public methods: Add(object key, object value); Get(object key); which just wrapped a private Dictionary, it would be inconceivable to test just one of those methods at a time, independent of the other. ...


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 ...


3

Use of reflection is often harmful in OO languages if not used with great awareness. I have lost count of how many bad questions I have seen on StackExchange sites where The language in use is OO The author wants to find out which type of object has been passed in and then call one of its methods The author refuses to accept that reflection is the wrong ...


3

From what I have encountered, usually, to build what can be considered as good software, one needs to have a clear set of requirements, maybe not all of them, but at least a set of core rules which will not change. From this, you then choose your architecture, design patterns, languages and frameworks. The problem with this is that most of the times, the ...


3

I think your reasoning is flawed because you consider "best practices" as boolean. However, it's not a question whether you apply them or not. It's "how much" you apply them. For example testing: you can do a couple of manual tests, cover the basic tests automatically, make an extensive automated suite, test also all your libraries/dependencies, ...



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