Friday, December 9, 2011

BTVWAG: Software Craftsmanship from a Product Owner's Perspective

I attended my first BTVWAG meeting and was very impressed with the turn out. I didn’t count the attendees but I expect there were around 30. I was especially surprised to see no one I recognized from the Vermont.NET User Group. In fairness – the .NET meeting was Monday so two meetings in 3 days is a bit much – especially during the holidays – but it was well worth it.

Rik Dryfoos gave a great talk on Software Craftsmanship. Though the talk was aimed at management / product owners (ultimately getting buyin), there was a little something for everyone, and ultimately getting the coders on management on the same page regarding code quality is greatly needed – and now we have a term for it – Software Craftsmanship. Why do we need a term for it – whats wrong with Code Quality? In short, in my opinion, its because writing great code is more of a craft, than an engineering discipline. It takes a new term to move heads.  

If you weren’t able to attend – take a few minutes and race through the slides available here.

Now for my own notes from the meeting:

Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin was added to my Wish List (hopefully that means someday I will find the time to read it)

The term YAGNI was mentioned briefly (You ain’t gonna need it) and I wasn’t familiar with it, so a quick google search led me to wiki where I realized that it is the idea that you should wait to do that really cool thing until that really cool thing is needed. I have a poster on my wall that communicates this same message which can be found on slide 22 here (I added a screenshot below).

image

Code smells was also brought up with a great link here. I hope to eventually find some time to automate the measuring of these code smells. I know fxcop does a lot of them but wouldn’t it be great if you could measure the total stench of your code?! We have to be careful though – measuring gets us a little too close to engineering..

One smell that was new to me was Cyclomatic Complexity which in my own words – measures the the number of computational branches your code can take. In other words if there are no If statements than the complexity has only one path and a Cyclomatic Complexity of 1. I find this smell particularly interesting, because I could use it ask myself, is this module complex for a good reason or did it just turn out complex.

The Software Craftmanship Manifesto was introduced and on its old style paper layout it feels something like joining a brotherhood

image

During the presentation there was an analogy to a blacksmith that was made – which is quite fitting with the old style paper above… One part of this analogy that really hit home for me was that a manager can’t mentor a blacksmith, it takes a blacksmith to mentor a blacksmith. I personally have experienced this level of micromanagement and it simply does not work. You can’t tell the blacksmith how long its going to take to mold the metal – he has to tell you.  

On one of the slides, it was mentioned that Rik would give his company a Red (not so good) for Pair Programming, which isn’t much of a surprise as most companies struggle to implement Pair Programming. I asked him what it would take to be Yellow or Green. I was surprised by his answer. He said that for Green, every piece of code would need to be Pair Programmed. I respect and appreciate his answer but personally find that to be excessive “craftsmanship.” I have done Pair Programming and can vouch for the value. We were able to come up with a much better design than either of us would have come up with on our own, and we both had intimate knowledge about how and why it was designed the way it was that can’t be compared to trying to “show” the how and why afterwards. But, then we went our separate ways and worked on the less challenging parts of the design in parallel. I can’t imagine the boredom if I were forced to Pair Program an entire application. To go back to the blacksmith example, do you tell the blacksmith that it takes two master blacksmiths to heat up the metal? We might want two when it comes time to shape the metal or some other intricate part of the process, but not the whole process.

Towards the end of the talk during some questions – the importance of the ability to say No was brought up. We need to ensure that our programmers understand the value of speaking up and are enabled to say no. For too long, we have been the blacksmiths that return a piece of metal that soon breaks, because we are never listened to when we say – the fire won’t get hot enough or the metal won’t cool long enough.

I appreciated the talk and especially thank Rik for his time and contributions to a better community of software professionals.

Dynamic LINQ – back to strings!!

 

Background:

During some recent refactoring – I was converting some old NHibernate code that was using the Criteria API to instead use Linq-to-NHibernate – I ran into a major roadblock. In my previous code – I was receiving parameters from my client regarding pagination, sorting, and filtering. Converting the pagination wasn’t too bad, then I got to the filtering and sorting…

My client (javascript) has passed me the string for the column it wants sorted. Linq wants a strongly typed function pointing to the member to sort on. I really don’t want to go write a translation layer that converts every string they could send me to a valid Linq Expression… so then I found Dynamic Linq.

Dynamic Linq:

You can find a blog about it by Scott Guthrie here: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

You can download the sample which contains the code here: http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx

Down to the Code:

I set up a proof of concept – available here: https://github.com/jhoguet/DynamicLinq---Nhibernate-Proof-of-Concept

Filtering:

So how can we filter on a column name available in string format…
       
[Test]
       
public void ProofWhereEquals()
       
{
           
var person = _dao.GetPeople().Where("FirstName=@0", "Jon").Single();

           
Assert.AreEqual(expected:"Jon", actual:person.FirstName);
       
}

and note this gets translated all the way down to NHibernate generating the following SQLite code

select person0_.Id as Id0_, person0_.FirstName as FirstName0_, person0_.LastName as LastName0_ from "Person" person0_ where person0_.FirstName=@p0;@p0 = 'Jon' [Type: String (0)]

not bad – how about something more realistic for a filter… LIKE

        [Test]
       
public void ProofWhereContains()
       
{
           
var person = _dao.GetPeople().Where("FirstName.Contains(@0)", "o").Single();

           
Assert.AreEqual(expected: "Jon", actual: person.FirstName);
       
}

which generated…

select person0_.Id as Id0_, person0_.FirstName as FirstName0_, person0_.LastName as LastName0_ from "Person" person0_ where person0_.FirstName like ('%'||@p0||'%');@p0 = 'o' [Type: String (0)]

alright I am impressed – but surely it will break if we do a NOT

        [Test]
       
public void ProofWhereNotLike()
       
{
           
var person = _dao.GetPeople().Where("!FirstName.Contains(@0)", "o").Single();

           
Assert.AreEqual(expected: "Manrique", actual: person.FirstName);
       
}

which generated…

select person0_.Id as Id0_, person0_.FirstName as FirstName0_, person0_.LastName as LastName0_ from "Person" person0_ where  not (person0_.FirstName like ('%'||@p0||'%'));@p0 = 'o' [Type: String (0)]

alright I am impressed!

But can it handle the order by problem…

        [Test]
       
public void CanOrderBy()
       
{
           
var person = _dao.GetPeople().OrderBy("FirstName descending").First();

           
Assert.AreEqual(expected: "Manrique", actual: person.FirstName);
       
}

which generated…

select person0_.Id as Id0_, person0_.FirstName as FirstName0_, person0_.LastName as LastName0_ from "Person" person0_ order by person0_.FirstName desc limit 1

sweet!

At this point I was satisfied and moved on – I know I read some blogs that spoke of limited support within DynamicLinq – but it certainly covered what I needed (I vaguely remember one example LIKE ‘StartWith%’)

I did find one surprising side effect (I might argue bug).

 [Test]
       
public void WhenArgIsNullBadThingsHappen()
       
{
           
try
           
{
               
var person = _dao.GetPeople().Where("!FirstName.Contains(@0)", null).Single();
           
}
           
catch
           
{
               
//you need to check for null in your implementation
            }
       
}

 

When you pass in null as the parameter you get some misleading exception

System.Linq.Dynamic.ParseException : No property or field '0' exists in type 'Person'
Took me a little while to figure out tha tit was looking for a property of ‘0’ because I passed in NULL, but my fix was to add a code branch looking for nulls and avoiding the additional LINQ altogether if the argument would be NULL.

Thursday, December 8, 2011

TeamViewer – Latest favorite in remote support software

 

So once again, being the “computer guy” for friends, family, and all their friends has led me to need to remote into someone’s computer. I decided to give TeamViewer a try and I really liked it.

Why?

1) Simple and quick: no creating accounts. It creates a unique id for each install and a unique one-time password for each session. They read me the numbers over the phone, and I am in.

2) Can run the program without installing it – so I can keep it on a thumb drive or… link to it from my blog and don’t even have to install it (need admin rights though)

3) Special (lighter) app for “customer.” Doesn’t require installation, and doesn’t even require admin rights…

4) Free for non-commercial use

Now for the links:

Full Installer (ideal for the technician) http://www.teamviewer.com/download/TeamViewer_Setup_en.exe

Light App (ideal for customer)http://www.teamviewer.com/download/TeamViewerQS_en.exe

Sunday, November 13, 2011

Culture at Netflix

http://www.slideshare.net/reed2001/culture-1798664

Awesome slide deck on the culture at Netflix and the definition of a culture without “politics.”

Thanks to Rob Hale  for brining this to my attention.

In particular – check out the slides on Talent Density and the obvious but often overlooked consequences of increasing processes (talent leaves).

Thursday, November 10, 2011

async / await

So after finding out that this is something I should be familiar with during a recent user group meeting – I decided to check it out…

http://www.dnrtv.com/default.aspx?showNum=205

I really enjoyed this video – while it is highly technical and a bit dry – it left me with very few questions. This talk literally goes into what the compiled code will be, and what the CLR is going to do.

It is so exciting to see C# continue to evolve – and in ways that make our lives as programmers easier!

Saturday, October 22, 2011

Meeting: Magic Bag of Tricks

I intend to add to this post over time with those tricks I want to remind myself before walking into a meeting.

Pearl Metaphor: Iterative development is like a pearl starting with sand and adding Calcium Carbonate. Instead we add functionality and usability over time.

Construction Metaphor: Moving a wall 3 inches to the left doesn’t cost a lot in terms of materials – sure you need a few more nails and maybe a few more 2x4s but it is going to cost a lot in man hours. Same is true for many late changes to a program.

Source: Code Complete

Monday, December 13, 2010

MVC View Not Found Misdirection

I recently came across the following error:

image

I was deploying to a discountasp.net and could think of an infinite causes of the problem. I decided to write a simple little code block to verify the view was there and accessible:

image

This confirmed that the file was in fact there. Sure that the problem had to be with discountasp.net, I sent them an email and slept on it. Their response was that it was my fault:

image

I tried searching their forum and found it lacking so did some google searching when I found this:

http://forums.asp.net/p/1592374/4038196.aspx

Which basically states the obvious – what about your master page? Yeah – what about my master page? Wait – why didn’t my master page publish…?

image

Well that would do it… no idea how that happened – I wouldn’t have changed it on purpose.

image

Problem resolved – hopefully this saves someone else some time.