Some time ago I found my old articles, from previous blog. Some of them are 5 or more years old, written in Polish, from times where I was spending more time far away from coding. In those times, I was focused on managing and “architecting”. It gave me a strange perspective on things. Few months back, I woke up with this idea to comment and criticize my own thoughts. I don’t know if you are going to like it, but at least for one person, it was fun 🙂 And it was me.
Before we start, lots of love and thanks to my wife, who took this burden on her shoulders, and translated these articles.
I include the whole article with my comments and thoughts inlined. Enjoy, or not 🙂
The 1980’s. Simple Minds and their classic Alive and Kicking (especially in
I have not been here for a long time. I neglected this small group of
readers, the blogosphere, and Googlebot. In the meantime, I changed my job, explored Northern Europe, survived the deadly “afterparty” after the first edition of the refreshed Confitura, and started a PhD in JBoss 4.2.3 GA.
I shut myself in my small space, at the new desk with a view of Krakow and repeat like mantra the mvn clean package, run and subsequent curse through gritted teeth and git reset. I turned off Google Reader, InfoQ and a few other “disturbers”. The only entertainment is to keep alive the noble idea of “zero inbox”.
Everything was dipped like nachos in spicy salsa in JBoss 4.2.3.custom_fixes_and_extensions, something I consider last stable version of JBoss. This application was a pure proof that it is not a challenge to make simple things simple, but it is a true mastery to turn CRUD application into “feature set” orgy, customizations “gang bang” and “we have wizards everywhere” extravaganza. Deal with it.
For clarity, the code I am working on, is not bad, terrible, unreadable or fatal. It is also not that it underwhelmed me, disappointed or plunged into the black as espresso despair. The man already knows what to expect, and accepts the fact that the client is the Lord and basta. And a racial purity of the code, its kosher, remains in a beer reverie in a cigarette smoke.
Actually, it was. Bad, terrible, unreadable and fatal code. This is, my dear friend, the first stage of working with legacy systems. Just admit it and say it out loud: “this code is garbage”. But do it one time. I think we spent too much time on whingeing: “who wrote this code?”, “this is shit”, “I am not going to work with it”, “this is pure spaghetti with hand grenade in it”. It is, and so what?
Keep in mind, you Mr. Perfect High And Mighty, that probably somebody, in 10 years from now, will tell all of these things about your “shiny code”.
Yes, somebody had a bad day 20 years ago. Somebody was forced to follow “architecture guidelines”. Somebody didn’t care at all, because he knew he would be moved to another project in a week. I can think about hundreds of reasons why this code is bad. There are days in my life where I shouldn’t be allowed to code or even get close to an IDE. Because I am fed up, because I am tired or with a mountain high hangover. Or my kids are sick, or my parents are not well.
First of all, you and I, we are human beings and work is not life. (Maybe it is when you are 20 or 30 but not when you are 40 🙂 )
So just don’t try to improve your self-esteem by saying: “I would never ever write this code this way, these people were stupid”. I bet you would have written even worse code in the same context this person was in.
So, “yes, this code is bad”, end of story. Let’s do something about it. The first step in a whole organization is to admit how bad it is and embrace the fact that it actually makes money, because you still have your job. Period.
So what pushes me to these late evening thoughts? For some time now, I live outside the mainstream of a TDD, BDD, DDD and Software Craftsmanship (now these toys do not quite fit into my sandbox). I realized how hard it is to work without these tools. How hard, at times, it was when I could use them on a daily basis but it is even harder to survive without them (maybe it’s just a matter of habit). Currently, with bare hands, I decompose the code structure, make destruction of local dependencies, discourage next application layers, and remove/disassemble piles of false assumptions and recognized truths. My human nature does not allow me, however, to accept the existing state of things and trying to understand the motivations and context.
What did go wrong? Because it went wrong all the way down to the gates of hell. It exploded in our hands right into faces of surprised CEO and other C-level executives. Oh God, this was so much fun talking with these people during these days.
I thought that quality was important. I was so fooled by all this software quality talks that it narrowed my view on the system. Don’t get me wrong, it is important but not when you have to dive into savage. When you are right before jump into shit and you don’t know how deep it is, last thing you need is quality. You need a world-class life support system.
You need a working continuous integration. You need tests which are not “false positive” all the time. You need bloody fast build times so you can experiment with “workarounds” all the day and all of the night. You need static code analysis quality gates which will make sure you will not get a system into worse state with your refactorings. You need access to production, without stupid procedures which give you systems logs a week after crash. As you are diving into shit, so how will these procedures make your journey more enjoyable?
And last but not least. You have to remove all signs of bullshit in management of your organization, at all levels. All this “our best people are working on it” (of course they are), “we need to break silos” (of course we need to, first start with all these management levels), “we have certain values” (no shit, really? I am proud of you. Do your values reflect quality of code you have?), “business value is priority” (how about all the money flushed down the pipes with all this technical debt you have?).
Back to the topic.
Fast turnaround and feedback is key. Especially in first days, weeks and months. It means it is more important to have “one click deployment” and working development environment on people’s laptops than “clean code”. Remember, the deeper you dive, your focus will need to change. But in first moments, everything you do, should be driven by this question: “Will I break the system? Yes? How fast will I recover?”
And this is something I have ignored. I thought that if I had a better coverage, response for class or cohesion metrics, everything would be fine.
I try not to search the guilty (git log will not change anything). I assume the good will of creators, unclear requirements and pressure of time.
So where does the reason lie? In JBoss AS. Do not take it too personally. It might as well be the Spring Framework, OSGi, Grails or homemade, tailor-made platform. Each platform/framework, or other kind of animal, carries the initial technical debt. You think that JBoss does not have a technical debt, and its code is clean as the proverbial glass of “wyborowa”. Stop delude yourselves. Every piece of code that was created is burdened with lesser or greater debt.
There is also another category of debt that comes along with a choice of “this only solution”.
Our lack of complete knowledge of the selected technology, gaps in documentation, outdated tutorials, things that developers do not want to speak loud and “miraculous” solutions available in the network. So this is what Dan North presented in the “Deliberate Discovery”. Our debt is what we do not know that we do not know :). And in this way, the simple things, as provided in platform are entwined by “hacks”, aspects, modified libraries just to make ends meet and release it.
I , kind of, still agree with these statements. With a small addition. Very often, we invest in certain technology, make it a backbone of the whole system. We love it so much that we see every problem through it. Even when deep in the heart we know it doesn’t fit our stack, our needs or our infrastructure. But because we have invested in it so much, so many hours, we think it is “the solution” to all of our problems. Sooner or later we are going to create “extensions”, “patches” and “proxies” to justify its existence in our environment. The truth is, when it doesn’t fit, it doesn’t fit. I see this kind of behaviour as one of key technical debt sources. Together with “I know shit about this NoSQL database, but will use it everywhere” and “cool kids use it these days, it has to be good”.
One thing that can be helpful in these moments is architecture decisions log. A place where you store all your stupid decisions with a context. Why have you decided to use X? What kind of assumptions did you make about X? When these assumptions appear to be false, you will have a clear evidence why it is a stupid choice.
And I didn’t have architecture decisions log.
Of course, you can still throw a pebble of our ignorance in the area of the domain business but at this stage I’m not going to wear a noose around my neck.
Now we get to the root of the problem. How important is the choice of our target, unique and beloved platform? In my opinion, it does not quite matter, and regardless of the choice, we incur a technical debt prior to writing the first line of code. And we will amaze future generations by our ignorance.
Oh, how wrong I was.
Yes, it does matter. The technology you choose, will drive your success or failure, will be there with you till the end of your life, will be your “hand of doom” in these lovely moments where whole your SRE team will sit by the camp fire and watch your DC burn in flames.
So why is the technology important? That’s tricky. In my old brain there is this hidden thought, hidden deep in darkest corners of my being.
“It is important to know how easy it will be to remove this technology from the stack, when the time comes”
There are frameworks, libraries and other stuff, which require you to bond your code with it really, really strong. You have to put import, annotation, extend, here and there. And slowly, your code is strangled into the framework, you cannot move, you cannot breathe, you cannot do anything which is not permitted by “uber framework”.
What if we could build our applications without single import from a framework whose name I am not going to reveal? What if we could build whole systems just using language features and its standard library?
That’s nothing new. Ports & adapters or onion architecture.
But hey, sooner or later, you will have to change your technology stack. Why do you need to change your so-called “business logic” code? It’s orthogonal concern for me.
Don’t let your framework strangle your “business logic” code.
Our debt will grow with each new version of JBoss or Spring to which we will not have time to move our application. Theoretically, the ignorance of the creators of those platforms will diminish with each new version. So lagging is not in our interest. But who can afford it? It is better to run up a debt.
It will not be shown in the annual financial statements anyway.
What’s interesting, we have not yet worked out a clear and effective approach to such problems (talking about “legacy code, architecture and design”). I know you will bombard me now with comments about my reading ignorance. But of course, I did read the “Working with legacy code” and “Refactoring to patterns”. However, each such application with which you will work, is unique in the set “brainfucks” which surrendered its creator. And that is why I believe, that if you seek real challenges, intellectual puzzles, and work that will bring you waves of elation and the avalanche of falls, look for some “legacy” system. Personally, I believe that none of the new, written from scratch applications, in the latest “frameworks”, extremely dynamic languages, giving you sharp tools into your hands, does not make so much pleasure and pride in a job well done as solid “legacy” put in your hands for straightening. Why, you ask?
Welcome to the moment when you start to accuse about lack of diversity and empathy in my way of thinking. But I have stopped worrying about what people thought ages ago (except carefully chosen a small circle of people who I respect).
“Everyone can code”. That’s a terrifying idea. We should, of course, create an open, welcoming place where everyone would feel safe, regardless of our background, skills and things that make as different (in the first blink of an eye). The thing that we have to even discuss it, it’s a pity and shame for us as human beings. That we are so miserable, that we put people in boxes, and create boundaries. As we now talk about it, it creates the other extreme of this problem. However, let’s leave it for another discussion.
Do we really believe that the only way to solve shortage of talent in IT is to have more people coding. Really? If it is true, it means that we have also failed as an industry in building right tools, paradigms and practices. Do you remember this joke about pregnant woman and project management? This is what I am talking about.
I have recently read a nice write up about Alan’s Kay idea of Moore’s law in software development. That’s sad, that it didn’t happen. That hardware outperforms software at so many levels. That we are where we are mainly because of advances in hardware. Maybe I am wrong. I hope so.
Good app is built around hacks. This is not TDD, BDD, DDD and Software Craftsmanship but HFDD (Hack it and Fuck it Driven Development). The new better paradigm 🙂
The future of IT, to the fear and general scandal, is programming archeology. And yet it is because of archaeology we learn about the past generations and their customs, we reconstruct course of events, we expand our experience and thus we become better. Sometimes also, we discover an extinct technology, and when we see that it is good, we put the new sticker on it and sell as a breakthrough discovery.
That’s the end. No final word.No closing comment. Just many thanks to Wiktor, Krzysiek, Kuba, Paweł and Jarek. You didn’t know, but you were inspiration too many thoughts in this post. I have a feeling that lots of these thoughts deserve their own post but I am too lazy to continue;)