CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

November 2006 - Posts

  • Wanna Review Jim Shore's " The Art of Agile Development ?"

    Jim Shore is writing a new book entitled "The Art of Agile Development" for release next year from O'Reilly.  In his words:

    My co-author and I are looking for reviewers that are in our target 
    audience: smart, capable, and curious (but perhaps skeptical) about agile 
    development.  They may be in an agile project now, considering it for 
    the future, or being asked to investigate whether it's a good idea.

    Review sections of the book and a mailing list for comments are available at: 

    http://www.jamesshore.com/Agile-Book/
     

    If you're interested at all in Agile development, participating in this book review is going to be a great way to learn the in's and out's of applying Agile practices to real world situations from one of the best.  Jim Shore is one of the guys I want to be like when I grow up, so I'm definitely looking forward to the book.

  • You said 'Should!'

    I worked with a great developer one time that thought the word "should" was a dirty word.  As in:

    • Me:  "It should work as is"
    • Him:  "You said 'Should!'"

    You'll have to make my word for it that the way *he* said it was funny.

    The point being is that the phrase "it should work" is close to worthless, and borderline dangerous.  You're either sure something will work because you've tested all of the plausible possibilities that you know of, or you don't know something will work.  I've found myself repeating that phrase quite a bit the last couple of weeks as "it should be easy" turns into day long tasks or biggish stack traces.

  • Bill Gates for President -- Think about It (OT)

    Can you imagine unleashing an Arch-Developer on the world as US president?  Don't you think just a bit of that "people skills" stuff is kinda necessary?  At least enough to be able to look in the eyes of a dictator and see that he's an authoritarian tyrant instead of whatever GWB sees? 

    http://dilbertblog.typepad.com/the_dilbert_blog/2006/11/bill_gates_for_.html

  • The Difference Between Big and Small Companies

    Roughly speaking, the first half of my software development career was spent in, or consulting for, Fortune 100 companies.  The last couple years I've been working in mostly small companies.  Here, in a nutshell, is how I see the difference between the two basic environments:

    In a big company it's often hard to figure out who knows the answers to the questions you have.

    In a small company, it's obvious who has the answers to the questions you have, but they're too busy on 5 other projects to help you.

     

     

  • I don't have time to sharpen the saw, I'm too busy chopping wood!

    Title by Steve Donie, my former colleague and sensei for all things related to Continuous Integration and Configuration Management. 

    I'm suggesting to my client that they need to invest in some CI infrastructure for the remainder of their code.  They're all in favor, and they want to do it, but it's not a priority because the have "too much sh**" to do.  That's understandable, but it's a self-defeating attitude.  In my client's case, I think a little CI with some smoke tests may be low-hanging fruit.

    Granted I've got a lot of CI experience by now, but I really don't think it should take you more than a couple of man days to set up CruiseControl.Net or something similar.  Compare that to the potential loss of time resulting from, for example, a new JAXB mapping gets checked in that breaks a service downstream or database schema changes not getting propagated to all of the development and testing database installations.  How much manpower is lost because of those problems?  Those very problems can be stopped in their tracks by a good CI infrastructure and philosophy (meaning that somebody has to watch the builds and care when they are broken).

    Developers aren't omniscient (sorry).  You can minimize the pain through good coding structure, but changing existing code always presents the opportunity to break something else.  That something else might not be detectable from mere code inspection.  It's a good, good thing to have the CI safety net to detect problems automatically. 

    Automate anything that moves!  Any code, or configuration, or database change that happens repeatedly with anything resembling regularity should be automated.  When you're tallying up the cost versus benefit of writing Ant/NAnt/Rake scripts, you absolutely must include the cost of productivity due to screwing up manual activities.  When you do that, you might just put a little more value into the build automation. 

    Granted, a nightly/daily build beats nothing hands down.  That being said, the great advantage of full blown CI, with the philosophy of checking in code often, is creating a record of causality between a build breaking and the new code that broke it.  Small frequent check in's both lessen the chance of breaking a build by making smaller changes at any one time and ease the burden of diagnosing build or code problems by immediately pointing to the last check in (readily available on the CruiseControl.Net build page).

    A lot of the blame has to fall on management's shoulders (and I'm not thinking of anybody in specific here), because they often don't understand or believe the opportunity to go faster by tightening up build or test automation.  I don't know how you get around the "management won't let me do the smart thing" issue.  The best I can say is to do the things that will make you faster when you need them and not even tell management.  As long as you really are making yourself faster, and that's the rub, you should come out ahead.  If things are bad, just buckling down to work harder probably isn't going to help matters.
     

     

     

  • Interacting with a Strange Database

    I relearned a couple of lessons today about working with database intensive applications.  Fortunately, I was merely writing test automation code and I caught my problems fairly quickly, but...

    • You should get the System DateTime.Now in a consistent manner.  It's either assigned by the database clock or the application server clock (assuming a cluster is synchronized somehow), but never both.  I got burned for a little while today because my system clock is apparently a few moments behind the database clock.
    • Don't play with strange databases.  If you're using a legacy database schema for the first time, assume nothing.  Treat them like a poisonous snake that needs to be handled with care.  Every legacy database seems to be littered with idiosynchracies just waiting to jump out at you.  That innocuous lookup table may be vital, referential integrity might be lacking, and there could be triggers lurking under the water waiting to take a bite out of developers swimming nearby.  I swear, and I know somebody is going to argue with me here, that the fastest way to make your code completely unmaintainable is putting business logic in triggers.  As much as I detest business logic in sproc's, at least you can generally see the flow of the code. 
    • Integrating through the database is not a good idea.  I've seen a handful of systems that integrate by having the downstream application determine it's workflow by scraping through the audit trail tables of the upstream application.  Everytime, the result is tears and brittle systems.  As an example, I'm thinking of designs where you might poll a table and look for any changes since the last time the polling job executed.
    • While convenient, using database tables to store application metadata can potentially cause you a great deal of friction in setting up the application for testing, especially when you're using a lot of surrogate keys (autonumber or sequence) for the metadata.  A single xml file is easier, and lends itself more readily to being versioned in source control than the corresponding storage in a dozen database tables.  At a bare minimum, have a way to suck in the database configuration from a single file.  If the application is hard to set up, test and build automation becomes very difficult and your velocity will suffer.
  • Getting Started: How often should you check in?

    Yesterday my team was talking about how often the CruiseControl.Net build ran each day.  The question arose, how often should we check in?  For example, our team of four developers creates about 20 successful builds in a full day of coding and I think that sounds all right.  I can't imagine there being a definitive answer, but you should strive to check in every time you hit a stopping point , and come to a stopping point as often as you can.  Much of the point of doing Continuous Integration is to get more feedback from the system and work in smaller steps.  Stopping to do a full check in dance (update from the trunk, run the NAnt script with tests) is a way to verify that your code can be integrated into the trunk with everyone else's new code.  Doing frequent check in's can keep those nasty merge problems away. 

    Some tasks are going to tear up the code for longer periods of time.  If you've got stale code because of one of these Herculean tasks, update your code from the trunk as often as possible to reduce the risk and burden of merging later.  Frequently run the entire suite of unit tests as you work if you're making changes that might ripple out into other areas of the code.

    The key concept for me in all software development activities is rapid feedback, reducing the cycle between doing something and verifying that something.  Frequent check in's ala Continuous Integration are definitely in line with that philosophy. 

    I'm going to assume that we all agree that checking in code that doesn't compile or pass its unit tests is a bad thingBroken Windows and all that stuff.  The unit tests don't provide much value if you ignore them or don't run them.
     

  • Using Anonymous Methods with Control.Invoke()

     

    Just in case I'm the only person that didn't know this, you can't pass an anonymous method as an argument to Control.Invoke() when you're trying to make cross-thread calls.  Instead, you have to wrap it in a Delegate like the MethodInvoker delegate like this code below:

     

       23         public string CurrentActivity

       24         {

       25             get { return _activityStrip.Text; }

       26             set

       27             {

       28                 if (InvokeRequired)

       29                 {

       30                     MethodInvoker invoker = new MethodInvoker(delegate()

       31                                                                   {

       32                                                                       _activityStrip.Text = value;

       33                                                                   });

       34                     Invoke(invoker);

       35                 }

       36                 else

       37                 {

       38                     _activityStrip.Text = value;

       39                 }

       40             }

       41         }

    It's fine and it works, but it's butt ugly.  I'm mildly tempted to try out Boo for this very reason or maybe play with RubyCLR to drive WinForms with a cleaner syntax.

More Posts

Our Sponsors

Free Tech Publications

This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP