Wednesday, May 21, 2008

On Thrashing

Sometimes I sit back and am amazed at the design tools we have today. As a single developer I can create a very functional web application in a matter of months. Even with the great tools we have today developers still face impediments to productivity. If you have any experience writing software then you have faced the problem of thrashing. When a fly is caught in a spiders web he will wear himself out attacking the problem with every once of energy he has, only to find in the end that he has made no real progress. That is the essence of thrashing.

For a designer thrashing can be broken down into different types. I've identified four that I'm sure many people have experienced, although I'm sure there are more types out there. If you can think of anymore leave a comment.

Design Thrashing - Design Thrashing happens when you first start architecting a product and you want to build a solid foundation to work on. Quite simply there are so many different ways to do things and the developer must make a choice that will have great impact on the future maintainability of the product. The thrashing comes in because there is fear that will choose a less than optimal course and will suffer for it in the future. The only real solution I have found for design thrashing is to get familiar with design patterns to build off the ideas of people who have come before you.

Tunnel Thrashing - Tunnel Thrashing comes into play mostly when debugging. You think you know what the problem is but everything you try to do to fix it fails. You may back further and further away from the problem trying to find the exact spot of failure but the solution eludes you. I've found the simplest way out of tunnel thrashing is to talk to another developer. There has been many times when I've talked over something with someone and in the middle of talking the light comes on and I realize what the real issue is.

Boredom Thrashing - Boredom Thrashing tends to strike towards the middle of a project. This is when you are just sick of the project you are working on and just can't bring yourself to think about it anymore. I'm not sure there is a cure for this type of thrashing, except maybe alcohol consumption.

Overwhelmed Thrashing - Overwhelmed Thrashing comes at the beginning of a very large project. I've seen many software rewrites fall into this type of thrashing. The current application is 10 million lines of code and a rewrite is necessary. You start talking to current users and they describe in excruciating detail that the rewrite must do everything the old app did, and it must do it better with more stuff. The application spans 5 different departments that all expect different outcomes but must all be coordinated correctly and, oh yeah, when can you have that done? The only cure for overwhelmed thrashing is to try to chip off a little bit everyday, and let time take care of the rest.

Blog Thrashing - This is when you write a blog post instead of hammering out some code like you should be ;-)

Wednesday, April 2, 2008

Better Searching Using LINQ

I'm going to come right out and say it, I love LINQ to SQL. I love it, I love it, I love it. Not only does it save us time by eliminating plumbing code, but it gives us new tools to write better code.

One thing that has always bothered me was I never found an elegent way to do multi-field searching. Take for instance the following class describing a customer in an application (written in pseudocode):

Public Class Customer
Property ID as string
Property FirstName as string
Property LastName as string
End Class

Somewhere you are going to have a screen that allows you to search for customers. You will probably have three textboxes where a user can put in values and a Search button that will execute a function that returns a list of customers that meet those criteria. Your function may look something like:

Public Function GetCustomers(byval _id as string,byval _firstName as string, byval _lastName as string) as List(Of Customer)

dim custQuery as string
if _id <> null AND_firstName <> null AND _lastName <> null Then
custQuery = "SELECT * FROM customer WHERE id = " & _id & " AND firstName = "....
elseif _id <> null AND _firstName <> null THEN
custQuery = "SELECT ...."
elseif
........
end if

return custQuery.execute()
End Function

I've also seen this type of logic written into a Stored Procedure to remove some of the ugliness from the application code itself. There are probably other more elegent ways to write the code but it all comes down to a bunch of If statements and checking for nulls, which is difficult to read and almost impossible to maintain. LINQ gives us a better way to do the above search.

Public Class CustomerSearch

Private dc as CustomerDataContext
Private mCustomerQuery as IQueryable(Of Customer)

Public Sub New()
dc = New CustomerDataContext
mCustomerQuery = From cust in dc.Customer
End Sub

Public Write-Only Property ID as String
Set(ByVal value as String)
If value.Length > 0 Then
mCustomerQuery = From cust in mCustomerQuery _
Where cust.ID = value
End If
End Set
End Property

Public Write-Only Property FirstName as String
Set(ByVal value as String)
If Value.Length >0 Then
mCustomerQuery = From cust in mCustomerQuery _
Where cust.FirstName = value
End If
End Set
End Property

Public Function ExecuteQuery() as List(Of Customer)
Return mCustomerQuery.ToList()
End Function
End Class

With the following class you could then do your search from your form using the following syntax:


Public Class frmCustomerSearch
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btnSearch.Click

Dim mCustomers as List(Of Customer)
Dim custSearch as New CustomerSearch

'this is assuming a textbox called "txtID"
custSearch.ID = me.txtID.Text

'assuming a textbox called "txtFirstName"
custSearch.FirstName = me.txtFirstName.Text

mCustomers = custSearch.ExecuteQuery()

End Sub
End Class

This code is much more elegant, easier to maintain and easier to add functionality to later. As written it is not perfect but it does demonstrate a way we can use LINQ to write better code.