October 20, 2007

 Software Development Essential Practices

I was in an interesting discussion last night: what software development practices do you consider essential? 

While opinions varied, I think there was some consensus on a few items.  In my list I also include some tools.  Some of these were mentioned by the group, but consider them my own additions.  Also, I am making this list specific to .NET, but the list applies to just about every language.

Universally agreed Practices

  • Source Control (1)
  • Local Development -- Every developer should have everything on their computer to run the system.  This includes all of the software and all of the source code.
  • Bug Tracking - nuf said.  There are to many tools available to list here.
  • TDD - Test Driven Development.  There was a little bit of back and forth, but the general consensus was that this should be done.
  • ORM - Object-Relational Mapping
    • NHibernate 
    • SubSonic - My person favorite
    • LINQ to SQL - not yet, but I feel this should be on the list.
    • LLBLGen ($) - Not free, but I've heard many good things about it.
    • More
  • Continuous Integration - Simple process that sits on a server and waits for things to get checked into your source control system.  When it sees something new, it gets all of the latest source code, compiles it, and runs all of the unit tests.  If there are any problems anywhere in that process it alerts the users (email, desktop icon, wave red flag, etc). (3)
  • One Step Build - it is unbelievably cool to be able to click one button and have your entire project compile, run all tests, and possibly create an install in one step.  Personally, I do like it, but with the current set of tools this is one of the hardest parts to setup.

Highly thought of but non-essential practices

I'm sure I have missed some tools in the list, but it is the practices that are more important anyway.  But if you put a comment about any tool that I missed I will add it to the list.

(1) Source Safe was notably not in the list.  While I don't like it either, it is better than nothing.  But if your team is greater than 5 people or you have multiple people working on the same project you really should look at one of the other products on the list.

(2) Not a unit testing library, but a Mock Object library.  Pick a unit testing libarary (NUnit, MBUnit, XUnit), then pick a mock object library (Rhino Mocks, TypeMock, NMock) to use with it.

(3) I really need to talk about continuous integration more.  But it is one of those things that leads you down a path.  First you add source control, then you start adhering to separation of concerns, then you start unit testing and mocking more, then you add continuous integration, and then one step builds are all part of the mix.  One best practice leads to another, but they don't make a bit of sense without some of the prior pieces.

(4) If you are a Code Rush person instead of a ReSharper person -- carry on, you are in good company.

($) The cost money - not just beer, but may have free version versions as well.

Labels: , , , , , , , , , , ,

 June 28, 2007

 NetDug last week...

I thought this was funny.

Last week I gave a presentation on C# 3.0 and LINQ to NetDug. Mind you, this is a really well run group. We meet at the ProClarity ---erm Microsoft -- building in downtown Boise. Usually someone from Microsoft lets us in, guards over us, and things go really well. Not this time.

It started with one of the group leaders sending me an email, the day before the meeting, telling me that he could not get onto their server, ergo: they couldn't send an email to the group telling them that the meeting was on, and what we were talking about.

Not great, but I can work around that. I sent out a message to the BSDG group, which is also largely Boise area developers and told them. It is largely the same people anyway.

One day goes by.

OK, day of the meeting. I show up and there are already people there waiting outside the building. I'm early so I don't think much of it. The Microsoft building here in Boise is actually a nice spot. There is this cool little spot that had some places to sit in the shade with lots of trees, which was needed because it was over 80 degrees at the time. So we just sat there until someone was going to open the building for us.

Janitors walked in, a few people walked out. I even knew a few of them. It was getting really close to the time of the meeting so I started talking to one of them as they came out. Asking if certain people who are usually there to open the building for us are still in the building to open the building so we can have our meeting. (yes, that is a run on sentence, but appropriate since the person I talked to was a tech writer -- who taught tech writing). They were not there.

Great. First there is no email to tell anyone about the meeting we were supposed to have, and now we don't even have a room to have it in. This is getting better all the time.

By this time there were about eight people there. That is a small gathering for this group. It usually gets 20 people. But, they were still interested in what I had to show them. But we were outside, and my laptop is useless outside running on battery power -- so no power point. There are worse things in life than giving a talk with no power point, really. So next best option: wing it with a pen and paper.

This is where it is a good thing that there were only eight people there. So I started the meeting, outside, and started talking. One thing that does happen when giving a talk like this, you cut out all of the extraneously stuff.

Array initializers -- didn't talk about it.
Extension Methods -- yes, but just enough
Object and Collection initializers -- just barely
Expression Trees -- mentioned that I didn't know anything about them.

But we did talk quite a bit about the var keyword, anonymous types, LINQ, and Lambda. All via pen and paper (which I now refer to as the original Power Point).

So, obviously, I wasn't trying to get the attendees to really grok the material, but I think they did capture some of the general zen. Which, as far as I can tell, is to rethink how and when you use a for loop on a list. With LINQ and Lambda, we should be seeing a lot fewer of them.

In the process we also talked about PLINQ, XLINQ, DLINQ, LINQ for SQL, NHibernate, SubSonic, and Log4Net. It was a good meeting. Not bad for considering the circumstances.

Then to close off the evening for myself, my mom and brother were attending a dairy conference a few blocks away, so I snuck into there and bored myself to sleep. They were talking about whey futures (as in stock market like futures).


I thought I had given a reasonable presentation with no slides earlier, on the street, in 80 degree weather. Here was a guy giving a presentation inside, with a huge projector (20 foot screen - at least) to 50 people and doing it badly.



Now all of this comes from my own general preferences. There is an art to displaying lots of numerical data on a slide. There is also an art to showing charts on a slide. This guy knew about neither, and probably never read anything by Edward Tufte.

Note: I have read Edward Tufte, but please don't blame my bad slides on him -- they are my fault for not reading his books enough.

All of his slides were white. All of his text was black. There was no variation. They could have been printed on a black and white printer and no one would have known the difference. Imagine trying to decipher slide after slide filled with large grids of numbers, each row having a different type of number, and only a thin black line between them. Not good. Then to show emphasis on a particular number -- out comes the laser pointer.

I about made my brother buy me a beer after that. And dinner.

My mom did instead.

Labels: , , ,

 April 12, 2007

 HNibernate: Many-to-Many Joins

OK, this one has waisted a few too many hours for me and another developer here in the office. Resolving many-to-many table relationships in NHibernate.

Note: last time I blogged on NHibernate I was told things were easier with ActiveRecord. But I'm still not using ActiveRecord.

I will set things up first. Here is our table layout and relationships:

If you can't see the image, there are three tables: TableA, TableB, and TableC. TableA and TableB both have relationships to TableC. A classic Many-To-Many table structure.

Now the first thing you have to decide is which table leads. Or which table is the master. That table will take care of actually adding and removing items from TableC. I will use TableA.

So in TableA's hbm you will have an entry that looks like this:
<bag name="TableBs" table="TableC">
<key column="TableA_id">
<many-to-many class="MyNamespace.TableB, MyNamespace" column="TableC_ID">
</many-to-many></key></bag>
and in the TableA class (this is C# kids), you should have this:
private IList<tableb> _tableBs = new List<tableb>();
public virtual IList<tableb> TableBs
{
get { return _tableBs ; }
set{ _tableBs = value; }
}
Ok, TableA is now setup as the master. Now to make TableB the slave.
In the TableB hbm.xml you will now see this
<bag name="TableAs" table="TableC" inverse="true">
<key column="TableB_ID">
<many-to-many class="MyNamespace.TableA, Aim.Domain" column="TableA_ID">
</many-to-many>
</key></bag>
Then the TableB class
protected IList<TableA> _tableAs = new List<TableA>();
public virtual IList<TableA> Contacts { get { return _tableAs ; } set { _tableAs = value; } }
It would be easy to miss the difference between the two, so here is the difference. In the TableB hbm there is a "inverse="true"". That is the only real difference, but it is a critical change to make if you want to be able to modify what items are related to what.

Labels: