This blog contains reflections and thoughts on my work as a software engineer

mandag den 5. januar 2009

Definition of SOLID

What's SOLID? I've came across the acronym a few times but never took the time to look it up (I guess a Google search would have taken no longer than for you to read these two sentences...)

Anyway - I came across it again while reading a post submitted to DotNetKicks and found a link to Pablo's topic of the month. Basicly SOLID is an acronym built upon five acronyms (no, it's not April 1st) - and they are:

  • SRP: Single Responsibility Principle
  • OCP: Open/Closed Principle
  • LSP: Liskov Substitution Principle
  • ISP: Interface Segregation Principle
  • DIP: Dependency Inversion Principle

That's what SOLID is. All in all five architectual best-practice design principles which are good to know in order for you to get things "right" in the design of whatever system you're working on. Agreed - I'm really only paying attention to the first one since so I won't preach the importance of all five of them to you.

There are numerous links to a detailed explanation of each of the five acronyms so I won't repeat them here - go check it out for yourself :o)

Regards K.

søndag den 28. december 2008

Buy it - just buy it.

The best thing about Christmas is the days off from work. You get to spend a lot of time with your family and that's great. You also get to see a lot of movies in the TV - which is nice because I like to see a good movie. I don't see a lot of TV basicly because I choose otherwise - my life probably goes on even though I don't know who got voted off the island during the last episode of Survivor / American Idol / Big Brother / (insert any mediocre TV-show here)...

You also get to read a lot so I've finished the book I blogged about three days ago - Michael Feathers Working effectively with legacy code. The short story is: Buy it - I was completely sold on his final appendix where he goes through all the various ways of decoupling dependencies - each example is followed by a codeexample and each example and explanation covers about two to four pages. Extremely nice setup and well thought.

One of his examples is the "Extend and subclass" refactoring. I never thought of that one but it is so obvious and offers lots of advantages with only a few minor disadvanteges so I'll share it with you here:

...(and 15 minutes passed...)

No excuses: I have failed to come up with a decent coding example on my own - the code just turned against me once I looked at the time and found out that one of the three "Lord of the Rings" are beginning in 5 minutes... Not that I haven't seen all of them at least 3-4 times but this is Christmas and about the first vacation this year which doesn't include a lot of work on our house or trips to far-far-away family - so watching a movie I've seen before and NOT get up from the couch and get some work done is really a new sensational feeling..... I could probably learn something by doing a bit of coding on the issue I'll just find a perfectly good example written by Jimmy Bogard for you  :o)

I'm off to see some orc bashing. Happy New Year to all of you - see you in 2009  :o)

Regards K.

torsdag den 25. december 2008

TDD on untested code - why does the first test take so long?

Most software developers have at some point in time been assigned a task with the following description: "We need to extend report X with a new column which sums up all the other columns in each row" - or something like that. Even if you don't know anything about the codebase tasks like this one in most cases don't cause too much trouble because you extend already something which is already working and in production. Even if you like to deliver this new functionality with shiny tests with 100% coverage of the new functionality it isn't a big deal because you don't have to touch the existing armageddon of untested code.

Worse - much worse is the task assigned to you the next day which says "Well - we have this bug in our invoicing system which causes all sales on the 1. of January to never show up in our reports. We need you to fix it". Even if you know that the invoicing system is a pretty decent working piece of software without a lot of maintenance - you also know that it has a mere code coverage of about 2%... When asked "How long will it take" what do you respond?

If you and your team are on the TDD side of things I have always been astonished how long it takes for someone to take the first step towards TDD-enabling untested software. However after having read the first 10-or-some chapters of Michael Feathers Working effectively with legacy code I am beginning to put words to my gutfeeling of "This will probably take a while..." when I see a change request to a system I know doesn't have a decent testsuite attached.

You've been assigned the task and you need to write your first test - why does it take forever to write it? Michael Feathers goes deep with numerous code examples but from a birdseye view it all sums up to the fact that before you refactor the dependencies in your untested code you can't write a suite of good unittests. Unittests must be kept as short as possible - I've heard the "No test should be longer than 15 lines of code" and it is a good best-practise to follow. Of course it doesn't always happen but if you have to write 20 lines of code to set up your test you need to look for design smells - most notably violations of the Single Responsibility Principle on the class or classes you are testing.

What I've recognized after reading these chapters are that code which have been developed without testing in mind have lots of dependencies to other classes. I've whupped up quite a few of myself - no doubt about it. When all you do is write code and never actually use your own code in a test you'll never get to see how your code "looks" from the outside. You basicly just make things work - and whoever is left to use your code after you have signed off on a task are pretty much on their own. This is how i.e constructors and methods with 10+ parameters are being born - I've seen them in my entire professional career wherever I've been - if you are "coding away" and need an extra parameter, you change the signature of your method, change the caller to use your new signature and everything is fine - from your perspective. What happens is that the more parameters you pass into a method the more state you will have to set up in your "Arrange" section of a unittest. Given that the more parameters a method or constructor takes the more state is injected your tests of that method will also be bigger in terms of lines of code - and long "arrange" sections in your tests are as much of a codesmell as any other codesmell you can think of.

The first test you write on untested code will have to take into account the time spent refactoring all the intertangled dependencies you dig up trying to get to those precious three lines of code you want to test on. It's a fact of life - get used to it. You might have to split up large classes, move object creation to constructors, extract interfaces to be able to mock dependant libraries etc. before you can actually make the single test that solves your problem turn green... The next time somebody has to write a test on your refactored code it will be easier - but the first test takes the longest - and the first test is also the one people fear the most because there is no other tests around to back you up when you begin to alter working code.

I agree with him on most of his writings - not everything though. He actually promotes writing "characterization tests" for already existing code "to be able to test for the existing behaviour". I disagree with him. The time you spend writing tests on existing code could be better used focusing on solving the problem you have before you. It's a mere waste of time in my opinion - when do you know enough and have written enough tests to conclude that the core existing behaviour is covered and documented in your tests? No sir - Keep It Simple Stupid, just get the job done. Use some of the many useful techniques he has documented but please - don't write tests for existing code. He means it well but honestly - it's just not valuable work to write code for existing functionality.

Even though I'm not finished with the book I can highly recommend it to anyone who just wants to be able to navigate through untested code without causing too big waves in the pond. It's a good book with quality stuff in it - definately one I will use to plan my attack on codebases that I've never touched before

Regards K.

onsdag den 17. december 2008

Silverlight - the pros and cons

Some time ago the team I work with decided to go to a one-day Silverlight seminar at Microsoft Copenhagen. Today we went and with an openminded heart (read: I didn't know anything about Silverlight except that I know I at some point downloaded a plugin to be able to access a beta version on MSDN (I think it was...).  I admit it: All I knew about Silverlight in advance can be told as "It must be some sort of Flash something-something from Microsoft".

So I went - and here's the sum of my notes and the people I talked to during lunch etc. Let's start with the "What": 

Silverlight is a cross-browser plugin which enables you to write light-weight Windows Presentation Foundation (WPF) applications and embed them into a website. It doesn't require the full .NET framework  on your machine but instead the plugin you download contains a smaller, compressed version of the .NET framework which enables you to run compiled Silverlight IL code. Silverlight uses XAML which enables you to write markup language using an XML syntax to express a UI.

That's the short story. There's much more to it (please leave a comment if the above needs to be corrected) but that's the basics as I know them of tonight. However - I talked a little and reflected a little during the rest of the presentations today and finally home again I have come up with this list of pro's and con's from my notes and my memories of the conversations I had:

Pros:

  • The Silverlight Toolkit on Codeplex is a good thing and it reminds me that someone at Microsoft is beginning to "get it". The toolkit is released frequently and doesn't require the client to download an updated version of the browser's Silverlight rendering engine. Any additional usercontrols except the standard set of controls (which only covers the most basic textboxes etc)  are embedded in your specific Silverlight application.
  • If you are a WPF developer writing desktop apps the switch to writing Silverlight website apps is easy to overcome because the context (XAML, .NET) are very similar. This isn't exactly the case with any other existing Flash technology where the learning curve is steeper no matter what you have tried before Flash
  • Expression Blend is a working environment aimed at designers. How much you tweak and turn Visual Studio I have never heard anyone say that it is a good working environment if you aren't committed to reading code. Designers have had more luck with products from i.e. Macromedia and I think that Expression Blend is trying to please other roles than the "system developer" - which is good  :o)

Cons:

  • I was told that if you i.e. copy/paste XAML from one file to another without also copying the codebehind, the target XAML file (with an empty code-behind) would only fail runtime - the compiler wouldn't let you know that you were missing method stubs in your codebehind to match the various events you had set up in the XAML markup. Error messages could be pure nonsense and debugging XAML is impossible. Of course you don't get to succesfully build a broken XAML document missing i.e. and end tag but checking for something as simple as method stubs should be a no-brainer. What am I missing here - we're at version 2.0, not some 0.8 beta release.
  • It appears that there is a Silverlight unittesting framework available - but it sounds a bit disturbing in my ears that the suite of unittests runs in the context of a browser? In order for me to adapt to Silverlight I need to have a good testing framework around when adopting a new technology - definately something I need to check up upon.
  • Styling in XAML means no inheritance - and your styles must be explicitly set on every element... That means that you can't have a general style for i.e. all your buttons which styles every single button on your site the same way. Oh no - you explicitly have to tell each and every button how it should be styled using an attribute on the button....... The guy from Microsoft breaking the news to us tried to be diplomatic about it. I can only imagine why this problem hasn't been solved when releasing version 1.1 - I wouldn't expect such stupidity to survive much beyond a version 1.0 of any product
  • Silverlight applications on the web can't be indexed by Google. Microsoft is working on this issue which should be solved in version 3.0 (due in Spring of 2009). Google is a cornerstone in any marketing strategy so the lack of searchengine compatibility shouldn't be neglected when qualifying Silverlight as a mature product.

Bottom line is: I think it could be fun to work with Silverlight (I'm nothing but a programming scarecrow who likes to bring home new and shiny technology to my computer) and I think that Silverlight has the potential to be "big". I also think that right now I wouldn't use Silverlight for much more than menues, banners and other non-critical stuff which requires the user to have a decent visual experience but I couldn't recommend anyone using Silverlight for building fullscale websites based on what I've seen today. However this technology has come to stay and the web is increasingly getting focused on rich clients and UI so this isn't my last encounter to the Silverlight technology.

Regards Kristian

 

Links:

www.silverlight.net

Microsoft Silverlight: 10 reasons to love it, 10 reasons to hate it

tirsdag den 25. november 2008

Thoughts on a revised Agile Manifesto

Today I became aware that there is a movement in the Agile community which has been born out of concern that the Agile Manifesto basicly needs to be updated. The argument goes that core values was forgotten when the manifesto was announced and the manifesto needs to be updated or revised to fit the world of today.

I got curious - so I found an article by Brian Marick, one of the people who is one of the original signatories of the Agile Manifesto. He believes that there are several values such as "skill", "discipline" and "joy" are missing and needs to be clarified as core Agile values. A paragraph from the article explains why "joy" should be a core value:

"Now, I could say that a joyful employee is a productive employee, and that lack of joy on a project is like a canary keeling over in a coal mine: a sign that something big is wrong and you better pay attention. Maybe that’s true. I’d certainly like to believe it. But, fundamentally, I don’t care. I think joy is its own excuse. We deserve it. More to the point, those people around us deserve it. Their work shouldn’t suck any more than yours does, and you have it easily within your power to remove some suckitude."

I agree with him in every word - but the consequences of having the Agile Manifesto updated with terms that requires or expects joy from you in order for you and your team to be agile is a paradox. Agreeing that you are only doing things right when you are enjoying working on a project is like saying that you are failing Agile principles if you don't always have a good time earning your payroll - and that's where my warning signs kick in.

In another article James Shore expresses similar concerns - he calls it the decline of Agile. His concerns are clearly expressed in the following:

"The good Agile--the real Agile--it really works. I've seen it. My colleagues have seen it. It's been repeated hundreds of times, and some of those projects have succeeded for years. But those hundreds of successes will be drowned out by the thousands of failures"

Agile is hard. The rewards you get for being agile isn't something you earn just because it works well for your neighbour. You have to put in a lot of effort and be prepared to fail a lot before you "get it". This is by far the hardest part - to fall on your nose a lot in the beginning without loosing faith. The reason you do it anyway is because you believe in certain values. Agile is a set of values you basicly either can commit to or can’t commit to. The discussions in the community often circles around how organizations are implementing the values of Agile - the ”how to do Agile”. The ”what is Agile” is another discussion which should not be confused with the ”how do we succeed with Agile where I work”.

Why do you and I get out of bed and go to work every day? Ask yourself why - what is the core value that make you set your alarm clock to wake you up before you awake by yourself every morning? It's a simple question, but the answer isn't obvious and requires you to reflect upon your everyday life. The vision for me as a person to go to work every day is that I need to feel independant in order for me to function as a social, human being - so I have an education and go to work because the money I earn there helps me to get closer to that vision. I also believe in love and trust so when I found the one we got married because that was the way for us to make a vision we both share come true. What we do we do because we believe in something – we believe in visions and ideas and everything we do, how we react, the choices we make every day should be connected to core values which we believe in.

The Agile Manifesto is a vision - it describes a set of values, nothing more, nothing less. Discipline, joy etc. are not values as such - adressing discipline and joy when implementing Agile however helps you in making the vision of Agile come true in your work. We don't need to update the Agile Manifesto - we need better skilled, better trained, better educated evangelists who can communicate to the world how Agile is implemented because the values and principles behind Agile are generally accepted, I believe. The decline of Agile that James Shore is blogging about is a matter of people who made the choice of going Agile but don’t ask for help or are not being pushed in the right direction by experienced Agilists when they attempt to implement Agile for the first time. We should address those implementation details in terms of "how to do Agile", not "what is Agile". We don't need to devalue the current principles and guidelines of Agile by upgrading best-practices such as discipline and joy to something they are not – that would indeed be a clear violation of the Single Responsibility Principle, I believe ;o)

/ Regards K.

lørdag den 22. november 2008

To TDD or not to TDD

I sat down today and reflected a little on SCRUM and TDD. The two are very alike in many ways and I have strong feelings for both of them because I think they work for me. They are "right" in a way.

Lots of blogs have lists of how you become better at SCRUM. The Nokia test for instance. I haven't however seen a list of how to become better at TDD. TDD is in the community more a "write your tests first and voila - your'e now a TDD developer"... Ehmm.... No, couldn't be farther from the truth. So I sat down and wrote for an hour and came up with the following considering the headline: How do you become better at "to TDD":

  • Get the basics right. Spend at least an hour or two and read about TDD. How do you do it? What is the AAA syntax? Testdriven development means that you write your test first. If you don't know why that's crucial to your success as a TDD developer you should read some more before going on a TDD deathmarch.
  • Want it. If you want to TDD you want to write your test first. No more "I'll write code and test if afterwards" - if you think like that you don't want to TDD yet.
  • Know you will fail when you begin. You will definately suck at it when you first attempt to write tests. You will forget to write your test first - many times. Your code will look different and not "feel" right. Even the smallest problems will be hard to solve because you have to think on writing tests, tests, tests. It feels like the TDD approach hinders you from thinking on the three lines of code that will solve your problem and enable you to close the damn support ticket... Relax. This is perfectly normal. Ask for help and tell that you can't come up with a decent test for this specific problem. If a test is hard to write it is often because the code itself is flawed and has design issues which makes the code hard to test - and you are not able to recognize those code smells at first. Know you will fail - you also fell the first time you rode a bicycle, didn't you?
  • Do it even when it's hard. It is easy to fall into the mental trap of "this code is 3 years old and un-tested so writing tests on this crap is overkill for this bugfix". No! You are not being paid to always jump over the fence at the lowest point - and just claiming that a codeblock is too hard to test without having asked for help or considered what it would actually require for you to make it testable ranges somewhere between stupidity and ignorance.
  • Do it where it matters the most. If you have a piece of code which is central to your applications or is being called upon everywhere (i.e. that little string utility thingy which is shared across all your VS projects around) and it is untested - test it at all costs.
  • Don't do it everywhere. If you have a piece of code which is used for generating reports once or twice a month for one person in the company and a test requires 4 hours of boilerplate work - don't do it, just make the code work.
  • Get help. When you fail or things won't work your way - ask for help. It is the second-most crucial thing next to wanting it: Ask for help if you're stuck. Get people who knows how to do things to push you in the right direction. Read books, subscribe to blogs to get more info on how to TDD.

I believe that you will have to want to TDD the same way you will have to "want" to SCRUM because both SCRUM and TDD are basicly a mindset you must adapt to in order to make it work for you. If you want to loose weight you will have to want to not eat so much or you will have to want to exercise some more. Your mother or girlfriend can't make you loose weight nor can any of your teammates or collegues make you want to go TDD on your code. They can and will encourage you just like your family and girlfriend will encourage you to loose weight but it won't work permanently if you don't want it.

When do you know that you're on the right track? You know you want it. Ask yourself that question and if you know you still want to TDD deep inside everything is A-OK. If you don't then focus on getting your motivation back or decide to not to want to TDD. That is perfectly OK as well because why do something that you don't want to do? You can become a very competent coder without ever writing a single unittest. Just be honest with yourself and don't go TDD on your work if you don't believe in it.

To TDD or not to TDD - that really is the question :o)

/ K.

fredag den 7. november 2008

How agile are you?

I always had this sort of weird feeling towards "Take this test to know how lovable / sexy / fat / lucky / suicidal / etc. etc. you are" - however I found myself taking one today and right now I'm advertising for it... So much for standing up to your principles I guess.

Here it is - I got a steady 39 (brag, brag, brag). How agile are you?

/ Kristian