Ask HN: Working with a monolithic codebase
The most common comment in my code reviews: "You're reinventing the wheel - we already wrote something similar. Take a look at [X], extend it a bit to fit this use case, and toss what you have." Since X is always undocumented this involves sleuthing + picking senior dev's brains. The process slowly repeats until my feature eventually converges onto a configuration of existing components, with as little new code as possible.
That's great for the business but not much fun for me. It means that to do a task that could be completed from scratch in X hours, I must spend X^(size of our codebase) hours grappling with other people's ideas, solutions, and mistakes. It means my thoughts must be bent to fit some pre-existing shape, which eliminates the need for my thoughts, and suggests they should be permanently replaced with those of my predecessors.
Is this actually the sign of a good codebase? Should I be deriving pleasure from this? Is this what software development is?
50 comments
[ 3.1 ms ] story [ 87.6 ms ] threadNo.
Yes, you're lucky the current code is flexible enough to be extended, if there is good unit test coverage that's one better. For me, it is crucial to study outside of work and have side projects
But remember to follow the 6th step of http://www.joelonsoftware.com/articles/fog0000000332.html
Went from PHP "monolith" with couple of services to Node.js using microservices. Jesus what a mess, our previous stack was 10x cleaner. Not to mention company now spends thousands of dollars every month for all the new/cool AWS stuff.
But hey, they pay me so I'm not complaining. :)
You are a junior dev. They hired you to invest in you and grow you. They pay you in dollars, not pleasure. Your day 1 contributions are likely meaningless in the grand scheme. What they want to see is that you can read and understand existing code and that you are a team player. Any code monkey can go in and write functions for validation or logging, but if I am paying you to understand HOW you should do it, taking advantage of the (hundreds of) thousands of dollars of my investment, then I would be pretty frustrated with you if you rolled your own. I would be further frustrated if you disregarded my attempts to point you in the right direction.
You are more likely going to have a positive impact by suggesting changes within the framework they are providing you than creating your own. Learn and understand what the code does and WHY it exists and then you will be able to see what can be improved. Coming in and saying that everything is wrong and persisting in doing your own thing, at your employers expense, will probably leave you without a job.
To satisfy your need to learn and be creative, work on a side project of your choosing. You shouldn't expect your day job to give you 100% of your career development. A large part of it is on you and whether you are passionate enough to invest in your own development on your own time.
Before you do X, you should always ask someone if they are aware whether or not X already exists in the code base.
This is true outside of the work setting. If you are making websites for fun in your spare time, you are likely to spend time learning a framework such as node or django. If you are making games you are going to learn some tool like Unity or an engine like unreal or source.
Imagine if you had a project where you defined 20 different functions for requesting the html of a webpage, each doing something slightly different. Think about what kind of a maintenance nightmare that would be. You are suddenly required to implement a proxy on all requests, but doing so breaks half of your functions. You can't just scrap them, because each has a nuanced use (since you were too lazy to update your existing function(s) to fit your needs).
You would never do that in your own project, but that's exactly what you're doing with this company's code base.
"It means my thoughts must be bent to fit some pre-existing shape, which eliminates the need for my thoughts, and suggests they should be permanently replaced with those of my predecessors."
No, it means your thoughts must bend the pre-existing shape, which eliminates the need to create the shape yourself, since that was already handled by your predecessors.
Your point of view is a lie. Do you program on an OS you wrote yourself from assembly code, in your own programming language, on your own custom built hardware, with no libraries or tooling?
Musicians do not reinvent thousands of years of musical discovery, yet they manage to find immense pleasure and creativity in their work.
If you have done very little programming outside of college, you should see other people's code as a treasure trove of information. Just as musicians find inspiration in other people's songs. My last tip is to revert to pencil and paper when you are having difficulty understanding someone else's code.
You: I have the task of X and I'm thinking of doing Y to do it
Other dev: Oh, we have W for that, it might help
You: Cool, I'll check W out
1. Let go of your frustration for now, a company is an incredibly complex machine and you need to invest more than 6 months learning how it works before people take your criticism seriously (I know this can be hard). Also, some people like to 'grill' the newbie as a right of passage, you may be experiencing this.
2. Acknowledge that code-reuse is awesome. It's great that there's reusable functionality, part of your job is memorizing the handy tools at a company and if they're good enough, rebuilding those tools later at your next job.
3. It sounds like you're frustrated that you don't find out about existing libraries/functions/classes/tools until your code review. That seems like a reasonable concern. Maybe next time you have a project come up with a rough plan and ask a senior developer for architecture-level feedback before you start coding.
4. Don't feel bad. You don't need to be a hero or change the world. If you mimic the senior engineers and try to fit in that'll go further than studying engineering theory, writing perfect code, or documenting the codebase. Once you're accepted into the group they'll be much more receptive to your ideas on how fix things.
I couldn't agree with this point more. When I first started, my team lead gave me a rough plan to add new features so that I wouldn't go in blind. Until I could stand without the support of others, I drafted a quick plan of action to get the task accomplish. This let my team lead know how I was planning on accomplishing the task while allowing them to point out existing code that would take care something I would have written.
It seems like unnecessary overhead, but the 5 minute conversation up front saves more time down the road.
If you want to write code from scratch and just blaze forward all the time join a startup. Less guaranteed job security but more fun for sure.
Think about it: do you want to have 5 separately-implemented code paths that all accomplish essentially the same thing, or one generic codepath that handles all the reasonable cases?
Right now you're the new dev. Yes, you are going to have a lot to learn about code that's already in place. Totally greenfield development is fairly rare. You don't have to learn the whole codebase (almost no-one does in large projects), but it would be wise to solicit input about where you should start looking before writing brand new code for a new feature.
> That's great for the business but not much fun for me.
That's why we call it "work" and not "play." :)
Even with the best documentation, there aren't very many functional projects (either companies or open-source projects) where the expected way of contributing is not to talk to anyone until you open a PR.
Adding less code as possible is good. It means that things are well structured. The speed that you want seems like you want to hack your way through and just increase maintenance time. That is what software development is.
If you feel some piece of code should be refactored and re-written / extracted, then that is another completely different case. Check what is the value and impact on doing it, both short and long term, and expose your rational to your team.
For me the biggest signs of a good codebase is having a clean build system and proper testing.
Next time when they point you to it.. Tell them: where was this documented. How can i prevent reinventing the wheel later?
Also ensure that the code that they wrote, is located in a logic location. Often it is not, and thats why its difficult to write in that codebase.
So it can mean two things: bad structured code, bad documentation, or you lack knowledge in the codebase.
Your job as a software developer is, roughly, to deliver maximum business value with minimum cost, and that includes writing minimum code to accomplish the task. That is what the senior developers are talking about when they're saying you've written too much code.
It does sound to me like they've got a well designed system if you can add new features simply by making a small modification and some configuration to the existing code. As long as it's also well tested and well documented (that may be lacking...), you've got the ideal codebase: one in which you can add large amounts of business value with only incremental changes.
You mention that this is "great for the business but not much fun for me". I think this is a sign of inexperience. Part of what makes something fun is how difficult it is. If something is too easy it's boring; if something is too hard it's frustrating. In the middle we find things fun. The reason writing lots of greenfield code is fun for you is because it's easy. Understanding and modifying existing code is harder, and that's currently too hard so you find it frustrating. You need to push past this stage to improve as a developer. As you get better, it will become easier to work in existing code and will stop being so frustrating.
[NB To be fair I had the same sense of disappointment myself years before when I was quite proud of a package to do CLOS object persistence and a more experienced chap told me there already was something to do that...]
Edit: Nice to have a comment downvoted, even though what I said is true.
In programming terms, it's very tempting to say, "this room is untidy, I'm going to build a new one." It's certainly more fun than tidying your room. But this is how you get sprawl and bloat.
I cannot upvote this enough.
Both of those are along the lines of "I need code to do this thing, but I don't want to be the (sole) maintainer."
You could write your own language, IDE, OS, build system, source control, networking library, logging library, shopping cart, payment processor, etc.
I recently made the decision to have a third party build a component as opposed to doing it in house. The cost and time to build a component in house vs using a third party ended up being a wash, but the third party offered to maintain and support a solution so this presented less risk to us. This major risk we incurred was in vendor lock-in.
These types of trade offs happen all the time. Think about virtually any SAAS offering that could otherwise be built in house.
But buying on margin increases your volatility and risk exposure, so you shouldn't take on more than you need to. Assuming zero transaction costs, it's always a good idea to substitute less code for the same benefit.
* Don't worry if you have to replace parts of your code. That's just part of the process, especially if the existing code is undocumented and everyone knows that. The code reviews are working.
* However, if at all possible, get feedback early in order to skip straight to implementing the feature with existing code. You'll finish features faster, get familiar with the codebase sooner, and hopefully move on to more interesting tasks sooner.
* Document existing code as you discover and use it. This is technical debt that your company needs fixed, and you're in a great position to help with that.
In school you get to write a lot of our own code from scratch with our own ideas, and it's fun. Some developers pump out code by the minute, even implementing the same thing over and over again in their own code; it's fun, and there often aren't repercussions for that in school. But code re-use is good practice. I love days when I produce net negative lines of code in an existing codebase, while adding a feature.
Not every company offers the opportunity to implement your own ideas from "scratch". In fact that's somewhat rare. If this is the only coding you enjoy, you may need a new company, but you may just need to wait a bit longer at your current company. A good advisor/boss will be able to have a conversation with you about expectations (going both ways) for the first and second year. You'll want to find out if your company can eventually provide the kind of projects you want, especially as you get a better idea of what those are.
Like others have said; instead of writing the functionality from scratch, try to understand the existing code and document it.
> The process slowly repeats until my feature eventually converges onto a configuration of existing components, with as little new code as possible.
In other words: "The process slowly repeats until you know the codebase". Also, less code brings less bugs.
> I must spend X^(size of our codebase) hours grappling with other people's ideas, solutions, and mistakes.
Learning to understanding how other people think is crucial, and its better to learn from the mistakes of others than your own.
> Should I be deriving pleasure from this?
Hopefully, with time. But you are more supposed to derive a salary from it.
If you're writing code to get the reward of a salary, you're not going to enjoy it nearly as much as if you do it for its own sake! Rather, you'll enjoy less the more you're doing it due to extrinsic motivation.
I'm not sure of the solution, but I suspect you need to cast any of these challenges, whether they are really coding challenges, or rather team communication challenges, as something you're excited (rather than anxious) to overcome and improve your skills at doing. Forget (in those moments) that you're doing it for a salary, but decide that, in order to later improve strictly coding skills, you are wise to currently work on improving your communication skills, your ability to discovering the capabilities of existing code and frameworks, and perhaps your ability to document anything you learn for future reference (for yourself and others.)
> Monolithic java codebase
> "we already wrote something similar"
Sometimes it's not even them who wrote something. I was working on a Java codebase where decimal numbers always had the separator be a period (e.g. 1.2).
In (most of) continental Europe, the character they use to separate the numbers in a decimal is a comma (e.g. 1,2). So I coded something up to do a location-specific separator.
Woops! Actually java.text.DecimalFormatSymbols().getDecimalSeparator() will do that, and has been a Java core API since Java 1.1.
Step 2 is learning how to adopt an engineering mindset. Spend time in analysis and ask your coworkers for feedback on your approach. Critical thought should not change from person to person. If the engineer before you applied critical thought to her/his code, then s/he encountered the same problems and made the same decisions you would, if you also applied critical thought. So spending time reading code and understanding it is a huge time saver.
The critique of re-inventing the wheel isn't "hey you just made a wheel... we already have one of those". It's "hey you spent all your time thinking about wheels and working out all the details... we've already done that thinking and here it is written down. Save yourself some time and catch up to us. We did the heavy lifting for you."
If you can write code but you can't read, than I'm sorry to say that you are not a good developer.