Friday, August 23, 2013

Why documentation doesn't matter?

Well, it's not really true, it does matter - just not post mortem. It does tell the developer what to do - sometimes even how to do it. It tells the tester how to test it. After the release it's no longer valid nor accurate for anyone to use. Wanna know why?

A simple case


Imagine for a second there's a new position you just stepped into. It's this glorious application that everyone keeps talking about on the 'net. You took a position in one of the teams because you were certain that this can't be wrong - people have been doing that for years so good established processes and a proper technical documentation will be accompanied by a proper introduction training - something to take the edge off from new hires.

Introductory shock


I mean, woooow!!! You just came to the office, suddenly you realize nobody knows who you are, nobody seems to care. People seem to be rushing for no apparent reason through the floors - it's nothing like the place you've envisioned. But that's ok, right? You came here to do the job so let's get that notebook and let's get this show on the road!

Still positive, still passionate, still a foreigner - but you feel this is your chance! In this company, in this corporation there are endless possibilities! Here you will shine!

The second disaster


Ok, so you finally know where you sit, you've got your shiny new notebook on your desk trying to figure out what you've been given, trying to get your familiar tools installed so that you can finally kick start that 'being a developer at ' dream come true.

First of all you don't get to install whatever you want on company's property. No no.. There are rules in place preventing you to utilize whatever power Today's software market has to offer (commercial or OpenSource) so you're kinda stuck with what your new employer has carefully selected for you. You keep telling yourself that it's just a matter of time, that chemistry doesn't happen over night and that you'll get used to it. Why wouldn't you?

Anyways,... There comes the big moment: you're getting the sources! Obviously it's all going to be professional, high quality, top-to-bottom properly designed and brilliantly described in a few pages of perfect documentation. Well.. Our heroes rarely live up to our expectations and my friend this ain't no different. Suddenly it looks like some soft-skill course is more important than getting things done (the famous 'complete this course by today midnight or you'll be terminated' email floating around). Product training is something nobody heard within this walls since the company grew from 7 enthusiast to 1300 employees most of which have better things to do than to sit here, with you and explain obvious things - that seems like a giant waste of time, right?

So you're a professional, right?


And so you've got the code, you've got all the tools you shall need, you have access to the password-protected Maven repository and by all means - let's get to hacking! Obviously we need to start that thing first on that shiny new piece of equipment to compensate the lack of documentation with a debugger session. But wait! What's that error during compilation? Does that look like a broken test? NO!!! It's the code in one of the core modules that a colleague from abroad committed a few moments ago - just forgot to add that new class to version control before and it just so happened it landed this way on your machine. No worries! This is a good version control system so people's email addresses are there to chase that person and to give 'em hell! And so you do:

Dear John,

I've tried compiling our solution a moment ago but it seems like the code you committed Today lacks one of the new classes. Can you please check what's missing? Thanks!

Best regards,
Francisco

One should thing that such an error like "code does not compile" would be spotted by some continuous integration environment where it's constantly tested to meed the high quality standards everyone talked about on the interview. It just so happens that the server CI is on went down 3 weeks ago and nobody noticed. Since everyone sat so far in the same room with nice flowers and A/C if John would commit the code with errors Sally would come over for a coffee and tell him to fix it. This time John is some 6000 miles away on another continent and just called it a day.

No worries - I'm a professional!


And so I'm capable of at least learning the inner workings of the system by going through that clear-cut set of unit and integration tests the project is obviously equipped with. So where are they?

The real life


As with any corporation there are rules: you don't moan, you be creative, think outside of the box, be proactive - and all that politely and politically correct. Following this path 2 weeks later you've got the application running, the database it talks to is across several VPN connections so it's ridiculously slow, most of the external systems don't respond since their security just isn't setup for your location (you being the new developer in the team abroad) and quite frankly you start to miss on the boss that told you you can go to hell because he's not going to be giving you anything you didn't earn with blood and sweat and tears.

So why doesn't documentation matter?


Plain and simple: if you think you have any form of documentation other than the application code itself you're mistaken. Anything talking about the code, telling you how things are is bullshit and does not mean a thing. Wanna know why? Because your compiler doesn't read wiki, it doesn't have access to your email account nor does he care at all about Word documents and Excel spreadsheets. All it's interested in is the funky looking wall of text in source files - that's the only specification, the only documentation, the only rule book that will tell you everything.

So for the love of God: KEEP IT CLEAN! You're gonna need it 'cause you're gonna read it over and over and over and over again. If your co-workers (co-located and those miles, miles away) don't understand the need for keeping things clean tell them it's important to you, that you don't want to work in manure.

And if they will not listen - to hell with them! Tell the world how things are so that the next person drown by the lucrative perspective of working in young and highly motivated team will stay away. Let other learn from your experience.

Post scriptum


If any of you felt this matches any of your previous experience I rush to say it's fiction (well at least some of it). The situation as a whole didn't happen at all (would have been a disaster and a case for a shrink afterwards :] ). It's just to underline the importance of clean code and the fact that the code is the ultimate documentation out there. Don't undermine it.

Thursday, June 27, 2013

It's been a while...

.. but I have not forgotten :) There was just not much going on in my life. A nice and quiet 6 months.

Recently I've been working on some health issues but nothing really serious. My doctor asked me to collect some statistics for heart parameters (pressure, pulse) for review. Since I hate dead-tree versions of pretty much everything I decided that it's the best time to renew my friendship with Ruby and Sinatra.


The challenge

The challenge for me was to write the app in about an hour, with possible extensions at a later time, but to start collecting evidence as soon as possible. Although I'm a huge Grails fan (like you didn't know that) I think it is just too damn heavy for simple data collection applications like the one I have had in mind - thus the obvious dilemma between PHP and Ruby/Sinatra. I really like the embedded nature of PHP but to write anything in a sane way one needs to employ frameworks like CakePHP and the like. I hate that. I wanted to have as minimalistic as possible, with everything just working in a matter of minutes.


My sweet Ruby, Dear Sinatra,

You all know what Sinatra in the Ruby space is, right? If you don't - just go to http://www.sinatrarb.com and find out. Here's what I did with it:

1. All in one construct with everything in one place (configuration, controller, views, css, javascript)
2. All of it takes 210 lines of code (63 Ruby, 143 Erubis and a few while lines for convinience)
3. Deployed to Heroku in a matter of minutes
4. Using MySQL backend because it was just convenient.

Heroku provided the infrastructure for free (the one web worker that's always for free), a free database and Git repository. With all that in place I was ready with the first usable version in about 30 minutes (that's how quick Ruby and Sinatra and Heroku are).


Iterate iterate iterate

As with everything in software development there are going to be bugs, there are going to be new requirements and there are going to be "things that could be done better". One of them was for me to be able to input new measurements using my phone's web browser (the simplest thing that could possibly work). And it worked right out of the box but the default font size is just so small on my S3 that I've had to go through a number of zoom-ins to make out what's in there. Every navigation to another page returned me to that ugly small fonts. Changing the font size to like 40 did the trick :)

Then there was the matter of inputting numbers into the edit boxes. See, the default keyboard is an alpha-numeric-on-request type of keyboard which means that to enter numbers you have to either long-tap on the screen every number you'd like to enter or to switch to the numeric-special-characters-page on every input box which was just plain ugly. Changing the input types to "number" did the trick. Fortunately I'm not using Firefox on my Mobile where this type of inputs are just plain text inputs (as per some sophisticated page that knows all about browser compatibility).

And there was light! I have had enough measurements to actually display them on a chart. I wanted it to be an interactive graph, obviously, so my first choice was Google Charts. Even though beautiful and easy to use almost out of the box I felt kind of cheated because it used Flash underneath the skin. That obviously didn't work on S3 so I needed some alternative. Dygraph to the rescure (with GViz interface) and in a matter of 10 minutes (including research) I've had my charts up for display.


A small snag

As it turns out MySQL by default doesn't understand time the way it's supposed to. It just knows that 13:21:43 is almost half past one but with no particular interest for time zone. An obvious way to overcome this issue was to set all times to UTC and convert them when interacting with the user. Piece of cake. I'd like to point out that the author of mysql2 gem could finally extend the thing to allow something else than 'utc' or 'local' for the automated conversion and life whould be a lot simpler.


Closure

I always believe that software should be written according to high standards, with proper code coverage, proper planning, agile mindset and clean code in the end. Even though I tend to not do TDD in the case of such simple project such as this I still think it makes sense in other cases. I know I shouldn't talk like this since I'm the "Mr TDD" among friends but guys let's face it: throw-away software happens all the time and there's no reason to follow the routine blindly even in the case of spikes. Production code you write for someone else - TDD all the way; spikes no.

I'll probably use the app for another week or two, maybe even for a couple of months, who knows. I just hope it'll give my doctor enough information to get me back on track.

Wednesday, December 26, 2012

Did you noticed Spring Loaded is here?

Well... I didn't! Not for almost a whole month! And it's the best damn thing ever!

Here's how you use it:
MAVEN_OPTS="-javaagent:/path/to/springloaded.jar -noverify" mvn tomcat:run
Next you open Eclipse, do changes, reload pages - all changes occur immediately! Sure you can't add new Spring artifacts (which is odd), change class hierarchy (no surprise there) but you can add/remove methods which is more that what you had before.

Well - it isn't JRebel - but it is good enough!

Have fun!

Monday, December 10, 2012

Named inner classes in methods

Do you know the feeling when you write something that should totally be wrong and it turns out perfectly ok? Well that's what I just experienced: A "WTF?! This is really cool" moment. What gives?

I've been entertaining myself with a little bit of Spring Data exercise. Trying to understand how much will I gain from using JdbcTemplate I dug a little into the sources of that class. At one point I saw that there's a named class (not an anonymous one) declared inside a method. WTF?

I know if I say it like that it is kind of lame of me not to know this. But this is such a nice feature I can't really understand why it's being used so rarely...
public String getName(String user) {
    JdbcTemplate template = new JdbcTemplate(this.datasource);

    class NameExtractor implements ResultSetExtractor {
        @Override
        public String extractData(ResultSet rs) 
            throws SQLException, DataAccessException {
            return rs.getString("firstName") + " " + rs.getString("lastName");
        }
    }

    return template.query("SELECT * FROM users WHERE id=1", new NameExtractor());
}
I know there's like a ton of different ways of writing that code but I have chosen this simple example to show you (and me in a couple of weeks maybe) that inner classes don't need to be defined on class levels.

Have fun!

Thursday, November 22, 2012

Who cares?!

Seriously, who cares? Who cares how HashMap or Hashtable is implemented? Or maybe an ArrayList, ha? How about DynaBlasterRollerCoster? Do you care how it's doing what it's doing?

I just got off a phone interview with some guys in the UK but the same thing was happening in other places. Do you really need to know this? And if so is this ever going to impact the way you design a distributed, highly scalable system if all you know is how to implement a HashMap on your own?

Seriously, we're past that point where we need to manufacture our own specialized collections (even though the Java Collection API sucks big time). Get over it! Maybe when I'll switch back to Microchip MCUs I'll look back to find out how to implement a dictionary then. Oh wait! It's implemented in SDCC already! And I bet there's a pure asm library doing this on Z80 as well.

And if there ain't one laying around there's this thing called Google, with this little box and a "Search" button (hell, these days you don't even have to press this key anymore) that will tell you what you're after

Edit 25.11, 05:17, on the airport: I wonder if the next question (since they asked me if I feel like a polyglot programmer) would be So how's implemented a Hash in Ruby and how does it compare to the inner workings of Dictionary in .NET?. Why not, right?

I just needed to get this out of my system...

Wednesday, November 21, 2012

Simple and effective: Spring and customizable configuration

The problem

The problem is to have the configuration customization possible after deployment. There are settings your hosting department for whatever reason will not let you know (like database password for instance). This fits really nicely to the ways Spring handles configuration.

The solution

The solution in Spring 3.1.x is to use the <context:property-placeholder> tag configured as follows:
    <context:property-placeholder 
     system-properties-mode="OVERRIDE"
     ignore-resource-not-found="true"
     location="
      classpath:defaults.properties,
      file:${config.location:/etc/example.properties}" />

The explanation

First of all there have to be sensible defaults the application can work with. I personally favor them to be good for development so other developers can just get the application, execute mvn tomcat7:run and have it running in minutes rather than to fiddle with all the moving parts of configuration.
Now deployment and the hosting team is a totally different beast all together. They will always want to have things configured their way. <joke>I don't know why :)</joke>

So here we have it - on the classpath there are the defaults in defaults.properties. Now the second part is interesting. First of all it makes an assumption that hosting will follow the best practices and store configuration where it belongs, which in almost all Linux distros is the /etc/ folder. Here's the trick though: some admins will cut your fingers an inch shorter if you force them to put anything anywhere. Especially for that occasion the second option is there to save the day. It allows you to specify a JVM parameter -Dconfig.location=... for Spring to look for configuration options in a completely different place. Neat, ain't it? Finally the system-properties-mode="OVERRIDE" allows for in-place overrides using JVM system variables (the ones specified with -Dvariable=value)

I hope it'll save someone some precious time. I know it'll save me from re-inventing this solution time and time again.

Sunday, October 28, 2012

Revisions

Back in the days when I switched over from Delphi (the day that Delphi died) I felt the overwhelming amount of frameworks for pretty much everything was giving me a headache. And I think everyone out there will agree with me. Hibernate, Spring MVC, Spring Integration, Spring Data, Spring Mobile, Spring WS, Spring Batch, Hazelcast, EhCache, C3P0, a whole range of Apache Commons - just to name a few prominent ones. Oh boy can this be a pain in the royal butt to learn all of them. An then there's the ever changing world we live in where new versions of open source frameworks come out like crazy. Pretty much a 100 times a year one can get something new to learn, try out, fiddle with, get angry with or embrace.

When I first started using Spring all it was for me was the dependency injection framework with stupid XML config and training that takes forever, costs a fortune and makes no sense. Remember, I came from a world where documentation was pristine (for both Turbo Pascal and Delphi), examples came in spades and the classes started with a T and all interfaces with I. All the separation of concern, testability and other ilities were not so needed in the Delphi world. Also inheritance was in the zone (now we all know it's bad and should be avoided). With Java everything was different and I felt lost.

I turned my attention to something I though would be a little bit more familiar - the .NET framework and C# language. Oh boy was I happy to see the notion of properties built into the language (so missed in Java). I though I've had the world by the balls with this one: modern platform, fantastic language (created by the same guy who created Pascal and Delphi) so I was right at home.

At that time job opportunities for C# web application developers were scarce and so I was sort of forced to stay with Java. At first I hated it with a passion (http://www.ihatejsf.com). In the mean time along came Guice and showed me why dependency injection makes sense and how to do it right. After some time I learned to live with it mostly because I discovered that there's more to it that meets the eye. Basically I learned about Groovy and Grails. That was the sweet spot for me: elegant and dynamic language, similar to Java but oh so much more powerful and a framework that finally doesn't suck like JSF did. That was the best time ever!

With time wisdom came and I started looking around what else can be done with this thing. That was the time when JavaEE 6 came out with Glassfish 3 (man you really have got to love something that's called Glassfish, don't you?). Finally all the stupid things like web.xml went away, web services creation started to be a breeze and all was cool again. Then I leared about EJB3 and all that comes with it. Can't say I was happy with what I saw after living on Grails, Guice and Spring for a while.

Now it's years later. I'd describe myself as TDD junkie with a healthy dose of polyglot programming skills. I've learned a great deal about the so called Spring programming model. I've learned a lot about Spring and the modules it brings to the fold. I learned not to hate XML. I've learned Ruby and got acquainted with Sinatra. Every day is a new challenge and every day I learn more. The more I learn the less I write and the more I integrate.

During all that time there has been only one constant: Internet. All I know, all I ever learned beyond the 6502 assembler, 68k assembler, Pascal, Turbo Vision, Delphi and VCL (which I learned ages ago from dead-tree books) came from the Internet. This is the best, most demanding and absolutely the most rewarding university in the world. All this because of open source projects and awesome communities that make the world go around these days.

It's a beautiful time to be a programmer!