Everyone can write bad code. But writing code that looks legitimate but actually terrible requires a lot of skills. If you want to write terrible code and still get an approval for your code review, here are some tips.
Add additional functionality you might need in the future today
Add extra classes and methods you don’t need but makes sense within the context of your code/feature. For example if you need functionality to read a file with a specific format, add functionality to create and update it as well, even though you don’t need them at all. Most likely the additional functionality you added today, won’t be used by anybody ever. However you can justify it by saying ‘This code makes the module complete, and reusable’. You will most likely get your code approved and it will be a burden on your team forever to maintain it. Bonus points if you really don’t understand the future direction of the project.
Over-engineer
Over-engineering is mostly used to define systems that are designed to be more complicated than they are supposed to be. However not every complex system is over-engineered. Making your code/module/project adaptable to change is a good design principle and could save your team a lot of time and trouble in the future. But we don’t want them to save time, we want them to waste time. So In order to make sure you are doing the real terrible type of over-engineering, use these principals as your guide:
make classes/modules extensible that won’t ever need to be extended,
make classes/modules way more generic than it needs to be.
Engineers like generic/extensible solutions, getting an approval won’t be an issue, just make sure that your terrible code is not too obvious.
Low Cohesion
Cohesion means a component (functions/modules/classes/methods ..etc.) is narrow, focused and does one thing. It is a measure of how strongly related each piece of functionality expressed by the source code of a software component is. Cohesion is closely related to Single Responsibility Principle (SRP). A good way to achieve low cohesion is to violate SRP. Writing a fat method, instead of breaking it down into multiple cohesive smaller methods is a good example of how to reduce cohesion. When your team needs to update your fat method, they need to understand the whole logic, Therefore, it slows them down, and they are more likely to introduce bugs. That is exactly what we want as terrible coders. Another good example of low cohesion is to have …Manager …Utils classes that carries multiple unrelated functionalities. During code reviews most engineers looks at the correctness of the added code but they fail to look at the big picture. Therefore you can most likely get away with low cohesion during code reviews. Another way of achieving terrible code is to separate the components of a module which are grouped because they all contribute to a single well-defined task. Such as breaking down a well defined function into a lot of smaller functions which on their own doesn’t map to any logical unit of work.
High Coupling
Premature Optimization is your friend
Writing performance optimal code is not necessarily a bad thing. There are obvious optimizations like not doing string concatenation inside a tight loop ..etc. However, It could be a great way to justify terrible code. When you claim a particular piece of code is performance critical, you can get away with writing complex and unnecessary code. Especially if it is done without really understanding the performance bottlenecks of your project. Doing bit manipulation instead of easy to understand logical statements, implementing a complex DP algorithm instead of straightforward solutions can all be justified by claiming that the particular functionality is performance critical. You can go above and beyond and create services and libraries that solves non existent performance problems. But doing so requires a rare skill set only great terrible coders can pull off.
Build Your Own Solutions Instead of Using Common libraries
When you run into a general problem, you might think, there should be a library that solves it. For example, if you need a retry mechanism for failed http client calls, using a library like fail-safe or resilience4j-retry makes sense and could save you and your team a lot of time. Besides, these common solutions are battle tested and will have significantly less bugs than your own implementation. However this approach will be a betrayal to your commitment to terrible code. You need to build your own solution. If you need an in-memory cache, build your own version. If you need a client side retry library, ORM, Collections …etc. build your own. First of all, if you build your own version, you will get more credit. If you can make another team adapt your solution, you can claim that you are this super engineer who is contributing across teams and deserves a promotion. Secondly, your implementation will not only be a maintenance burden for your team, but also be source of many operational issues due to bugs in the code. However, getting your code approved could be a challenge. In order to get an approval, claim that common library solution is too generic and requires too much work to adapt to your particular case and having a specific implementation is much easier. I believe this will be a convincing argument for many cases.
Write unit tests for code coverage
Write a lot of unit tests to reach maximum code coverage, The most important point here is to cover maximum number of lines without focusing on covering all behaviors. Don’t follow the single responsibility principle, your unit tests should check multiple issues. Make sure when a unit test fails, it is not obvious what is causing the issue.
Error check your parameters everywhere
Error checking parameters at the beginning of public methods and then avoiding error checking the same parameters when passed to private and package private methods seems like a reasonable approach. However you should error check parameters at every method regardless of its access level. You can intentionally make your package structure complicated, this forces you to create public methods instead of package private ones and then you can get away with error checking for the same parameters over and over again.
Rewrite existing code just because it doesn’t fit your style
After reading this, you are probably thinking that writing terrible code seems more work then writing good code and not worth the effort. However, the sense of superiority you will feel once you see how much your teammates are struggling to maintain your code is totally worth the hard work you put in. You can jump in from time to time to save the day and go to management to brag about how smart you are as well. Other engineers won’t want to work on your code base, this way you will be known as the solo expert of a particular area, and it comes with extra job security. But most importantly it is fun, even more fun than destroying public property, or trashing public parks.
Comments