lauantai 16. heinäkuuta 2011

Why Clean Code Matters and How to Write Some

When I started in a business, as a junior programmer, I was full of enthusiasm and arrogance. I was the artist and every single line of working code was piece of art. No matter how I act or what I said or what I did, I was irreplaceable. ”I know my code, don't touch it”. ”Yes, it's complicated. But it's complicated thing, you know.” Main reason for that kind of behavior: I was young and stupid. And I didn't know much. I knew a little bit about programming, but nothing about how to do good software and how to work in a team. Why I had some success was that I worked hard and I like to program, maybe too much. Luckily I worked in a project where I was (almost) only person who worked with my “perfect” code. That code wasn't clean or good. It worked somehow, but it would have been crime if someone else had taken care of it.

Next company, one of the projects: 2000 lines of JavaScript code in single JSP-page. Have to say that UI was cool, but I didn't understand how it worked or how it was constructed. And I had to maintain it and add couple of new features. I hated that project, I hated the guy who did those pages (sadly there was many of them). Maybe saddest thing was that “piece of art” worked and it was developed by one of the seniors. So it was mainly “my problem” that I couldn't fix it in reasonable time. Afterward I heard that affected to my reputation, I was slow and whined. No one talked about the guy who wrote the code, because he was a senior and software worked (but was impossible to maintain). In business wise those 2000 lines of non-understandable code were very sad too: It took almost 2 months to add couple of new features to that application. In that time it's possible to develop whole application with right tools.

Next project, couple of years after: 20 programmers, couple of architects, business analysts, testers, project managers. And couple of “consultants” (in this case, they were junior programmers). 100 entities, 50 ui screens, 50 reports, hundreds of thousands of lines code. Complicated code. And no one cared about code quality from the start. There was reviews and stuff but that was a joke. They reviewed plans, no code. Documentation was important, even code comments. But no one really cared about code. That led situation where no one actually knew what was implemented where, how it was implemented and was it really implemented. Result: our bug tracking system had over 1000 issues and bugs when we started to really clean it. And I'm pretty sure that there still is some, after couple of years. We spent couple of full 2 month iterations to fix them (yes, we had too long iterations or sprints too). That was cheap, eh? I don't say that dirtiness of code was ONLY reason for corruption of code. But I say that was one of the biggest issues. Or what do you say about service methods which have about 1000 lines of codes, multiple exit points, lots of side effects and chained method calls? And no unit tests. Who can really understand that? Not me.

What is common in those three projects? Programmers that doesn't care or understand to care? Programmers that can't code? Artist who thinks that they are alone in software island, where they can work with they code alone, isolated? Lots of time to spend for maintaining that shit, not for fun like developing cool new apps or features? I say that reason is us, coders who just don't sometimes care or take responsibility of their work. Only we are the ones who have skills to care and fix those problems and we should. Of course schedules could be too tight or plans or requirements have problems but also in those cases we should tell our opinion and try to fix them. But main reason for bad projects in my opinion is bad code, code that is not “clean”. If we don't understand the code we write or maintain, who can? We are still the ones who have to do all that shit. And I'm pretty sure that most of us wanna do new stuff, not spend whole time in work to maintain that shitty code.


So how to get there, to the Land of The Clean Code

1. Code should communicate. I don't mean that you should write thousands of lines code comments or document for every single line in your code. I said that you should use names, which tell exactly what your methods do or attribute (or variables mean). If its impossible to give reasonable name, then there is problem in your method, attribute or variable. You don't understand what it does or it does too much or you just don't actually need it. If you have to use comments, think hard if you can refactor your code so someone who reads it understands it's meaning without reading you comment. If you really have to use comments, be sure that if you change code you also need to change comments too. Obsolete comments are BAD. For some reason many programmers believe comments more than the code.

My favorite tweet about this issue is from @petercordell: "@unclebobmartin Love this theme. My mantra: Treat running code as a side effect of describing your algorithm to a fellow developer."

Coding is caring about you fellow developers and co-workers who have to maintain your (hopefully) good and readable code (love, peace and understanding :). “No man is an island” (http://www.phrases.org.uk/meanings/no-man-is-an-island.html) and we need others when we are doing complicated things.

2. Refactor all the time. Code is never ready. If functions (methods) are too big, extract new ones from them. If names are meaningless, change them. If model doesn't correspond your business model, recreate it. Refactoring isn't hard anymore, because of good tooling. IntelliJ IDEA and Eclipse have features for it. And even if you do it by hand, you can compile and run your code fast so you can test if it still works. Best situation (and recommended) is if you have unit (or integration) tests for the parts you are refactoring. And if you don't you should write ones for those parts you gonna refactor. Good unit tests are backbone for all software development. When you have tests, refactoring and making other changes aren't so scary anymore. You know that your code works when your bar is green.

And remember: "Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior." (http://www.refactoring.com/)

3. TEST, TEST, TEST. And do some testing too. Coding is more testing than coding. In my opinion, if you don't show that your code exist using running tests, it doesn't exist. It is in your laptop (or server) somewhere, but doesn't really exist if you can't show it does what it's written for.

When you start to do some coding, first think how to test it. The easier it is run those tests, the more often you will do that. If you are not used to write unit tests for your ui controllers, record them when you click through you newly written ui. Then you don't have to click again when you change your code, just run your recorded test. Or if you are writing complicated algorithm for something, write test (and more tests along when you are coding of course) for it first and it's ready when bar goes green. And if there is a bug (we pros don't do bugs, but still :) ) in that code, write test for that bugged input (or situation) and refactor and fix your code until all the old tests and that new goes green. Or if you create new entity classes for you ORM-layer, write integration tests using in-memory database for making sure that all associations and other persistence stuff still works.

It's not hard anymore, there are lots of good material in internet and lots of books written about it. Actually, when you start doing merciless (automated) testing and TDD (Test Driven Development), it's fun. And it makes creating of good software so much easier and faster.

4. Work and talk with other people about your code, their code or some other code. Learn about mistakes your co-workers have done. Tell about mistakes YOU have done and what you have done right. You don't have to be hero, who resolves all problem just by himself. It's not honorable. In my opinion, it's just stupid. So ask and give help, please. Hero cult tells about low maturity level of processes and practices. It slows project progress and prevents personal development of the people. You may think that you are always right and your solution is the best. Until you talk to someone else. Also it's just so stupid to spend two days in trying to find solution to problem that someone else have solved before. And it's expensive too.

Good friend of mine said long time ago that developer saves customers money when he asks for help. I think there is big point in his saying.


Continuous learning

In my opinion, you can always do your work better. Of course there are constraints in projects like schedule but we use lots of our time for stupid things that monkey could do like regression testing using user interface clicking it by mouse. Or trying to understand those 1000 line long functions and stupid variable names like “a1” and “a2”. We could (and should) use our time wisely so we had time for real work like discussing with customer about business problems or designing more usable user interfaces. Or just inventing application ideas which make us all rich and famous. Or learning new more effective technologies and methods for making our job more efficient.

But still we fill our days wading in the swamp of smelly code to never really get to the dry land. Is that pure stupidity or are we just prisoners of our bad habits? I don't care about reasons actually. I just wanna have fun in work by creating good software. Writing good and understandable code is the way. And it's not actually THAT hard. It just needs some discipline and will to learn all the time. And some passion to be good.

If you agree the above, here's couple of books you really should check:

Clean Code (http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882)
Clean Coder (http://www.amazon.com/Clean-Coder-Conduct-Professional-  Programmers/dp/0137081073/ref=sr_1_1?s=books&ie=UTF8&qid=1310819884&sr=1-1)
Agile Software Development, Principles, Patterns, and Practices (http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=sr_1_2?s=books&ie=UTF8&qid=1310819924&sr=1-2)
Refactoring: Improving the Design of Existing Code (http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=sr_1_1?s=books&ie=UTF8&qid=1310820005&sr=1-1
Test Driven (http://www.manning.com/koskela/)

Also I higly recommend videos from http://www.cleancoders.com/.They give lots of value for money and are fun to watch.


Little craftsman.