Your code is not your child. It’s not a sculpture or a painting. It’s not a hand crafted table and chair set. It’s not going to be around in 5 years, hell it’s not going to be around in 2 months if it ever sees the light of day at all. Eventually you will move on to another project, someone else is going to work on your code, they will have their own ideas, their own needs. They will use your code in ways you never intended, or wanted. They will change your code, for the better, and for the worse. There is nothing you can or should do about any of this. It’s the circle of life. Don’t get attached.
Like nature, code in a large project with many developers undergoes Darwinian pressures of natural selection. If you write truly great and clean code. If the purpose is obvious. If there are simple, easy to understand examples of it’s use in both production code and tests then your code will grow and get used. Other developers will start to use it as a pattern, they will use your classes in unexpected and surprising ways counter to your original design. Code that is ugly, hard to understand and use, or that does not provide benefit over other code (even new code) will not get used and eventually will be killed off. If you are an “architect” or “tech lead” the most damage you can do to a project is to interfere with natural selection and force other developers to do things a certain way. Particularly when the classes you wrote suck.
Forcing people to use your magical “flexible” framework will only prolong hardships in your app. Despite your best attempts, new mini-frameworks will crop up like weeds as developers either try to get around your bad code or simply don’t understand that it “already does that”. The fact is if your code had been good to begin with people would have happily extended and used it.
So don’t worry when nobody is using the divine classes you spent so much time on. Figure out why, make improvements, compete. Developers are like water and will always follow the path of least resistance. Make your code that path. Make it the yellow freakin’ brick road. Encourage your own bad code to die, kill off others without worrying about upsetting them. It’s for the greater good after all. Most of all don’t fall in love with your code. It’s not long for this world.
To expand on my little rant about Java 7 let me rant about the one feature that almost all other modern languages have that Java lacks and really bugs me.
var
Yes, var, it seems like such a little thing, such a minor feature, but it makes refactoring so much easier. Take this statement:
var foo = someObj.GetFoo();
Note how nowhere in this statement does it explicitly say what foo is. It’s still statically typed because the compiler can infer type from GetFoo’s return. Some people might think that’s a problem but we have modern IDE’s so it’s really no big deal.
The power comes when I want to refactor GetFoo, now as long as whatever it returns has the same signature as the original everything is OK and I never have to touch this file. I might be introducing a interface, or a abstract class or even completely replacing it with some other implementation. It matters not, all that matters is that my change had the smallest impact possible.
In Java 7 they are introducing some generics stuff where you don’t have to state the type twice. So instead of
Map<String,String> foo = new Map<string,string>();
you can do
Map<String,String> foo = new Map<>();
This completely misses the point of type inference. All it does is save me some keystokes but it does little to assist future refactorings. The fact that Sun/Oracle spent time on this rather than proper inference features is mind boggling and almost insulting.
P.S. someone has made a library to attempt this. I can’t speak for how well it works or it’s impact as I have not yet used it. I suspect that for type inference to really work well it needs to be baked into the compiler.
Recently I changed jobs and with it the programming language I get to spend the majority of my time in. I had been doing mostly C# day in day out with occasional forlays into java. Now I’ll be doing Java full time so I wanted to get back into what was hip and happening in the world of java
What I’ve found is a party that all the cool kids left hours ago. I don’t know if it’s the oracle takeover or if it started before that but the whole scene just feels sad and lonely. The recent announcement of the features in Java 7 adds to it.
7 can easily be summed up as the programmers version of Ralph’s present from his aunt in “A Christmas Story”. We wanted lambdas and all we got we got was strings in case statements. Seriously, they should have just snuck the strings-in-cases thing in without pointing it out because everyone is just making fun of the fact that it took until version 7 to get it.
Oh well, I guess the Scala party down the road is where everyone went. I hear they have a keg…and closures.
The resume I snail-mailed into GeoLearning over eleven years ago was replica British WWII propaganda poster. I didn’t have a lot of “official” experience at the time so I thought I would make up for it in style. It worked, The CEO called me the day he got it, we went to lunch, then over to CompUSA and picked out a new G4 Macintosh. I pushed my first product live a few days later. That was Geo; fast paced and personal.
Eleven years is a lifetime in the tech world to be somewhere. I often tell people that in reality Geo was at least three different companies over my tenure. There was the early cowboy hacker startup phase; the professional services “we’ll customize anything for anyone” middle phase; and finally the SASS app agile/TDD rock star halcyon days that ended with our eventual acquisition. It really was the kind of place where it was what you made of it. You could learn a lot, work on interesting projects, improve the product on your own initiative, and interact with some of the best peers in town. That’s not to say it was all wine and roses but overall people with the right attitude and a little patience could go quite far.
The key was, the company was never satisfied with itself. It was constantly experimenting and changing and had great courage to make leaps other companies would never have considered. Sometimes we failed epically, but failure was OK as long as you learned. In the end, that’s one of the best things you can find in a company.
I really owe my career to the people I worked with at Geo. I don’t know where my career would have taken me elsewhere but I’m sure it would not have been as good. So a big thanks to Frank and the executive team for creating a company environment where IT was allowed to be IT; and a huge thank you to all of my fellow developers, you guys are truly rock stars.
As to why I am leaving. Let’s just say that the new company is not GeoLearning.
Several years ago I became the inheritor of a rather large codebase that had been farmed out to an R&D team of contractors. I could go on with a litany of grievances about the delivered product but I’ll leave most of those for other posts. Todays issue is about dead code. When we got the application it was quite bloated with unfinished and forgotten features. Imagine going to look into a bug only to find that there are 3 different modules that do the same thing; only one of which was actually used. There were entire assemblies that did nothing, or very little. Lots of modules were “flexible” but then configured to just work one (very simple) way.
How it got this way could be a good masters thesis on the dangers of waterfall and cramming every possible requirement into a bloated spec at the begining, but regardless of that, the team had a problem.
Extra and unnecessary code made building slow, made performance slow, and made testing slow and very difficult. It was confusing for developers to to have to deal with and it wasted all kinds of time with rabbit holes and marathon sessions in the debugger. Worst of all there were few tests to document the behavior.
Finally after a particularly difficult weekend the team had had enough. We made some time, got out the machete and started to hack away at the dead flesh. The result was a faster, less confusing, less buggy system that performed all of the same duties as the original app. Dev velocity went up as build times and time in the debugger went down. Occasionally there would be second guessing, “What if we need that some day?”, “Well, that way IS more flexible”, but you know what? That’s what version control is for. To this day I have yet to go hunting back in time looking for some of that dead code.
The other result was legend…”The Big Book of Dead Code”. The more and more code I hacked away the angrier I got. I watched as developers I knew from the R&D team disappeared like they had never existed. It was never their fault that they were asked to write something the product never needed to begin with.
We needed to be able to show to management how much waste a gigantic 2 year waterfall project produced. So I took the diffs and wrote a little script (called “Bring Out Yer Dead”) that took the deleted code, removed all of the spaces, tabs and line breaks, formatted everything into a sigle block of raw text and then printed it all out in a 9pt font front and back. As the code was removed the book grew.
It ended up being easily over 500 pages. 500 pages of blood, sweat, yak hair and money. The book became famous, people would come from far and wide to gaze in wonder. I never saw the look on the owners faces when they were shown it, but I was told that it was very sobering. It ended up becoming a symbol of development black holes. Never again would management tolerate non-incremental development and gold plated specs. We would deliver small bits quickly, we would adjust requirements as needed. We would do only what needed to be done. Keep it simple! Yagni! “Bring out Yer Dead!”
Today a friend was expressing concern about C# test loop times. Even going so far as comparing it to gasp C++
He challenged me to ” please see if you can get a smallish project, maybe 1K unit tests (ignore other tests) to build and run in <45s & blog it!!”
Well, lately I’ve been working on setting up a integration test suite for Ninject, so I was familiar with it as not just a small, fast C# library, But one that is quite popular.
So here is the result. For just the build/test of the core project total time from the command line is between 4-5 seconds. 2 of that is running the 223 unit and integration tests.
For a total CI package/build including generating packages for .Net 2.0, 3.5, 4.0, 3.5 compact, and silverlight 2, 3 and 4 which adds up to 669 tests takes around 1:45 - 2 minutes.
So I’d say that shows that .net is at least capable of having fast cycle times. The thing that’s still missing are good autotest tools. IntelliJ and Eclipse smoke VS in terms of testing and refactoring. ReSharper…as good as it is…does nothing for the rest of the bloat in studio.
Now, if only we could get JetBrains to make a ReSharper for MonoDevelop we would be all set.