4 ms·
My work in the past consisted mostly of dissecting and refactoring large legacy codebases. Usually after anybody who actually understood it already left and whe
by lmilcin 5y ago
My work in the past consisted mostly of dissecting and refactoring large legacy codebases. Usually after anybody who actually understood it already left and where the codebase is too large and rotten for anybody new to be able or willing to learn it.
I have my own process I apply for any change to code. The basic goal is to introduce zero defects to the code that I do not control/know. Which is crucial when I want to make thousands of changes to a huge application where if I make a mistake it can be very costly to the client, can cost me a huge amount of effort to fix and can completely undermine my effort.
Usually there is no good way to test the changes. I make hundreds or thousands of individual refactors, bundle them up and kind of hope I haven't broken anything in the process.
Some of these applications are just too large for one person to be able to comprehend. They either have vast user interfaces or vast network of integrations. That and no ability to test it in automated way.
This is the reasons why these applications usually aren't taken good care of -- new developers (new, not necessarily junior) are just too scared and unprepared to do anything than smallest changes and that with huge amount of effort.
From my experience, the programming language and environment plays enormous role in making this possible.
The most basic questions I may have when analysing the code I want to change are:
1) What is the thing I am looking at? For example, the exact type of variable, parameter, code for method, etc.
2) Where is the thing I am looking at referenced from? Usually when I want to modify a piece of badly written code, I have to be able to find and analyse every single usage of it.
3) When is the thing I am looking at being executed?
It is not just the ability to answer these questions -- I need to be able to answer them with absolute precision.
Since I program mostly Java, all that information is usually available to me. #3 is sometimes a little bit more tricky but if you can hunt all usages you can typically get to it with some effort.
But that is not the case for most programming languages these days. For example, I tried this with a large Python application and I have utterly failed and had to tell my client I can't help them. Which tells me that most programming languages are not suited to building large, complicated systems that somebody might want to be able to analyse and refactor in the future.
- beebmam 5y ago#2 and #3 are very difficult in Java when working with frameworks like Spring. Spring obscures much of its internal mechanisms, and it takes a long time to build the knowledge needed to understand all of the nuances in it (and to even debug it). Jonathan Blow's arguments against frameworks in general apply strongly to the Spring Framework. #1 is usually solved by using strongly typed languages, like Java or plenty of others
- lmilcin 5y agoIn general case you would be right -- Spring does complicate things by hiding some of the actual references. But reality is that most projects use very simple dependency injection rules. Most use just singleton beans and occasionally profiles for different environments (mostly to access external components like databases or APIs) and that is practically the extent of the problem. Spring is flexible on paper. In reality (and very fortunately for me), most projects follow the examples and conventions you can find on the Internet. Which makes pretty much every Spring application look like any other Spring app, even if they don't have to. By giving defined, recognisable structure to the application, Spring actually makes part of work easier. When I see controllers, repositories, services, etc., I usually know what I can expect. Problems start when you find a project written by "smart" developers. These people are smart enough to write very complex structures and "customise" their Spring experience, but not smart enough to figure out they should separate app development from satisfying their intellectual curiosity.
- marginalia_nu 5y agoI feel the reason most Spring applications look similar is because the Developers have been copy-pasting from the same Baeldung-articles. Copy-paste driven development is something you get a lot of when you are working with frameworks. Since the framework is itself inscrutable, it's nearly impossible to properly understand. So developers copy.
- lmilcin 5y agoI wouldn't say that is necessarily fault of Spring (though scope creep might be an important contributor). I think the basic causes are: 1) Because most developers almost never need more than what you can find on Baeldung/Stack*. And even if they need, they need it for very small pieces of the application and the rest is just boilerplate. 2) Because you are penalised for customising the structure of your Spring application. You do that and you expose yourself to various complicated problems. 3) Because, frankly, Java is a bad programming language from the point of view of building abstractions. I would personally prefer to program applications in Common Lisp or even Clojure (or any other Lisp for that matter) if only for some reason these projects did not typically end in unmaintainable mess even well before Java projects do. It is truly tragic that Lisp and strong typing are fundamentally incompatible with each other. There are different types of unmaintainable mess -- mess caused by copying and pasting stuff typically committed by novice developers who don't know any better tends to be infinitely easier to clean up than mess caused by "advanced" developers running amok with macros, continuations, generators and async callbacks. 4) Because developers are not taught how to structure their code. Nowadays getting something working is all that matters. And this is usually best accomplished by copying/pasting code blocks Lego-style from a dozen different tutorials. How anybody is going to learn to structure their large codebase if they never learned to structure a smaller one? People who advance faster are the ones that are more efficient at copying pasting, not the ones that are better at writing better code.
- xvilka 5y agoWriting complex application in Python or any other dynamic languages is a madness anyway. I often witnessed cases when developers even reused the same variable for different purposes and types just because the language allows it.