in

 

Chad Myers' Blog

Department of Problem Prevention

January 2008 - Posts

  • I don't trust me

    Where I'm Coming From

    HAL 9000 - I can't allow you to do that, Dave.I've learned that, in general, I can't trust humans' judgement, knowledge, or experience when working on software  projects, among other things. I'm not saying that humans are bad, I'm just saying that humans are creatures and subject to mistakes and failure. Quite so, as a matter of fact.

    The past couple years I have worked in predominately old-style software development modes. I have seen success in spite of everything -- in spite of the non-developers on the team, in spite of the politics, in spite of the command/control management, in spite of waterfall-esque project structure. Despite all these things, we were usually able to get something out and help the customer somewhat, but not nearly as effectively as we could have with a highly motivated team, focused on a goal, working towards total success with minimal interference in the creative process known as 'software development'.

    This frustrated me, and it has made clear, in my mind, the value of the processes I preach/endorse and attempt to practice in this environment (occasionally strides are made, but they're hard to sustain).

    Managing Human Weaknesses

    Ultimately, what I've come to realize is that software development is really all about the people. With good people and processes that enable them to work effectively, you will have success to one degree or another (usually a good degree). So the goal is really to make sure that everyone on the team (including non-developers) are properly motivated and share the goal of the project. If not, they shouldn't be on the team, or the project manager (or similar role) needs to work with that person and persuade them to cooperate (find out why they're not cooperating and work with them to resolve the issues).  Once you have a good team with everyone interested in accomplishing the goal, the next task is to try to implement processes to appeal to their higher nature and set them up for success rather than crush them with threat of looming failure.

    There are many processes out there, and I have found the following to be very effective in my own practice, and through observing other teams who have been practicing them.  The only failures I have seen is when the team is not properly motivated, has conflicting goals, or there are personality issues that are not properly managed by the manager.

    These processes (detailed below), can be summed up with this statement: 

    Setting Yourself up for Success

    I don't trust the customer

    I don't trust the customer or the target consumer for the software we're building. I don't trust them to know thoroughly what their problem is. I don't trust them to be able to communicate effectively to me what picture of a solution they have in their mind. I don't trust them to be able to know, beforehand, everything that they would need to have their problem solved to complete satisfaction. They will change their mind, remember things they missed mid-way through the project, remember that what they asked for earlier on was wrong and needs corrected, etc.

    So we put in processes to help achieve better, more structured communication -- but not too much, and the kind of structure that facilitates dialogue and interaction versus lengthy 500 page Word documents.  We talk with the customer more often (every few weeks) and show them what we've got so far to help them coalesce in their mind what it is we're all trying to accomplish and what steps we need to take to finally accomplish it.  Finally, we (the team) hold ourselves accountable by keeping tabs on what we understood from the customer, what we promised them, and how long we said it would take us to accomplish it.  We help achieve better accuracy by promising smaller things and promising them more often since more promises over longer periods of time virtually guarantees failure.

    I don't trust the team, in general

    I don't trust the team, in general (including myself). So we have daily stand-up meetings to keep each other apprised of our situations and to keep tabs on any problems that may be brewing. It's also a chance to allow the manager to get a feel for what roadblocks are hampering development (including non-technical ones like personnel issues).

    I don't trust the team (including myself) to deliver on what we promise, so we break promises into more manageable chunks and estimate them the best we can. After the chunks are done, we review our promises and estimates and grade ourselves on how well we did. We use this information to get better at promising and estimating in the future, and also to help us plan how close we are to being 'finished' based on our accuracy.

    I don't trust the developers

    I don't trust the developers (including myself). I don't trust the developers (including myself) to:

    • make sure they don't lose their work
    • not overwrite each other's work.
    • not make changes that break the build and cause a work stoppage among the developers.
    • be able to manage the complexity of building new software while maintaining an existing, production branch of the software.

    So I use source control/revision control/version control (whatever you want to call it).  I, personally, have found Subversion to be most effective at addressing all of these problems, but there are other similar products that are also effective. I have found the Microsoft Visual SourceSafe product to be inadequate at addressing all of the above concerns. I would recommend not using Microsoft VSS for a team development project like I have been describing.

    I don't trust the developers, including myself, to write code:

    • that, first and foremost, accomplishes the acceptance criteria
    • that is well tested and has good code coverage (where 'good' is subjective and relative)
    • that works as expected with all the other code in the system
    • that is acceptable to the coding standards/policies we have set as a team
    • that doesn't break the build and cause work stoppage among all the other developers
    • that works on a system that is not a developer workstation (i.e. 'It works on my box!')

    So I use an automated build process with continuous integration. The build process compiles the code on non-developer workstation/server that doesn't have all the developer tools on it (only the bare minimum necessary to compile).  The build process then executes the tests (unit, integration, acceptance, etc) to ensure the fitness and working condition of the software, as well as it's cohesiveness as an entire unit.  The build process then runs code coverage, complexity, and policy analysis to determine whether it is of the quality standards we have set for ourselves as a team.  If any of these steps are not met to our high standards of satisfaction, the build will fail and our Continuous Integration software will alert us to this fact.  Personally, I have used NAnt and MSBuild as the build tool, CruiseControl.NET as the continuous integration software, FXCop as the policy analysis tool, NCover as the code coverage analysis tool.  I have heard good things about Rake and FinalBuilder as build tools and JetBrains' TeamCity as a Continuous Integration server.

    I don't trust me or any other developer, individually

    I don't trust my ability to estimate, so I track my estimation accuracy as the project progresses.  I don't trust my ability to understand the requirements placed before me. So I encourage the customer not to write big long requirements specification, but rather to discuss the requirements with me using conversation starters like User Stories. I get a greater understanding of the problem and the desired solution (including the technical component of that solution) and participate in defining the specification for that requirement WITH the customer.  We then develop the actual specification and codify it in documentation, the code, and any other necessary artifacts (i.e. auditor documentation for later review).

    I don't trust my ability to actually accomplish the requirement, even if I understand it completely.  But I know that I am not likely to ever understand any requirement completely -- or even that the customer himself understands the requirement completely -- so I make sure to design my code such that it can be easily tested, and easily refactored later. I make sure that I don't code too much of my assumptions in one place because it'll be harder to unravel later.  I also write lots of tests that assert my assumptions and understanding of the problem.  I write integration tests to ensure that the code I write works well within the entire system (and not just the specific unit in which I'm working). I write acceptance tests at a higher level that serve as a customer-driven sanity check of my code which isn't concerned with how the code is implemented as much as the end result of it's function (i.e. when I say 'debit from account', it really debits from the account).

    I don't trust our tests

    I don't trust my testing discipline enough to ensure that I will achieve acceptable coverage of the code unit and cover all the edge cases and any other important scenario worth testing. I don't trust my discipline to avoid writing a bunch of code that isn't directly necessary to accomplishing the requirement. I don't trust myself that I won't go code happy and write a bunch of unnecessary code just for the pure joy of writing 'cool code'.

    So I write my tests first. I write the tests first while I'm fresh and not burnt out on writing code. I write the tests to get some of the non-interesting, non-cool stuff out of the way first.  I do this to ensure that when I get to the 'fun' coding, I can feel comfortable knowing that I've boxed my creativity and directed it into the areas I want it to go and will provide the most value for the client.  Now I don't have the dark specter of having to come back and test my code after-the-fact which is not very enjoyable.  I also know that my code is inherently more testable because it was written to be testable in the first place and necessarily must be so. Even when trying to write code with tests in mind, I have found that I can never quite do it 100% and, when writing the tests afterwards, I end up having to refactor the main code a little to get it to work right with the tests. So writing test makes my life a lot easier. It also helps me ensure that I've met all the requirements and achieved quality up front instead of afterwards.

    Even after all that, I still don't trust my tests

    Doing the tests first, up-front helps a lot, but it still requires some discipline and creativity to come up with test scenarios. The temptation is to take it easy and not test every case you can think of. Or maybe one day you're tired, after a big lunch, and you just don't feel like it. The project will suffer.

    So, I pair with another developer. We keep each other honest. We work in a friendly, but adversarial/competitive mode where we write tests for the other developer and ask them to implement the code to pass the test. This keeps things interesting and adds some incentive to write good tests as well as good code.

    Finally, I don't trust the testers or the code release itself

    I don't trust the testers to test everything they should properly. I don't trust that they won't also fall into human nature and not test everything every time.  So I work with them to automate things to the maximum extent possible and give them the tools they need to set themselves up for success like we have on the development side.  Monkey testing (banging on the keyboard or mouse) is tedious and soul-sucking. Few people in this world enjoy it.  So, we try to minimize monkey testing and, instead, give the testers tools to automate things and add in their own test cases into the automated suite.  Then, they only have to monkey test as a last resort for some very specific, complicated case. These are usually somewhat interesting to set up and discover (but not always), so it helps to keep the testers focused and interested.

    Once the testers are done and the software is ready for release, I still don't trust that it's ready or that any human involved at this point won't introduce a problem at the last minute. So I make sure that releases are automated and I test this release process with the testers and other team members so we can trust the automated release packaging system.  For this, I usually use NAnt or MSBuild to automate the final packaging of the build, the documentation, licenses, or any other 'final build' type tasks that need to be done. I try to avoid doing anything after the testers, but, at least in my cases, I have never been able to avoid having to do SOMETHING to gather up the final package for pressing onto a CD or pushing out to a download server and sending out notifications to customers.

  • Austin TDD CodingDojo Full!

    We actually didn't get the form shut down in time and a few overflow's slipped in, so it's gonna be a little cramped.  I'm betting that a few people will be no-shows (stuff comes up, hey, what can you do, right?) so I'm sure it'll work out alright in the end. Ray Houston and I have come up with a dev scenario for the dojo that will actually contribute something to the world and help kids learn, how 'bout that, huh?

    Anyhow, if you're still interested in coming and didn't get a chance to sign up, drop one of us a line and let us know and maybe we can work something out. We're sincerely hoping (actually, terrified) that this will go well and we'll want to do it again. Or maybe someone else will step up and facilitate it the next time and that can be a trend, who knows?

    Thank you everyone who's helped us and helped get everything together and shared ideas, support and well-wishes. We look forward to having a great session and learning a lot about not just TDD, but coding styles and micro design as well.

  • 101 Great Computer Programming Quotes

    (Found via DotNetKicks -- please kick it there, don't kick this post)

    Link: http://www.devtopics.com/101-great-computer-programming-quotes/

    Some of my faves:

    “There are only two industries that refer to their customers as ‘users’.”
    (Edward Tufte)

    “Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots.  So far the Universe is winning.”
    (Rich Cook)

    “No matter how slick the demo is in rehearsal, when you do it in front of a live audience, the probability of a flawless presentation is inversely proportional to the number of people watching, raised to the power of the amount of money involved.”
    (Mark Gibbs)

    “The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry.”
    (Henry Petroski)

    “I’ve noticed lately that the paranoid fear of computers becoming intelligent and taking over the world has almost entirely disappeared from the common culture.  Near as I can tell, this coincides with the release of MS-DOS.”
    (Larry DeLuca)

    “There’s an old story about the person who wished his computer were as easy to use as his telephone.  That wish has come true, since I no longer know how to use my telephone.”
    (Bjarne Stroustrup)

    “Complexity kills.  It sucks the life out of developers, it makes products difficult to plan, build and test, it introduces security challenges, and it causes end-user and administrator frustration.”
    (Ray Ozzie)

    I never thought I'd quote ESR, but this captures a lot of the way I feel about the art and craft of software development:

    “Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter.”
    (Eric Raymond)

    And I found this one particularly insightful. I have found, by experience (not by ivory tower!) that using Agile methodologies (in part or in whole), helps to solve or mitigate this issue:

    “The trouble with programmers is that you can never tell what a programmer is doing until it’s too late.”
    (Seymour Cray)

    Man, these are just gold, I could go on and on, but instead I'll leave you with this final thought:

    “First, solve the problem. Then, write the code.”
    (John Johnson)

  • The truth which makes waterfall advocates go blind

    Frans Bouma recently posted a post to his blog pointing out some of his frustration with the various ALT.NET communities (specifically mailing lists).   As I understand it, his primary argument was that there wasn't much academic thinking and citations behind some of the positions and postulations people have voiced on the list. While I certainly appreciate his (and am guilty of it) and agree that there's a less citation and academic backup behind some of the ideas than there should be.  Part of this is simply because the CS academic community is behind the commercial world in some areas, and the commercial software development world generally doesn't produce a lot of academic-quality research papers sufficient for the level of citation Frans appears to be demanding.

    But aside from that, I have a particular beef with Frans over his position on Waterfall. He has, on several occasions, asserted that there are specific situations where the waterfall methodology makes sense and/or is even preferred -- even necessary. He used a specific contrived example of MRI (Magnetic Resonance Imaging) machines and the software that runs them.  This is essentially an argument that mission-critical, life-critical machines MUST or SHOULD be developed using Waterfall.  I'm not sure I agree with this and the two seem to be separate, if not mutually exclusive.So, in order to elevate the discussion using Frans' suggestion, I did some research to try to find how and what methodologies are used for mission- or life-critical systems such as medical machines, military combat command and control systems, etc.

    Case Example: QinetiQ

    I stumbled upon this press release from a company called QinetiQ announcing an MRI software deal with Mayo Clinic in Minnesota (a world-renowned top-notch medical facility).  It turns out that QinetiQ also builds other life-critical systems including Hyperbaric Oxygen Wound Healing chambers and, perhaps more interesting, battlefield tactical management and human integration systems. They have a product named (and I love this name): SMITE - Systems Management In Tactical Environments.

    (screen shot from QinetiQ's SMITE application)

    Software Methodologies in C2 Systems

    Ok, so we've established that QinetiQ is doing some pretty heavy life-and-death critical stuff. So, if Frans is right, they are most likely using some form of Waterfall Methodology, because it's the only one reliable enough to guarantee critical software reliability, right?

    Imagine my surprise when I saw this PDF whitepaper that QinetiQ's UK office prepared for the 8th ICCRTS Command and Control Research Technology Symposium, and indexed by the U.S. Department of Defense's Scientific and Technical Information Network (suggesting the world's largest military apparatus is interested in this information). The PDF walks through various popular software methodologies including Waterfall, V-Model, SSADM, and a pragmatic, quasi-Agile "Rapid Application Development" methodology (they call it). They weigh the plusses and minuses of the various methodologies and essentially eliminate them one by one.  Of particular interest, here is an excerpt where they argue that Waterfall will not work for critical "C2" (command & control) systems:

    The waterfall model was based on a number of assumptions:  

    • that all its stages could be completed in sequence
    • that the costs and benefits of an information system could be calculated in
      advance
    • that users knew what they wanted
    • that the work needed was known and could be measured
    • that programs once written could be altered
    • that the right answer could be produced first time

    For the development of C2 systems, none of these have been shown to be true. C2
    systems have proved difficult to manage because of at least two major problems
    which cannot be dealt with by traditional management methods. These are (Grindley,
    1993):

    • the difficulty of stating what is required
    • the difficulty of measuring pioneering work

    The traditional life cycle approach effectively ignores these issues and developers
    have been forced to consider other methods to overcome these problems. One solution
    is to integrate prototyping into the user and system requirement processes.

    It's Scientific Frans, Waterfall Doesn't Work; All Non-Agile Projects Eventually Devolve into Necessary Sub-Standard Agile

    Now, granted, this is only one white paper (which cites the book "Managing IT at Board Level: The Hidden Agenda Exposed"), but I'm quite sure that given a few more days, I could come up with quite a few more examples.

    Frans, I respect you greatly and you're a very smart guy, but I defy you to show me quantitative proof that Waterfall has led to the success of anything after the 1950's, rather than projects succeeding in spite of the Waterfall process they started using.

    It has been my anecdotal experience that all projects that aren't specifically attempting to do Agile will eventually end up there out of force of necessity, but they will do it too late and without proper methodology, thus jeopardizing the project itself, or the moral of the talent on the team.

    Agile, at its most basic, it concerned with managing the main, unavoidable (whatever your Waterfall books may say) constant in all projects: You (anyone) simply cannot know everything that will need to be done in order to call the project 'Done'. Done is something that is eventually discovered, no matter how good the planning, experience, and knowledge of the problem is up front.

  • What would an Apple gaming console look like?

    While pondering my navel, it occurred to me that there is a potential GUI-heavy lickable touchable poke-able consumer electronic device that Apple has not yet touched: Gaming Consoles.

    What would an Apple iGameStation look like?  What would the iController and the iCartridge (or iDVD?) look like?  What kind of iGames would you iPlay on your iGameStation?

    Posted Jan 10 2008, 09:30 PM by chadmyers with 7 comment(s)
    Filed under:
  • Austin TDD CodingDojo Signup

    The details of the Austin TDD CodingDojo event have been finalized and the sign up form is now online.

    Signup (opens in new window):

    http://austintddcodingdojo.wufoo.com/forms/austin-tdd-codingdojo-signup/

    Details:

    Who

    You! We hope to have a good mix of experts and novices and everyone in between. The hope is that everyone will be forced to challenge their practices and ideas and glean insight from the ideas and practices of others. 

    What

    .NET, C# based group coding session in the prescence of peers and to suffer review, criticism and suggestions with the goal of gaining better experience and understand of the practice of Test-Driven Development.  The style will be similar to the 'CodingDojo' (opens in new window).

    When

    Saturday, February 9th, 2008 from 8:00am until 12:00pm.  Optional networking will follow and I'm sure a few people will probably go out to lunch together afterwards to share ideas, reflect, and network.

    Where

    TOPAZ Technologies, Inc. is graciously hosting the venue for us. Thanks!
    Their address is:
    9601 Amberglen Blvd.
    Suite 140, Bldg G
    Austin, TX 78729

    Space is limited to the first 30 registrants.

    Use Google Map or Windows Live Maps for directions

    NOTE: We'll set up in the front training room. Please no food in the training room. There will be a break room where food can be eaten.

    Misc

    We're trying to arrange breakfast tacos and/or doughnuts and there should be refreshments (coffee, tea, cocoa, water). If anyone wishes to help sponsor/contribute to the food and beverage fund, it would be much appreciated.

    For questions, comments, suggestions, gripes, R0l3x or V1/\Gra Spam, please email us: austintddcodingdojo+comments@gmail.com

    Posted Jan 10 2008, 02:07 PM by chadmyers with 3 comment(s)
    Filed under: ,
  • A Challenge to Microsoft, Scott Guthrie

    After reading Ayende's latest post, and having run into few myself just this weekend (see System.Data.SqlClient.MetaType), I'd like to challenge Microsoft's .NET efforts, and particularly Scott Guthrie's group (since I have the most hope of them actually accomplishing this), to release a library/framework/module (something like ASP.NET AJAX, ASP.NET MVC Extensions, etc -- on that scope) with the following statistics:

    • 0% 'internal' keyword usage
    • 0% 'sealed' keyword usage
    • 0% (or very few) 'static' keyword usage
    • 0% (or very few) 'private' methods (only private fields).

    If this functionality is good enough for you, why isn't it good enough for us!

    Also, sometimes you guys make mistakes or do something not very good (we all do, I'm not pointing fingers), and having a most of those methods be 'virtual' would really help so that we can fix things when occasional mistakes occur.

    This would help us folks in the field more than you know!

    Posted Jan 06 2008, 09:35 AM by chadmyers with 13 comment(s)
    Filed under:
  • Working with ActiveRecord model classes outside of the Rails environment

    I had a task yesterday that involved me wanting to dump some information about a Rails ActiveRecord class I had (don't ask, it's a long story).

    I wanted to access my AR class from outside the Rails web environment (i.e. I wanted to type 'ruby something' from the command line).

    I put a file in the scripts folder and put the following code at the top:

    ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
    RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
    require 'rubygems'
    require 'active_record'

    ActiveRecord::Base.establish_connection(YAML::load(File.open('config/database.yml'))[ENV['RAILS_ENV']])

    From here on out, you have the basics of the rails environment and can execute ActiveRecord functionality.

    Posted Jan 06 2008, 08:27 AM by chadmyers with 4 comment(s)
    Filed under: ,
  • What I do (with spoilers)

    Joe Ocampo (a.k.a. AgileJoe, not to be mistaken for his evil cousin, WaterfallJoe) has tagged me for a What I do post.

    I waited a bit because my situation has recently changed and I wanted to cover the new news too when the time was right.

    Current Gig

    I'm currently a consultant for Helpdesk Response, Inc. (or as we call it: HDRI).  We do lots of work for a very large customer. It's all ASP.NET development using 2005 and now 2008 with SQL Server 2000 and 2005.  Our customer has a big contract with Microsoft which basically allows them to use whatever and as much as they want of Microsoft software, so we got to play with some of the less commonly known (and less sexy) packages like Host Integration Services (now part of BizTalk).

    One of the great things about working there is that the time between building a system and it going into maintenance mode was relatively short because there were many smaller projects. The frequency and volume of projects gave me a very wide range of experience and the ability to quickly see how my (poor) design choices resulted in some nightmare maintenance scenarios. 

    The key things I learned from this gig are: Patience, Humility, and Prudence (at least with respect to software development).

    New Gig

    Recently, Jeremy Miller approached me with an opportunity to come work with him at his new gig and I accepted. Starting this Spring, I'll have a chance to work under Jeremy and take my new found humility and add in healthy measures of discipline, design, and teamwork.  I'm really excited about this opportunity not only because I'll be working with Jeremy, but because we'll be using some different technology and practices that I've been meaning to learn over the past few years.  These include: Ruby, FIT/StoryTeller testing, serious agile practice, and many others.

    As far as technology, it looks like we may be using: Mingle, StoryTeller, StructureMap, Ruby on Rails ActiveRecord, Ruby on Rails ActiveRecord Migrations

    Of course, this scares the crap out of me because I haven't used any of these and only have an elementary knowledge of them and I'm sure Jeremy expects me to walk in an expert on these (shh... don't tell him I'm not, ok?).  Looks like I'm in for a serious mind-bending, mind-expanding roller coaster for the next few years.

    I the Name of, I Tag Thee

    I'm curious about what the following people do these days. So, I would like to tag the following people (in no particular order):

    Kevin Miller

    Ray Houston

    Brian Donahue

    Mike Moore (a.k.a. blowmage -- pronounced blow-mahj)

  • Announcing an Austin TDD Randori/CodingDojo Session

    Ray Houston and I will be hosting/facilitating a CodingDojo-style, Randori-style TDD session in early February here in Austin, TX.

    (EDIT: Shoot, I forgot to mention that this idea came from David Laribee and Scott Bellware (no linkage currently available). I'd like to thank them for their ideas and encouragement)

    We have several venues we're currently working out the details with and we'll post more info when we've finalized the location.

    It will likely be Saturday February 2 or Saturday February 9, 2008.

    Our plan is this:

    • Half-day, compressed session (though if there's enough interest, we may go full-day, but that remains to be seen)
    • Building a very simple application focused on accomplishing a few user stories (NOT getting bogged down in the finer points of doing WinForms or WebForms development, we may use ASP.NET MVC, but I'd like to avoid muddying the waters with too much new technology all at once and distracting from the main focus: TDD)
    • Several micro-iterations of design and coding
    • We thinking about having a few more than the recommended 15 folks (like 25-30), but limiting the coding time of people stepping up to code so that you don't get code hogs
    • Rather than a hard-and-fast 5 minute switch time, I was thinking more of a fishbowl/hot-seat style where, if you think you can do better, you hold up a card and take over, but you can only do it once every iteration so that you don't get code hogs

    We're still shaking out all the details and we're open to suggestions/criticisms, etc.

    Please contact Ray or me via our blogs' contact forms or post a comment here if you're interested and/or would like to help in some way.

  • Joining the Donkey Side

    The wonderful folks over at Los Techies invited me to join the list of their notable and venerable bloggers and I humbly accepted.

    If you have subscribed to my Feedburner RSS feed, you should have to do nothing to migrate with me. The new Web URL will be: http://www.lostechies.com/blogs/Chad%5FMyers/

    Posted Jan 04 2008, 07:35 AM by chadmyers with 5 comment(s)
    Filed under:
Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems