Cory Foy

Thursday, March 30, 2006

Agile and the Virtual Case File project

I stumbled across a link to Glen Alleman's blog from a post on the Agile Project Management list today. He has an excellent post describing the FBI's virtual case file project, it's spectacular failure, and rebuttals to a lot of posts over the past few days to several agile lists asking if agile processes could have saved it.

In particular, several key things stood out to me about the project:
  • The Project Manager had never led a project before. (He was brought in because of his FoxPro experience)

  • There were no formal deadlines or milestones the contractors were obliged to meet

  • The two contracting companies used polar opposite development methodologies

A very good read, and a blog I will definately be subscribing to.

Tuesday, March 28, 2006

Using Symbols in Java Fitnesse Fixtures

Fitnesse has a nifty feature where you can store the output of one test table in a symbol that you can then use in a subsequent table. The documentation does a good job explaining the concepts, but seems to be missing some code behind the scenes to make it work. So I've put together a simple example of using it.

One thing to note is that this feature is implemented in the various version differently, which is why this is targetted at the Java Fitnesse version.

Let's say we have one class that returns a value (SymbolTextFixture) we need to use in a subsequent test (SymbolTestRecall). First, let's look at our value provider:

import fit.ColumnFixture;

public class SymbolTestFixture extends ColumnFixture {
  public SymbolTestFixture() {
    super();
  }

  public String getTestValue() {
    return "Set from Fixture!";
  }
}


So, we have a class whose instance provides us some value. Now, we have a class that needs to take in this value so it can display it:

import fit.ColumnFixture;

public class SymbolTestRecall extends ColumnFixture {
  public String testValue = "Not Set";

  public SymbolTestRecall() {
    super();
  }

  public String getTestValue() {
    return testValue;
  }
}


So, obviously our goal is to get the test value from a SymbolTestFixture instance into the testValue field of SymbolTestRecall, so it's getTestValue() method can display it.

As mentioned above, there is a special header syntax within ColumnFixtures that let you save the output from a method into a symbol, which can be reused later. Here's the Fitnesse fixture we'd use for this:

|Symbol Test Fixture|
|=getTestValue?|
|myKey|


The above test is saying to use a class called SymbolTestFixture to store the output of the getTestValue method into the symbol myKey. How does it know to do that? The = in front signals to store the value, and the ? at the end tells the Fit runner that the value will be coming from a method.

So now that we have the value in myKey we want to use it. This test shows that:

|Symbol Test Recall|
|test Value=|getTestValue?|
|myKey|Set from Fixture!|


This test says to use an instance of the SymbolTestRecall class and set the testValue field with the value stored in the symbol myKey. It then verifies that the value returned from the getTestValue method is the value returned from our previous test ("Set from Fixture!").

And there you have it! The complete Fitnesse test looks like:

!path /home/foyc/workspace/fit_stuff/bin

|Symbol Test Fixture|
|=getTestValue?|
|myKey|

|Symbol Test Recall|
|test Value=|getTestValue?|
|myKey|Set from Fixture!|


The above just adds the !path directive to where the output of my classes are. Build your classes, fire up your Fitnesse server, and test to green goodness!

Monday, March 27, 2006

On Reuse...

Excellent advice on building frameworks and libraries from John Roth, via the XP mailing list:

Reuse is an interesting issue. There's a rule of thumb that you should write it three times, then you're in a position to make a resuable library or framework the fourth, because you now know what you need; you're not speculating.

For the fourth time, if you simply take the first three and remove duplication you might even get it done faster that doing it separately.

That's certainly been my experience. Try to make a tool reusable too early, without having gone through iterations with it, and it rarely works well without modifications. But take something you've done several times, pull out the common components, remove the duplication, and you might just have something there.

It's one of the great things about Rails. It came from a real project, with real needs, and was really solving them.

Sunday, March 26, 2006

What's the difference between OS X and Vista?

Microsoft employees are excited about OS X..., at least according to the comments (350 and growing!) on this blog entry entitlet Vista 2007 - Fire Leadership Now.

This is what worries me about large companies. Microsoft used to be touted as the place to be. It doesn't seem like that anymore - now Google might be the place to be. But they're public now, and so they serve different masters. When the shareholders begin to run the company...

But then, I don't want to believe that you can't grow a company without turning it into a mess. Of course, you are going to have some politics, but with the proper leadership and focus people should be able to come together. Or, by drastically moving from the norm, as Richard Semler did with Semco (here's Geoffrey Slinker's paper on Semco).

In fact, the only large company I've read of so far that has been around for a long time and seems to have it right is 3M, a frequent example from books like Lean Software Development. Project champions, being able to understand the market, and ROI, and customers, and consistantly delivering on that.

Maybe 3M should start a consulting business. Maybe larger companies should pay attention to it.

Friday, March 24, 2006

Clearing a TkCanvas in Ruby

Something so simple, yet so seemingly undocumented...

After struggling for about 10 minutes with trying to clear a TkCanvas from Ruby, and only finding what seemed to be one message discussing it (but not answering it), I stumbled across the answer - delete('all').

So, if I have a canvas like this:

def initialize(parent)
  @parent = parent
  ph = { 'padx' => 10, 'pady' => 10 }
  clear_b = TkButton.new(parent) { text 'Clear'; pack(ph) }
  clear_b.command{clear}
  exit_b = TkButton.new(parent) { text 'Exit'; pack(ph)}
  exit_b.command{ exit }
  @canvas = TkCanvas.new(parent)
  @canvas.pack
  @start_x = @start_y = 0
  @canvas.bind("1", lambda {|e| do_press(e.x, e.y)})
  @canvas.bind("B1-Motion",
    lambda {|x,y| do_motion(x,y)}, "%x %y")
  @canvas.bind("ButtonRelease-1",
    lambda {|x,y| do_release(x,y)}, "%x %y")
end


I can use this as the clear method to wipe the canvas:

def clear
  if @canvas
    @canvas.delete('all')
  end
end


Easy as pie! ;)

self.out

James Shore on Dependency Injection

(Update: James updated his blog entry with a list of resources to good D/I articles [here and here] which discuss much better the topics below.)

James Shore has a new post about Dependency Injection, which he calls a "25-dollar term for a 5-cent concept."

While his examples were indeed examples of D/I, he seems to miss a critical one, the ability to use Spring and Spring.NET to inject dependencies at runtime using configuration files. He has a code snippet that looks like:

public class ExampleTest {
  TestDoStuff() {
    MockDatabase mockDatabase = new MockDatabase();

    // MockDatabase is a subclass of DatabaseThingie, so we can
    // "inject" it here:
    Example example = new Example(mockDatabase);

    example.DoStuff();
    mockDatabase.AssertGetDataWasCalled();
  }
}

public class Example {
  private DatabaseThingie myDatabase = new DatabaseThingie();

  public Example(DatabaseThingie useThisDatabaseInstead) {
    myDatabase = useThisDatabaseInstead;
  }

  public void DoStuff() {
    ...
    myDatabase.GetData();
    ...
  }
}


While it is true that the above is a form of dependency injection, so is the following:

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
  <object name="DomainObjectImplementationClass"
    singleton="false"
    type="ImplementationClass4, SpringDIExample">
  <property name="DependentClass">
    <ref object="DomainObjectDependentClass"/>
  </property>
</object>
<object name="DomainObjectDependentClass"
    singleton="false"
    type="DependentClass, SpringDIExample">
  <property name="Message"><value>Dependent Class</value></property>
</object>
</objects>


The above is a sample configuration file from a good article on Spring.NET in MSDN Magazine.

So, D/I isn't just about passing in a dependency via a constructor at compile time. It's about decoupling your code using interfaces so that you can inject completely different implementations at run-time using configuration.

Of course, Spring.NET is much more than that. You can initialize object graphs, set properties in objects, and initialize singletons, all from a config script.

Oddly enough, the one use James hits on - testing - is the one that I don't use frameworks like Spring.NET for, and one where his interpretation of being able to pass mocks in from the tests is very valid. But to say that D/I is a 5-cent concept because you can pass in a dependency via a constructor at compile time is similar to saying Rails is only a rapid environment because it is dynamically typed. While both statements are technically correct, they miss a vital concept - configuration based injections with D/I, and metacoding with Rails.

Sunday, March 19, 2006

The Dreyfus Model experiment

A few weeks ago, several coworkers and I went to the No Fluff Just Stuff Conference (overviews here, here, and here.) During the conference, I got to hear Dave Thomas speak about the Dreyfus Model for Skills Acquisition. A lot sounded familiar, and that was because Dave touched on a lot of the same points Andy Hunt did when he spoke at a CharJUG event in Charlotte.

For those not familiar with the Dreyfus Model, it is a model of skills acquisition that describes how people progress in their knowledge. There are five levels to the model, summarized as:
  • Novice - Needs to be told exactly what to do. Very little context to base decisions off of.

  • Advanced beginner - Has more context for decisions, but still needs rigid guidelines to follow.

  • Competent - Begins to question the reasoning behind the tasks, and can see longer term consequences.

  • Proficient - Still relies on rules, but able to seperate what is most important.

  • Expert - Works mainly on intuition, except in circumstances where problems occur

During the talk, Dave challenged us to an experiment. He asked us to watch closely over the next few weeks the conversations we have. When we are involved in a discussion, mark on each participants head a number in (imaginary!) magic marker which is the Dreyfus level you think of them at. Also put a (imaginary!) number on your head of your own Dreyfus level. Then, tailor the conversation to that. If you are the lower number one, bring the conversation to your level. Conversely, be sure you aren't talking over the heads - and needs - of the other participants.

The very next week I was working with my pair on some PL/SQL unit tests, which I had very little experience with. One of our development DBAs offered some advice which got us past this problem we were having. He then suggested that it might be a good idea to test another part of the procedure we were working on. But, he wanted us to make the decision of whether we should test it ourselves. After going back and forth for a minute or two of whether we should do it, the Dreyfus model experiement popped into my head. I immediately realized he was at least a four, and I was a one (at most).

Recognizing the situation, I turned to him and said, "I appreciate the teaching style you are using to get us to understand this problem. However, right now, I just need to be told what to do." Immediately he understood where we were at, and explained his reasoning behind what he was asking about. This enabled our pair to follow a specific path and acheive a win, while understanding a little more about the system at hand.

I challenge you all to do the same. In your conversations with your coworkers, think about what they - or you - need out of it based on the Dreyfus model, and tailor the conversation to it. You might just find yourself getting your points across clearer and faster.


Links:

Wednesday, March 15, 2006

The importance of System.Environment.NewLine

So, let's pretend you are happily coding along in C#, doing test-driven development, and you get to a method that needs to return a message that spans multiple lines. Say, an address printer that prints out like:

Cory Foy
12345 Developers Way
Columbia, MO 12345


So what is the test you should write? How about:

[Test]
public void printAddressSpansThreeLinesWhenOneAddressLine()
{
  string expected = "Cory Foy\r\n12345 Developers Way\r\nColumbia, MO 12345";
  Assert.AreEqual(expected, customer.printAddress());
}


or maybe:

[Test]
public void printAddressSpansThreeLinesWhenOneAddressLine()
{
  string expected = @"Cory Foy
12345 Developers Way
Columbia, MO 12345";
  Assert.AreEqual(expected, customer.printAddress());
}


The problem is that while both of the above styles are valid C# syntax, they will both fail - on Linux.

"Linux?!", you gasp!

Yes. There really is quite a push with Mono to get a lot of C# apps running on Linux. The problem is that if you rely on a newline being "\r\n" as it is on Windows, your apps aren't portable for no other reason then you didn't know about the difference or didn't want to bother with it.

The correct solution, which is cross platform and really not that difficult, is:

[Test]
public void printAddressSpansThreeLinesWhenOneAddressLine()
{
  string expected = "Cory Foy" + System.Environment.NewLine
    + "12345 Developers Way" + System.Environment.NewLine
    + "Columbia, MO 12345";
  Assert.AreEqual(expected, customer.printAddress());
}


The same applies for path separators. On Windows, it is ";". On Linux, it is ":". And, just like NewLine, Microsoft has a System.IO.Path.PathSeparator. They also have a System.IO.Path.DirectorySeparatorChar for directory structures.

The tools are there, and not terribly difficult to use. Give it a try and help make your app cross-platform.

St. Louis Code Camp!

Brian Button officially announced the St. Louis Code Camp coming up May 6th and 7th. I know Brian has worked hard to bring it here. I spoke at the Charlotte one, and had great fun. It isn't often you get to go directly into a Microsoft campus and talk about open source tools, and even Java and Ruby, but that's exactly what happens here.

Brian is looking for Speakers and Volunteers, so if you are interested be sure to get a hold of him.

Tuesday, March 14, 2006

Speaking at the Mid Missouri XP User's Group

CARFAX's own Gary Brown has gotten together a group of XP enthusiasts to form the Mid-Missouri XP User's Group. The first public meeting is tonight at the CARFAX offices in Columbia, MO. Several people who attended the NFJS Conference in St. Louis, myself included, will be doing a panel discussion on various topics, including the latest from the Java world and Ruby.

It looks to be a great time, and hope anyone in the area can make it out. Here was the official annoucement:

The March 2006 meeting of the Mid Missouri XP User Group will be held on Tuesday, March 14, 6:00 - 8:00PM, at the CARFAX office in Columbia. Pizza, salad, and pop will be served.

This month, several CARFAX employees attended the No Fluff - Just Stuff conference in St. Louis. They returned full of enthusiasm about the new technologies and techniques that they learned about at the conference.

For our program this month, Steven Asher, James Carr, Cory Foy, Jami Fulton, and Chris Sage will lead a panel discussion about their experiences at NFJS. They will discuss many new technologies and techniques that should be on everyone's radar screen.

Please RSVP by noon on 3/14, so we can order the appropriate amount of food.

See you there,

Gary Brown
CARFAX XP Coach
(573) 356-7581

CARFAX, Inc.
2301 Maguire Blvd
Columbia, MO 65201

Tuesday, March 07, 2006

Schema Spy number 54 on SourceForge!

John Currier, a former CharJUGger, released a tool a while back called Schema Spy. If you haven't seen it, you owe it to yourself to check it out. It generates graphical dependency diagrams of your database, including things like implied constraints between tables.

Anyway, he sent a post over to the CharJUG mailing list saying that he was trying to figure out why he was getting so many hits to it, and then realized it was listed on the front page of SourceForge, and was ranked #54 out of 114,000 or so project!

Congrats John, and check out Schema Spy!

Monday, March 06, 2006

NFJS Conference Day 3 and Wrap Up

What a whirlwind weekend. I wasn't sure how I was going to fit any more information in today, but somehow I managed to. I decided to get some more Java in today, and play with some more tools I hadn't played with yet. I can't stress enough how great this conference was, and they are on a national tour, so try to get in when they come by you.

Without further ado, day 3...

The State of AOP


Aspect-Oriented programming is one of those things that I've heard lots about, read lots about, and just haven't played with. Ramnivas Laddad, the author of AspectJ in Action, was giving the talk, so I jumped in. And it was a good session. Ramnivas gave some good examples, outside of even logging, and showed how to use AspectJ with 1.4, and then using annotations with 1.5.

However, I couldn't help but feel that Aspects in Java are some nasty hack put in to work around limitations of the language. Well, a well done nasty hack anyway. It was actually good to see the use of annotations both here and from the Tapestry session one of my coworkers attended.

Table-Driven Acceptance Testing


I had met Mario Aquino on Saturday, and was interested to hear their viewpoint on FIT, which is what this talk was really about. We use Fitnesse almost exclusively, and other than Excel, I'm still not sure why people would create HTML tables manually. However, Mario had done some interesting things around DoFixtures, and it was an interesting demo. Especially the part where he used Jemmy to talk to his Swing App and drive it. We also talked about maybe driving Selenium in the driven mode using Fitnesse to test web apps.

While that may seem like overkill, it really is nice to be able to have your JUnit tests, and then all of your others controlled with Fitnesse. I'm glad Ward doesn't read this - he'd probably throw a monitor at me or something. ;)

Pragmatic Tracer Bullets


In my opinion, Jared Richardson's Pragmatic Tracer Bullet talks was one of the best of the day, and one of the most controversial in our organization. Jared (the author of Ship It!) proposes a "tracer-bullet" process for starting a new project.

What is the tracer-bullet? First, you take the requirements and define your System Objects, which should be coarse enough to be able to be deployed seperately on different machines. Next, you propose the interfaces between the objects, connect them using stubs and canned data, add functionality, and then refactor, refine, and repeat.

The problem? Well, it seems like a lot of people think of this process as Big Design Up Front - the antithesis of XP. However, I don't think that is what Jared was trying to get across at all. I actually felt he was proposing to do the simplest thing possible, except with a little planning ahead of the game. And, unless I have been duped by multiple spoof emails from Mr. Jeffries on the XP list, XP allows this. In fact, it encourages it. It just doesn't encourage:

  • Item 218.4.c.ii.1: The first character of the password may be of the set [a-zA-Z1-9]

  • Item 218.4.c.ii.2: The second character of the password may be of the set [a-zA-Z1-9]

  • Item 218.4.c.ii.3: The third character of the password may be of the set [a-zA-Z1-9]


Ugh.

Anyway, now that I've talked to some people, I think the issue is the terminology of all things. When someone says, "To build a system, first come up with the system objects, then build the interfaces between them, then start building them", well, I guess they could be confused.

But even when I explained the full concepts (System Objects are tiers like Client/Server/Data Access/Database, interfaces are how we anticipate the layers talking to one another), it was still a stumbling point.

But I think Jared got it right. When we get a requirement in for an app, the first shot at the tiers are usually obvious. For example, if I get a request for an app where a user can go to a web page, enter some information, get a response back (which records the request for billing), I know I have the following tiers:

Client -> Server -> Data Layer -> Database

And I know the interfaces might look like:
  • Client -> Server

    • Login(username, password);
    • GetDataForRequest(request);

  • Server -> Data Layer

    • RetrieveDataForRequest(request);
    • RecordRequestAttempt(req, user)



And so on. But, in a small shop where these layers might be the responsibility of a handful of people for all, breaking out from the beginning, because there is no way to work in parallel on the layers - you're small and serialized. But in a large shop, it very well might make sense.

Ruby Tools


Ok, enough about that. The last session was Mark Volkmann giving a rapid fire tour of various Ruby tools for editing, building and interacting with objects in Ruby. Perhaps the most interesting part was when he wrote a C++ file, compiled it, used SWIG to generate a wrapper, built an .so, and then called it from Ruby as if it were a normal Ruby object. As easy as he made it look, I was quite impressed.



All in all, I had a wonderful time, and thanks to Jay Zimmerman and the whole NFJS crew for their hard work in bringing this to the area (and many others). We have a lot of people who learned a heck of a lot in such a short time, and who are excited about the various tools available to them in Ruby and Java.

Saturday, March 04, 2006

No Fluff Just Stuff Conference - Day 2 - The Debauchery continues...

As I expected, today was just as intense as yesterday, except longer. Some great sessions, and great information. I found out a fellow Missouri blogger - Duane Keys is around here, though I don't think I've run into him. Hopefully next time we can get the name badges to be a little bigger - at least in the name/company part. ;)

However, it was also tough. There were a lot of great sessions, and it was hard to choose. A lot of Java, a lot of Ruby, and a lot of AJAX. So what does one do?

Facets of Ruby


One starts with Ruby from a master. The session was actually entitled "Ruby for Java Programmers" and was quite fun. Not just because Dave is a great speaker. But because of the gasps I heard from the audience when he demo'd ActiveRecord and with, oh, no code, persisted his objects to the Database.

But, one can't just start with that. In fact, he acknowledged from the beginning that language selection was in some cases a religion, and that he wasn't going to convert anyone to Ruby just by talking about it. He started with a simple code sample of the Fibonacci sequence:

def fib_up_to(max)
  f1, f2 = 1, 1
  while f1 <= max
    puts f1
    f1, f2 = f2, f1+f2
  end
end

fib_up_to(1000)


And asked a simple question. What's missing? Surprisingly, the first one was curly braces. And then parenthesis around the while. And then finally someone got to the "And it doesn't have a type!". To which Dave replied, that "Ruby doesn't have types. Should we have this fight now or later?".

He then went on to explain why he doesn't think that's such a big deal, and then went on even further to show why it's an advantage. Yes, there are bad things about not having static typing (optimization, autocomplete IDEs, etc), but the power you get from Dynamic Typing outweighs that.

He also touched on Open methods and classes. He wanted to be able to say:

"cat".encrypt

instead of the Java Encryption.encrypt("cat");. The problem? The string object doesn't know anything about the method encrypt, sooo...

class String
def encrypt
  "cat".reverse
end
end


Ok, he actually used a method to do a simple letter substituition, but the same principle holds that he just redefined the String class to have an encrypt method. And he said that people often say to him, "But Daaaave! How could you use a language with open methods and objects?" His answer: "Because most language assume you are stupid". He then went on to a secret way to ensure that a developer didn't go in and redefine the + method in FixNum. I can't reveal it here, but I can say it involved a parking deck, Home Depot and a length of rubber hose.

Politics of Persistance


This talk by Bruce Tate seemed highly interesting. And in fact, it was for me. We discussed in an open-type format about various persistance frameworks, and what the state of the politics between them are. For example, I knew that Oracle was trying to buy JBoss, and also knew that Gavin King had gone to JBoss. I didn't know that BEA had acquired Patrick Linskey's company SolarMetric, and somehow that put a different spin on things for me (like maybe Oracle is really just trying to get Gaving since BEA has Patrick, and so they'll just take JBoss while they are at it). All in all it was good, and I think we'll take a closer look at the Spring JDBC and iBatis next week.

Rails and Ajax


This was very cool. I've heard a lot about Ajax, and seen it used (Google Maps I love you!), and used well. I had no idea that the tools for it were so darn good. Looking at the Prototype.js framework and the stuff from http://script.aculo.us I was blown away by the cool stuff you could do with fade effects. And then tying that into Rails and watching how easily it gracefully degraded with Javascript turned off was awesome. Dave also mentioned that Rails 1.1 is on the verge of release, and they will be adding a new RJS (Ruby Javascript) which you can use in place of a rhtml template.

The quote of the day came from this session when Dave called browsers "3270s that display porn". Priceless.

Building Domain Languages Atop Java


Somehow I realized that I hadn't attended any topics from Neal Ford, and this one looked great. And it delivered. He covered the concept of Domain Specific Languages, and in particular Language Oriented Programming, coined by Martin Fowler. What is it? An attempt to move towards a programming language or abstraction closer to the domain problem.

And what the heck does that mean? Let's say you are keeping an exercise log (the example he gave). Would you rather type in:

public class ExerciseLog {
  public static void Main(string[] args) {
    new ExerciseLog().load();
  }

  public void load() {
    FebruaryLog.add(
      new Swim()
      .onDate("2/01/2005")
      .forDistance(1250)
      .report();
  }
}


or

swim on WED for 2150
run on TUE for 6.5
bike on SAT for 50
summary


Both of these are examples of domain specific languages, and depending on your target audience one might be just as appropriate as another. He then went on to touch on some tools for LOP and DSLs, including Antlr and the GOLD Parser Builder. It was really fascinating, and I think I will be able to use some of this real soon.

Client / Server Birds of a Feather


For the last session, Neal Ford and Scott Delap held a BOF on Client/Server. We got into some good discussions about MVP versus MVC, Tapestry, Macromedia Flex, EJBs and the pain of Java deployment. Scott then asked everyone who was considering using EJB 3.0 when, and I'm not making this up, all the lights in the room went out.

So, we decided to call it quits earlier and parted ways.

Dinner


Finally, Jay Zimmerman had invited me to the speaker's dinner which was a great opportunity to talk with some of the other speakers. It somehow annoys me to no end that a lot of these guys are from Raleigh, and I didn't meet them until I moved to Missouri.

We headed over to an Asian Grill type place, and had good discussion on coding, teaching, and living (and when it was appropriate to TP someone's house that is for sale). We then were treated to a mini Nascar race between the grill and the airport to get Justin Gehtland out on time.

Tomorrow is going to be some good sessions on AOP, another technology I've kind of been overlooking, and then I get to head back to Columbia.

(As a side note, I got an email today that Charlotte, NC now has it's very own Ruby User's Group! Be sure to stop in an support those guys!)

Friday, March 03, 2006

NFJS Conference - Day 1

In a day that starts with being told to stink less and earlier, and ending in dinner with Dave Thomas, Bruce Tate, Justin Gehtland and a host of people from the St. Louis Ruby group, it's amazing that so much was packed into just a half a day. Here's what you missed by not coming to the 4th Gateway No Fluff Just Stuff conference (or, if you did, what you missed by not stalking me around).

Registration


The day started with finally running into Jay Zimmerman, the guy whose hard work makes these conferences possible. Jay has been trying to get an NFJS conference in Charlotte (Which, if that's where you are, I suggest looking at that conference, especially if you are into AJAX), and it figures that he finally gets it there the year I move to Missouri.

Where Agile Meets Argyle


After registration, I wandered over to "Where Agile meets Argyle" by Bruce Tate. We've all worked at companies where practices and processes are wielded by business people. But, to sell agile, you can't just go up to them and say, "Hey! Let's do this *EXTREME* Programming paradigm where we don't do any documentation, we pair program, and we write gobs of test code for each line of real code we write!"

In fact, you need to drop the notion that the language you use to describe your ideas is sacred, and just hold the ideas themselves sacred. This means maybe saying something like, "Hey! We've been reviewing some of our development processes in order to see how we can improve them for the business. We think by increation collaboration, focusing on the crucial artifacts, and ensuring that the code we produce works as the customers expect we can increase the quality and decrease the time-to-market for our products". What non-technical manager wouldn't spin around on that?

Besides that, he touched on some other good points:
  • Emphasize: Small, smart teams. Simple Requirement management. Simplicity. Refactoring. Automatic Unit Testing, and good feedback from customers

  • Since developer estimations stink, let's shoot for a goal to stink less and stink earlier in the cycle

  • If a customer isn't interested in a relationship, or doesn't see the point in the demo, find something that they can't do today and deliver it to them early anyway to get them excited about the project

  • When removing some aspect of discipline from an Argyle process (say, extensive documentation) ensure that some matching form of discipline is added to the agile (say, extensive unit tests)

  • If your customer wants lots of or specific documentation, can you possible get a tool that generates it for you?

  • Requirements should be your only currency


One additional thought I had during it, that I will expand upon in another post, is that business people always seem to want to see the people behind the curtain doing the real work. Why don't we as developers ever want the same?

Spring Dependency Injection


After a quick break, I headed over to Justin Gehtland's talk on Spring Dependency Injection. I've played some with Spring.NET, but hadn't gotten much into the Java version. He touched on a key point, and that is how developers end up with tightly coupled code. It's through:
  • Concrete Classes

  • Calls to new (!)

  • Checked Exceptions

  • Contructors


It was fun to see the reaction to the "Calls to new" point. But it's true - time after time the advice is to write to contracts (interfaces), especially at flex-points, but it isn't done often enough. In addition to interfaces, you reduce tight coupling through:
  • Interfaces

  • Inversion of Control (IOC)

  • Unchecked Exceptions

  • Bean Properties and Configuration files


And, of course, Spring can help with this. I found it interesting that Spring can use XML files and Property files, but also Groovy, Java, Python and Ruby scripts to define the configurations.

However, Spring 2.0 is coming soon, and is adding some nifty new features, so be on the lookout for that.

Herding Racehorses and Racing Sheep


Finally we headed over to the Dave Thomas talk on Herding Racehorses and Racing Sheep. However, Dave's plane was late, so Bruce Tate stood up, declared himself to be Dave Thomas, and promptly did a jig. Ok, not quite, but he did do a good job of stalling until Dave did arrive.

Dave's talk was, of course, fascinating. He stressed People Improvement over Process Improvement since, after all, the people are the ones implementing the process. He then talked more in depth about the Dreyfus Model which Andy Hunt touched on when he came to the Charlotte JUG, but I found utterly fascinating still.

Finally, he touched on what he coined an "Experience Portfolio" and how we should apply common Financial Management concepts to it. For example, diversify by learning a new language every 3-12 months. Set a plan for your end goal, and constantly review it to see if you are on target, remembering that a plan is a plan - not a map.

Dinner


Finally, I made it over to the St. Louis Ruby User Group's dinner. I was quite glad to meet them - I've talked with several people on the mailing list, and it was quite nice to put faces to names. Dave, Bruce and Justin (and Neal Ford!) joined us, and much debuachery ensued. Well, at least some really good discussion over a decent little meal (even if it was a bit Ruby-centric ;))

With two more days to go, and some very difficult sessions to choose from, I am excited to be here. Hope you get to come to one soon as well.