Write software, 1.5 year later update CV with fancy buzzwords you used, change job for better comp and repeat. Who cares how did the design mature?
They always have some method/approach which is unparallelled in every metric, except it being reflected in reality.
Years of brainwash caused new developers to make strange looks if you use "if" statement or write comments in your code.
Also acting as if design pattern was some holy code instead of just a name for an approach to some problem (just normal code, but with name).
Same with if statements. There is a point to be made about encoding logic in the type system (type-state pattern), which is great. However, encoding it in indirection and abstraction in the name of saving a couple of lines of imperative code is an especially egregious cancer.
They just repeat what the code is doing. And they are often wrong, because they are not functional, they don't cause compilation errors and they don't cause crashes and make tests fail, so errors in the comments tend to go unnoticed. It is so bad sometimes that I trained myself not to read comments as they can be deceptive.
Comments are a side channel, and IMHO, strictly a side channel. They can be used to express what can't be expressed in code. A common usage is to explain why you chose a solution over another.
I have absolutely no problem with "if" statements, I also think too much indirection is cancer. I have a problem with booleans parameters however. They tend to result in confusing and error prone calls like style(true, false, true), instead of something like style(ITALIC, NO_BOLD, UNDERLINE). In C/C++, I then use "switch" instead of "if". The advantage of "switch" is that the compiler warns you if you forgot a case, you also avoid to problem of accidentally reversing the condition. Make sure your compiler warns you of unintended tall through too.
The problem developers have is they assume it's obvious why things are needed. It's usually not obvious 6 months from now, even if you wrote it.
Though, comments are so much more. They can be like the foreword in a book, the intro paragraph of a paper. While every paragraph might be easy to understand, a foreword to help the reader know what to expect can be invaluable.
Comments can be a scaling tool. A few lines above a test to tell me what is being tested might take 5s to digest, compared to adverse engineering the codd which might take 25s or longer. Multiplied over a dozen test cases, and you have something that can be understood in a minute compared to a dozen minutes. Multiply that put to a half dozen test suites or more and it is a time savings of hours.
As another analogy, it's like someone providing a travel itinerary. If you know the overall itinerary,the individual parts became expected and obvious - so much guess work of "where are we going with this" is removed. Instead that is replaced with, "I now expect these three steps", which makes it easier to recognize those steps and fit them into place.
Another analogy is a puzzle. Well written code is like having very large pieces where you can see a lot of detail. Good commentary is like having the full puzzle picture provided to you. Having both makes for an easy puzzle (which requires less time to understand, which means it requires less time to modify.)
Oh there is. Well written code with good naming and clean structure often doesnt require comments.
I'd argue database-centric design is the only rational place to start if there is money on the table. Done correctly, this forces you to have deep & meaningful conversations with business stakeholders and customers. It was arguably the only way to build this stuff until the resume stat padders wandered into the job market and started throwing nu-SQL & "patterns" at everything that moved, or otherwise drew everyone's attention away from what is effectively a perfect solution for 99.99% of business needs.
So much impedance is unclear thinking and overly complex solutions, it usually combines with inconsistent naming schemes across the stack.
It's easier to gatekeep if you're the only who knows a "game" equals a "contestQuest" because you've created some overloaded polymorphic "quest" system in your backend.
That's on their employer for offering subpar comp. They could have offered that employee a raise instead, and asked him to rewrite his bad code.
Why would an employee deserve a raise if they write bad code that has to be rewritten?
I also particularly dislike it when you’re trying to support two different formats of payload in the same API, and if() based on presence of the new field. Expedient, I’ll grant, but if not reversed quickly it’s soon absolutely unintelligible. The more-stable systems which have to support clients sending older formats do better by versioning the format, and just having multiple implementations doing whole-payload validation, and delegating to the same underlying task-object (you do have one of those outside the class that’s just about interfacing with HTTP, right? ... okay that’s fine, I understand, but you’re gonna do it now.)
On the other hand, sometimes an if-statement is the logic itself. That’s fine.
I will say that, when I see object-oriented code that branches on the particular subclass of a value at run time, it's often one of the earlier sign that the code is getting messy. Subclassing is supposed to be used for a "don't ask, tell" style of programming. A lot of the problems with OOP that people like to complain about aren't really problems with object-oriented programming, per se; they're problems that crop up when object-oriented and procedural programming are mixed in an uncontrolled manner.
If something is there that's not going to be obvious in 6 months time please please document/comment it. Stop building mysterious fences!
In 20 years if it smells like duck it's because the duck was trying to shoehorn functional programming paradigms into ruby by abusing the hell out of blocks, bad clever code is just bad code.
“In the matter of reforming things, as distinct from deforming them, there is one plain and simple principle; a principle which will probably be called a paradox. There exists in such a case a certain institution or law; let us say, for the sake of simplicity, a fence or gate erected across a road. The more modern type of reformer goes gaily up to it and says, "I don't see the use of this; let us clear it away." To which the more intelligent type of reformer will do well to answer: "If you don't see the use of it, I certainly won't let you clear it away. Go away and think. Then, when you can come back and tell me that you do see the use of it, I may allow you to destroy it."
This paradox rests on the most elementary common sense. The gate or fence did not grow there. It was not set up by somnambulists who built it in their sleep. It is highly improbable that it was put there by escaped lunatics who were for some reason loose in the street. Some person had some reason for thinking it would be a good thing for somebody. And until we know what the reason was, we really cannot judge whether the reason was reasonable. It is extremely probable that we have overlooked some whole aspect of the question, if something set up by human beings like ourselves seems to be entirely meaningless and mysterious. There are reformers who get over this difficulty by assuming that all their fathers were fools; but if that be so, we can only say that folly appears to be a hereditary disease. But the truth is that nobody has any business to destroy a social institution until he has really seen it as an historical institution. If he knows how it arose, and what purposes it was supposed to serve, he may really be able to say that they were bad purposes, that they have since become bad purposes, or that they are purposes which are no longer served. But if he simply stares at the thing as a senseless monstrosity that has somehow sprung up in his path, it is he and not the traditionalist who is suffering from an illusion.”
I also don’t really like the fence analogy. A real fence typically exists to demarcate property lines and / or keep things in / out. This is usually perfectly obvious, even if you don’t know who the owner actually is, or the specific role.
Chesterton’s fence is another adage in the “try not to assume things” category.
If anything, consistency hurts the capacity for developers to generalise their understanding of a system. Differences in representation ie. multiple perspectives, help people to develop their understanding of the underlying concepts of the system.
This is important because code doesn't effectively record concepts, intents and oughts. These are things recorded within the context of the system. So the more context, usage and interactions available, the more opportunity for learning.
I think consistency is one of those things that sounds appealing and offers the illusion of making development 'easier' but boils down to someone deciding by fiat that their poorly communicated representation of the system is correct and nobody else should add their own representations of the system to build up a useful level of context and understanding.
Somebody comes along and creates a new, isolated piece of functionality using words for variable names and using the languages type system for numeric values and structures. It works well.
It certainly looks like this inconsistency would make it easier to work with this code in the future. Any conversion functions introduced that deal with the consistent string types and the new inconsistent types will help new developers understand both types of code.
Unless it’s really convoluted, most of the time I’m reading code, I’m concerned with why it’s doing something. Technical consistency helps understand the intent by removing distractions and the need to switch paradigms.
to read
to onboard new people
to review
if you have e.g 3 different ways to handle error handling then it is a mess. one time you expect exceptions, other time monads, other time int values.
One trick I've successfully used to get around this is to basically work on doing that in what would otherwise be slack time, at "background priority". Only when you're done do you give the business owners the proposal, and when they object, say that you already did it and show them the results. Of course this works only if you actually do have slack time, which is normally a given in the sort of enterprise environment these abominations usually get created in; and you understand the existing application to a sufficiently large extent and manage to find a way to simplify it to a fraction of its current size while maintaining backwards compatibility, something that seems to be the exact opposite of what the leads in this story wanted to do.
"It's easier to ask for forgiveness than permission."
People seem to be constantly developing workarounds for the deliberate sabotage by their own superiors preventing them from doing the work they're being paid to do, and even sacrificing their own time for it.
Unfortunately, this keeps the parasites in power as it masks the damage their approaches are doing, or would be doing if left to run their natural course.
Don't be a cuck and pick up others' shit. Especially not if they're higher-paid and get to give you orders.
I hear this, but I also find there's practically no retrospective at the managerial level outside of an acquisition as that's the only way a culture shift is incurred at the upper levels, and that of course all depends on the acquirer.
They're all too busy playing the game of minimizing their exposure, creating leverage and advantage for their ambitions, etc.
I feel like a managerial culture is something that kicks off on day one and gets perpetuated, or it just turns into every other Enterprise eventually.
The “bad” employees left behind are not always bad — hence the quotes. I disagree with that idea. I think it lacks empathy and perspective. There are a lot of instances where good employers stay in situations like this for very valid reasons. Here are some examples:
[...]
They believe they can singlehandedly change bad practices as an individual contributor.
---
I can only say: take the whole company with you to remove technical _and_ organizational debt otherwise any rewrite will end up as the next lava layer.
The problem is essentially invisible to everyone except maybe the dev who is dealing with a high noise-to-signal ratio as a result.
If it was a woodworking shop instead of a code repository, management would constantly see what a mess the shop is due to never being cleaned up properly.
They would never tolerate this because of the way it looks. The woodshop looks sloppy, half-assed and almost sure to be an inefficient place to do work, if it does not get cleaned up on a regular basis.
Because they cannot see deadcode in the repository in a similar manner, it is especially challenging to get them to care.
https://www.joelonsoftware.com/2005/05/11/making-wrong-code-...
At a company, I was brought in to help Version 2 get off the ground (serverless everything, Typescript). Version 1 worked just fine (PHP + VM), they kept none of it. When I left two years later, the new tech leadership started Version 3 (Ruby).
Three rewrites in three years!
I’m not sure why, but I really like working with legacy code (as long as I’m given some autonomy to improve it over time). Part of the enjoyment is the restraint, the humility when facing code that, despite not being squeaky clean, has racked up millions or billions of hours getting shit done. The code knows itself better than you do.
It was completely impossible to work with. Each week the build failed for new random reasons. I hardly dared touch the thing.
This "pattern" is really a failure from multiple parties:
* Managing software engineers is an art, and you really need to understand what is happening to succeed. Only prioritizing short-term goals just ensures you're going to fail in the long-term. Make sure you understand technical debt. The speed of work in bad code-bases versus good code-bases can be orders of magnitude in difference.
* Software engineers really need to use branches properly. Work that is halfway done should not be in the main branch. Consistency and simplicity is king here. Maintaining an old and new version of software for a while can be a pain, but it's much better than maintaining a halfway converted application. Pressure from management is no reason to release stuff halfway done. And if you need to demo, release a specific branch.
Nowadays I don't even ask to do necessary maintenance. It's just part of the job. Always stick to the boyscout rule (leave things in a better state then you found it). Make your code-bases cleaner incrementally, and eventually you'll be in a much better state.
In case of considering a refactor always make sure you can finish it completely.