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

September 2005 - Posts

  • No More Meeting Hell

    Palermo was joking with me today with a sarcastic "Let's have a meeting today.  I'll find an open conference room and try to find an empty spot on all of our calenders.  How about over lunch on Friday?"  I'm having terrible flashbacks to my Meeting Hell days inside Big Corporate IT.  You wanna know how to kill off meeting hell really quick?  Co-locate the developers and the rest of the team and only put them on one project at a time.  If my team needs to talk, we just talk.  No scheduling hassles, no running around looking for an open meeting room, no "Tetris" Outlook schedules.

  • Agile Project Management is everybody's job

    My team today had a very fruitful, but long, "Planning Game" meeting today to do sizing on our next project release.  I admit it, I don't particularly enjoy the rigamarole around the planning game and the whole iteration planning/close/track your velocity overhead junk.  I got a really bad taste in my mouth from my first XP project because the project manager made the iteration kickoff and retrospective meetings nothing but sheer torture.  It used to really bug me that I had to spend an entire afternoon being pilloried by the project manager for poor team velocity instead of coding (a really good way to improve project velocity).  Later on in the project we had some other personnel come in who had more experience with Agile projects and they helped us straighten out our project management and eliminate much of the misery.  I soon started to understand the value, or possible value, of many of the overhead activities that I had previously blown off.  A couple pieces fell into place in my mind about Agile processes that continue to amaze me to this day.

    1. When applied intelligently a modicum of process can actually be valuable.  Process and discipline doesn't have to automatically equate to "useless document that nobody reads until it's hopelessly out of date."
    2. A project's process goes a lot smoother when the team actively adapts the process to their (changing) situation.
    3. You and I and everyone else on the team is responsible for making the adaptations to the process.  We don't have to be stuck with a stupid unnecessary process.  We can eliminate processes that don't pull their own weight.  We can add processes when we observe a lacking in the way we are working.  Just to head off an obvious objection, you are obviously constrained by what the other teams you interface with are doing. 

    On paper there does not seem to be much process involved with an Agile project compared to heavy document-centric processes, but what is there needs to be followed consistently with something resembling discipline.  One of the cool things about Agile is putting the emphasis back onto people instead of processes.  An essential tenet of Agile thought is that teams are expected to actively and regularly change their process.  It's important on an Agile project to constantly reflect on how you're running the project.  One of the most important lessons for Agile software development I've learned is to pay attention to what you're doing each and every day.

    Another thing to keep in mind is that an Agile process purposely blurs the boundaries between project roles.  My goal on a project isn't just design and coding, the team's goal is to deliver working software that doesn't suck.  With that in mind, I'd urge all of us developers not to blow off the project management stuff in an XP or Scrum project.  Here's a rundown of some of these activities and why and how I think they're important to developers.

    Release Planning (The Planning Game)

    At the beginning of a release cycle, get the team together and review the story list (high level requirements).  The developers will get a chance to provide high level estimates based on the explanations of the requested features.  These high level estimates will be used to generate a rough release plan and maybe a hypothetical iteration list.  In order to estimate the stories the developers have to talk through possible solutions.  Release planning is important because it helps create an expectation of the project completion date.  The value for the developers is that it gives us a chance to start understanding the problem domain of the project and begin to develop a common vocabulary with the business folks.  One of our lessons learned from our first project with my current team was the lack of a release planning effort.  I know that I made some decisions that led to project inefficiency because I didn't completely grasp the sum of the project goals and scope.  From our marathon meeting today I walked away feeling like we had made an important first step towards getting our arms around the new system infrastructure to be built.

    Release Retrospective

    The whole "lessons learned" thing - what worked, what didn't, what should we change.  Take this seriously or you're damned to repeat the same mistakes and never improve.  One of the things I like best about my job is that we actually do make improvements in the way we execute projects so that we can stumble into completely new problems.

    Iteration Kickoff

    At the beginning of an iteration the team gets together and talks through the candidate user stories for the iteration.  This varies quite a bit from project to project, but here's roughly what we're doing.  The developers will task out the user stories in enough detail to make an estimate for the story that isn't completely fantasy.  The act of tasking together is essential.  I've never seen anyone write this down anywhere, but the tasking exercise is one of the best platforms for creating a common technical vision between the developers and fostering communication between the developers and the folks managing the requirements.  Tasking is design masquerading as an estimation activity.  At the end of an iteration kickoff meeting every developer should have a basic understanding of the technical work for the next couple of weeks.  I've seen projects do pre-tasking meetings before iteration kickoff to break up the work into more easily digestable chunks.

    Take the estimating exercise seriously.  On one hand, it gives the project managment and senior management types information to adjust expectations according to the rate of progress.  On the other hand, decent estimating keeps us developers from being overworked.  That whole sustainable pace thing is kinda nice.  In my waterfall days there always seemed to be a binary switch from "working half-heartedly on planning documentation" to "working way, way too many hours."  I think one of the best ways Agile improves productivity over the long haul is by spreading the work more evenly over the course of a project.

    Make the iteration kickoff meetings as brisk as possible, but no shorter.  These meetings can drain the life from all participants if you are not careful.  Consider it a valuable and necessary evil and get it over with. 

    Iteration Close (Retrospective)

    It's important to timebox your iterations.  Having a brief meeting at the end of an iteration helps to enforce the rhythm of the iterative coding cycle.  Use your iteration close meeting as a way to get the entire team to talk over how the project is going.  Take a short break from the day to day minutae of the project and look at the big picture.  What are we doing that's working?  What's not working that we should change?  What are the project risks and how do we mitigate them?  Where are we going to lunch?  How can we make the iteration meetings shorter and our estimates better?  This is your chance to effect positive changes in the execution of the project.  Do things like look at your bug history and try to spot trends or compare story estimates against actuals to improve your estimating.

    Stand Up Meetings

    Most Agile teams have a short standup meeting in the morning.  The ostensible purpose is to go around in a circle and have each person (or just the developers on some projects) talk about what they're doing and bring up any blocking issues or ask for help on a task.  We use the Scrum burndown chart to track remaining hours in the iteration to get a feel for how the iteration is progressing and track velocity.  I like to have a brief bug report from the testers as part of the standup myself just to keep the developers and testers on the same page.  I'm pretty absent minded about updating my stuff on the burndown so do as I say, not as I do

    Don't ever let stand up meetings take very long on a regular meeting.  It's more or less harmful for a long-winded project manager to dominate the meeting as his or her daily pulpit.  The standup is about the team communicating and collaborating.  I think that the general mental health of an Agile team is easily measured by how miserable or how smoothly standup meetings go on a daily basis.  Make the standup be a net positive for the project team.

    Yes, you can sit down in a standup as long as you're listening (I've got a prematurely arthritic knee so of course I sit).  The original impetus for it being a standing meeting was to insure that the meeting was short.

    Velocity

    I have no business explaining project velocity to anyone, so check out these links:

    Basically the concept is to measure the team's ability to deliver user stories in an iteration in order to predict the amount of work a team can accomplish in upcoming iterations.  There's a wide variety of velocity tracking philosophies and mechanisms, some of which are seemingly designed to flay developers alive.  The finer details of how this is actually accomplished is more or less a mystery to me.  I'm an ex-engineer and the embarassly unscientific nature of Project Velocity compared to the project controls team on a construction project bugs me.

    My only real advice is to make the team as whole familiar with the mechanism for measuring project velocity.  Again, taking project velocity seriously (do put an effort into your estimates, do track the actual effort for a each story in some fashion) helps the project manager set expectations and priorities while keeping developers from being overworked. 

    Non-story work like maintaining a build process, creating Wiki documentation, and minor refactoring work is not estimated because it is assumed to be a fixed ratio to the effort related to story work.  This leads to the saying "We'll just let Velocity handle that."  It's kinda like a golfer telling another golfer to "just pick it up" on a 6 inch putt.  A joke between my boss and I is to say "we'll just let velocity handle it" anytime we don't know how to estimate something.

    Throwing Estimates

    A practice I really like in doing team estimates is to "throw" estimates.  I think it encourages a lot more participation and discussion between developers without bogging down. We did this today in our release planning meeting and I thought it went well.

     

    Of course, I have a lifelong habit of generally ignoring and disparaging project management in general so let's not even pretend that this is a remotely complete list on how to manage an Agile software project.  I've also never been on any two projects that did iteration management the same way. 

  • Exposing a Connection String as a Public Property is a Huge Design Smell

    Pure diatribe ahead:

    Take a look at this code and ignore any concerns over security just at the moment:

    	public class MyConfiguration
    	{
    		public static string ConnectionString
    		{
    			get
    			{
    				// lookup the connection string wherever it is
    				string connectionString = lookupValue("CONNECTION_STRING");
    				return connectionString;
    			}
    		}
    
    		private static string lookupValue(string key)
    		{
    			...
    		}
    	}
    

    This little piece of code may seem innocuous.  It's just a little static helper class to look up the database connection string.  Remember the scene in Lost Boys when the head vampire mocks the heroes by telling them that "Don't ever invite a vampire into your house, you silly boy. It renders you powerless."  Exposing the connection string to any and all callers in a system can effectively denude your system of the protections inherent with layering.  You have probably lost any hope of a coherent data access strategy.  It doesn't *have* to be this way, but every time I've seen (or written) a system that had a publicly available connection string property, the result is pure chaos.  People will grab the connection string and write tons of one-off data access code anywhere and anyhow that they please.  Of course, some of my irritation is that the code I'm looking at uses a modified version of the original DAAB -- one of the stinkiest pieces of code ever dumped on us by Microsoft.

    The database connection string should only be used by a small handful of classes dedicated to data access so you can centralize the database access code

    The dumbest example I've ever seen was a proto-SOAP framework our enterprise architects rammed down our throats that forced us to push a connection string down from the service layer to the business layer and finally down to the data access code.  All so we could write a couple hundred lines of scaffolding code to use his pet framework instead of the "complex" 3-5 lines of code it used to require to pull an Xml document off of an HTTP POST request in ASP/VB6.  Using this web service framework was also going to require us to make 3 HTTP posts on every call (including a pair of self-posts!) and at least a couple of DCOM round trips.  We timed a no-op call at 3/4 of a second -- for a system that was under a heavy load.  My hatred of non-coding or centralized architects started with this project.  My time as the central architect only reinforced this view.

  • Uncle Bob Martin on the Visitor Pattern

    Some design patterns just appear weird the first time you come across them.  The "Visitor" pattern is like that for me because of all the double dispatch stuff.  I understand it and I use it on rare occasions, but I rarely reach for it because I'm not perfectly comfortable with it.  Uncle Bob of ObjectMentor has a great post on the Visitor pattern called "I Use Visitor" that's a good explanation of the pattern.  Familiarity with a pattern like Visitor mitigates the weirdness.

    It's timely for me because I have a little side project going that will likely involve a "Composite" pattern that will include multiple operations across the aggregate object graph.  I'll definitely consider a Visitor when I get there.

    I used to grade code submissions from job applicants at a former employer.  One of the very few good submissions I ever looked at came from a C# coder who used a Visitor pattern on a sales tax calculation problem (think lot's of exception cases).  At first blush I thought it was over-designed, but after a closer look I thought the usage of the Visitor pattern was a fairly elegant way to solve the problem.

  • Classic Technical Lead Blunder

    A couple days ago I saw a post (EDIT:  the post was removed) relating a depressing situation that sounded sadly familiar to me and I have to respond.  The author relates a story of getting to the end of a time-constrained project and realizing that the other developer’s code is bad.  I can easily relate to the author’s plight because I’ve been in the exact situation at least twice.  My diagnosis for both the author's current project and my past experiences is simple.  The technical lead (me) failed to lead the technical effort.

     

    My problem was that my first official developer job was in a completely dysfunctional organization.  That’s actually a mixed blessing in a way.  You can get more opportunities because it’s easy to stand out, but it stinks in the long run because you don’t get to learn the right way to do things very often.  I was by far and away the most productive coder and the guy with the design vision, but I didn’t know squat about leading or coaching other developers (plenty of people will say I still don’t).  I was forced (ok, I basically seized the role when nobody else was looking) into a technical lead role on my very first significant project.  I’d never had any role model for being a technical lead, much less a good role model.  I made the typical blunder that many first-time technical leads do.  I put the headphones on and hunkered down with what I thought were the most difficult pieces of code and did them.  I gave the other developers what I thought were easier tasks and generally ignored them as much as I could. 

     

    I answered questions here and there, but I wasn’t that involved with their coding.  When I finally got around to looking at their code I often didn’t like what I saw.  I rewrote several pieces of their code behind their backs at the last moment.  I essentially wasted the efforts of the other developers.  Two of the developers was truly incompetent but the other two were bright folks that had even less experience than me.  One of the developers was so bad that I started calling him the “Canary” when the “Reduction in Force” rumors started when the tech industry crashed in 2001.  The project was very successful, but could have been much less stressful if I’d invested much more time into the other developers.  They probably would have gotten a lot more out of the project, too.  One of the reasons I think that shop was and is so bad is the complete lack of coaching for technical folks.

     

    Losing Strategies

    • Drive by shootings -- I mean code reviews.  I’m sure code reviews are useful somewhere, but I’ve never been in one that wasn’t either a complete waste of time or a source of resentment.  Relying on code reviews to catch bad code after the code is written is inefficient and just plain stupid.  Code reviews can easily turn into a case of the prosecution versus the defense.
    • Poor or infrequent communication between the technical team members.  On a couple of occasions some of the developers on my team were on the other side of a cubicle farm.  Co-locating a technical is a no-brainer.  I wonder how much inefficiency exists in large IT organizations where they don’t co-locate development teams.  Technical documentation like design specs are a poor form of documentation.  The only good thing about technical specs is that they’re more durable than a conversation.  Tossing specs over the wall to a development team and walking away doesn’t work.
    • Detailed work assignments.  My experience has been that feeling is that the more detailed work assignment you give another developer; the crappier code comes back to you because they will mechanically implement your design without thinking.  I’ve got a case of this on the system I inherited when our very bright boss gave some specific design advice to the team building the system that this team followed without question.  The advice wasn’t necessarily bad, but there were definitely simpler alternatives to what was built. 
    • I design, you just code.  Even before I had ever heard of XP I always believed that coding, design, and architecture are too interdependent to be done by separate people.  Developers can internalize a design strategy better if they contributed to making the design strategy.  Over and over again I’ve found that it just doesn’t work to give someone a detailed design without a lot of verbal and whiteboard communication.  I think there’s also an issue of developer pride and ownership.  I think coders do a better job when they feel some sort of ownership stake in what they’re coding.
    • Ignoring the other developers to concentrate on my work.  I have to constantly remind myself to focus on the team’s velocity as opposed to my velocity.  I still think that I’m most effective early in the morning when I’m heads down into code with zero interruptions, but that doesn’t help the other developers.  It’s not just a matter of trusting the other developers – but that is often an issue.  It’s also about talking over the design, looking for duplication, and creating a shared vision.

     

    Winning Strategies

    • Involve every developer in the design work.  Over and over again I’ve found that developers have a better working understanding of a system’s design when they’ve been involved with creating the design.  Many agile practitioners are hostile to design sessions because of a fear of speculative design or an assumption that it’s jus wasting time (but the agile community is also mellowing in recent years).  I think design sessions in front of a whiteboard with the team is a create way to get the team on the same page.  Most agile projects involve a “tasking” activity to break down user stories so they can be estimated in iteration planning.  The “tasking” meeting is essentially a design meeting.
    • Pair programming has been very effective in my experience for communicating design knowledge throughout a team.  It’s also a great mechanism to coach other developers.  Pairing can be used as an ongoing code review to eliminate problems more rapidly without the nastiness of a formal code review.  Bad coding practices can be caught very quickly.  On a project last year most of the other developers were Java and GUI guys that hadn’t worked with database or persistence code very much.  Because we were pairing I noticed that they weren’t attending to connection hygiene very well.  I caught the issue very early and explained why it was important to manage database connectivity.  Waiting for a formal code review a couple months into the project to read other people’s code would have allowed that problem to fester.
    • Collective code ownership.  Nobody works in a silo.  Every developer, at least in a small team, should have some visibility into the entire codebase.  Determining and enforcing best practices can be a lot easier when people are rotated through the code.
    • Think out loud.  This is purely an exhortation to me because I never do this well enough.  If you’re one of the primary people doing design on project, talk about your design thoughts all the time.  Involve your teammates as much as possible.
    • Coach the other developers.  If you’re the senior most developer your most important contribution may be the coaching you give other developers, not necessarily the code you write.  Helping other developers is an investment in your team and organization.  Besides, they undoubtedly have something to teach you too. 
    • Co-location of the developers and the rest of the team.

     

     

    You could easily argue that the ability to communicate ideas to other developers is one of the most valuable skills a lead could possibly have.  I don’t think anybody can be a technical lead without good technical skills, but not every strong developer is fit to be a lead.  Heck, I’m the veritable poster child for this.

     

    Of course, you’re always going to have trouble if the ratio of “needs coaching” to “able to coach” gets too high.  The idea that all you need is one smart guy on a project to tell everyone else what to do is a nonstarter in my book.  No process or goofy accreditation effort, be it wild-eyed XP, UML out the wazoo, Six Sigma Ninjas, or CMMI Level Umpteen, is ever going to change the fact that producing good software requires good people.  Some people want to be the bright shining star of an organization, and the easiest way to do that is work with bad people.  I’ve gotten to work on a couple of very strong teams at both my current and previous employer.  That’s been vastly more fulfilling and less stressful than being “the” guy on a weak team. 

  • Database per Developer and Environment

    Our Continuous Integration talk Monday got a bit rushed at the end and I missed an important point when we talked about CI with databases.  For the love of all that is good and holy in the world create a separate database/schema for:

    • Each development workstation
    • Build environment
    • Test environment 
    • A "Sheep" database for the Business Analysts (baaaa) or Product Manager to use for ongoing demos to the customer

    Running automated tests against a database is a complete joke unless the database is in a completely known state.  There are some "hacky" alternatives, but the easiest alternative by far is a completely isolated database with only one user.  Think about going to a hospital and seeing them reuse needles.  A shared development database should make you recoil in horror in much the same way.

    "Jeremy, everybody already knows that and it's been a best practice since before you were born."  I didn't know that a couple of years ago on my first CI/TDD project and I know there are people out there who haven't thought about this issue at all.  I've been a pair of projects now where we attempted to run automated testing against shared databases (in both cases it was organizational stupidity and bureaucracy in Fortune 100 internal IT departments).  It was excruciating.  An untrustworthy automated build is completely useless.  If your initial reaction to the build busting is "Oh, it's probably a database conflict.  I'll just force the build again" -- your investment in CI has been squandered.   

    It's also more fuel on the fire for being able to test the majority of your code without the database being involved.  You'll also need the ability to automatically create a database structure from scratch inside the build to pull off the separate database scheme.

     

  • What’s so great about Inversion of Control?

    Inversion of Control (IoC) is an essential tool for any software designer’s design toolbox because it’s often a great way to break dependencies between classes and promote loose coupling.  IoC is vital for doing Test Driven Development without pulling out all of your hair in frustration. 

     

     

    Real Life Example

     

    I’m doing an interesting refactoring early this week on some existing code.  I apologize in advance for being a little vague, but the NDA thingy gets in the way a bit here.  The product that my team works on is basically a B2B hub between sender companies (spokes) and receiving companies. 

     

    The application:

    1. Receives a message in one of a handful of industry standards and 3rd party formats
    2. Converts the data into a canonical data format
    3. Performs a variety of business validations
    4. Translates the results into yet another industry standard for transmittal to another downstream system

     

    The translation code is obviously critical to the system, so it’s very important that the automated testing is rock solid.  Moreover, that code would be extremely useful in many other contexts throughout our enterprise.  The code works just fine and there is a robust suite of automated tests ensuring that the code continues to work.  I had tried in the past to adapt this code inside of an automated regression test tool without any success because it had too much “tail.”  What I mean by this is that the code can only function with some specific dependencies on a couple of different data sources that weren’t necessarily easy or even possible to recreate without bringing in a large fraction of the system.  Using the translation code requires some data access code which in turn requires some configuration code and external settings in a Registry (We’re going to make this go away too.  I detest using the Registry for any configuration, much less as a Plugin strategy.).

     

    In an ongoing effort to speed up a slow (15-20 minutes) build, I managed to break the integration tests for the translation classes and had an opportunity to look much closer at this code.  Here’s roughly what I found:

     

          public class Translator1

          {

                private readonly IDataSource _source;

     

                public Translator1(IDataSource source)

                {

                      _source = source;

                }

     

                public Translator1()

                {

                      _source = new CompanyDataSource();

                }

     

                public XmlDocument TranslateFlatFile(byte[] contents, string senderId, string receiverId)

                {

                      XmlDocument document = this.startNewXmlDocument();

     

                      CompanyInfo sender = _source.FetchCompanyInfo(senderId);

                      CompanyInfo receiver = _source.FetchCompanyInfo(receiverId);

     

                      this.createSenderNode(sender, document);

                      this.createReceiverNode(receiver, document);

     

                      // Do a lot of other stuff

     

                      return document;

                }

     

                private void deepInTheBowelsOfTheClass(string key)

                {

                      string something = DataSourceSingleton.Instance.LookupValue(key);

                      // do something with "something"

                }

     

                [OTHER METHODS]

          }

     

    And the test fixture looks a bit like this:

     

          [TestFixture]

          public class Translator1TestFixture

          {

                [Test]

                public void WriteTheSenderNode()

                {

                      // The sender and receiver data is assumed to be in the database -- somewhere

                      Translator1 translator = new Translator1();

     

                      byte[] contents = this.readFlatFile();

     

     

                      XmlDocument document = translator.TranslateFlatFile(contents, "ID00001", "ID00210");

                      XmlNode senderNode = document.DocumentElement.SelectSingleNode("Sender");

                      Assert.AreEqual("Austin", senderNode["City"].InnerText);

                }

     

                private byte[] readFlatFile()…

          }

     

    So what’s so terribly wrong with this code?  From my standpoint there are several problems.

     

    • Setting up the tests.  The unit tests cannot function today without known data being previously setup in the database external to the TestFixture.  When you do write tests against a live database you’re forced into a “least evil” decision.  One of the things I talked about in an earlier post was the desire for tests to reveal the intention of the code.  One of the best ways to do this is to make sure that the test is largely self-contained.  In this case the data assumed to be inserted into the database prior to the test running.  One way we can make this test self-contained is to do the database data setup inside the TestFixture class itself.  That’s okay with small chunks of data, but it doesn’t scale very well. 
    • The tests are not isolated.  The tests break if other tests overwrite the data in the database.  Life is happier by far when each test is truly isolated and order-independent.  The dependency on the singleton in the Translator1 class certainly doesn’t help either.  I’m fighting with a set of tests today that are not isolated.  They exhibit some interesting behavior like running successfully one at a time but failing occasionally when they’re run with other tests.  I’m not happy.
    • Debugging the unit tests.  Look at the WriteTheSenderNode test method.  There is an assertion that checks that the “City” node has a value of “Austin.”  Just looking at the test code you won’t be able to see where this value comes from.  It’s not clear from the test code why the value of the xml node is supposed to be “Austin.”  You can partially beat this problem with comments in the assertions, but that’s not enough in my book.  Comments are often a crutch for obfuscated code and this isn’t an exception.  Another thing to keep in mind is that granular tests are easier to debug than coarse tests.  This code today only has integrated tests without any unit tests.
    • Test execution time.  Tests that run against the database are slower than tests that run completely inside one process.  I’m writing this post while I wait for some very slow integrated tests to run.  Slow tests are a form of inefficiency.  I really want to test the translation code here, not the data access.  If I can isolate the translation functionality away from the database structure, I can make the tests faster.
    • Reuse the code.  As I’ve stated before, it would be very advantageous to reuse this translation code.  Today this is difficult because of the tight coupling to other classes.  The dependency on the specific data access class is easily remedied by a little “constructor injection,” but there is still the dependency on the singleton buried deep inside the class.  To use the translation code I have to bring with me everything that damn singleton needs too.  Moreover, it’s not going to be obvious to someone else attempting to use the translation code what they need without tracing deep into the translation to figure out the external dependencies of the singleton.  Singleton == testing pain.  I haven’t done enough research into the singleton usage, but one way or another we’ll remove the dependency on the singleton.

     

    Refactoring to Inversion of Control

     

    My thought on the translation code is to apply Inversion of Control to the translation code to remove the database dependency.  Let some other class be responsible for running out and fetching the receiver and sender information and “push” it into the translator.  I could have abstracted the data source class as an interface and used Constructor Injection to push alternative classes or mocks into the Translator2 class.  My thinking in this case is to simplify both the reuse of the translation code and eliminate the mocking overhead (~70 automated tests) by eliminating the interaction with a data source class altogether.

     

    The code below is a skeleton of the approach I’m going to take to refactor our translation code (someday).  Here’s how I think the new code stacks up to the old code.

     

    • Setting up the tests.  The input data is created within the test itself because the inputs are just objects.  Don’t ever discount the value of Intellisense in creating test data.  Working with SQL statements or DataSet’s is laborious and error prone.
    • The tests are isolated.  The translation code no longer depends on any kind of external or shared data inside the tests.
    • Debugging.  The tests are somewhat easier to debug because the tests are self-contained.  Debugging one of these tests if they break is simpler because you don’t have to keep “ALT-Tabbing” between the database window and the code.  I’d also argue that the test code is much more intention revealing.
    • Test execution time.  These tests will run faster because the external network hops to the database are eliminated.  Don’t underestimate the importance of fast tests.
    • Code reuse.  I can now reuse the translation code more easily in other contexts.  I don’t have to have any special database structure or external configuration anymore to use the translation code.

     

          public class Translator2

          {

                public Translator2()

                {

                }

     

                public XmlDocument TranslateFlatFile(byte[] contents, CompanyInfo sender, CompanyInfo receiver )

                {

                      XmlDocument document = this.startNewXmlDocument();

     

                      this.createSenderNode(sender, document);

                      this.createReceiverNode(receiver, document);

     

                      // Do a lot of other stuff

     

                      return document;

                }

     

     

                #region other methods

          }

     

          [TestFixture]

          public class Translator2TestFixture

          {

                [Test]

                public void WriteTheSenderNode()

                {

                      CompanyInfo sender = new CompanyInfo();

                      sender.City = "Austin";

                      // set other sender properties

     

                      CompanyInfo receiver = new CompanyInfo();

                      // set receiver properties

     

                      byte[] contents = this.readFlatFile();

                      Translator2 translator = new Translator2();

     

                      XmlDocument document = translator.TranslateFlatFile(contents, sender, receiver);

                      XmlNode senderNode = document.DocumentElement.SelectSingleNode("Sender");

                      Assert.AreEqual(sender.City, senderNode["City"].InnerText);

                }

     

                private byte[] readFlatFile()…

          }

     

    All I’ve really done is move the responsibility for fetching data out of the database into another class.  It’s a small change but it had a positive impact on both the code and the testing.  If you think about it, you could actually say that software design boils down to “Where should this code go?”  I think there’s a watershed moment in every developer’s career when they start look more at their code as a structure and less as a bag of statements. 

     

    Other Examples

     

    We’re taught that the key to safe lifting is “push, don’t pull.”  I like to think of Inversion of Control as applying this mantra to code.  IoC is fairly common, and much more so with Test Driven Development practices.  Here are some other examples of IoC you might run into.

     

    • The Data Mapper pattern is the central concept in many Object/Relational Mapping tools.  Using an external mapper class to handle persistence duties for a business domain class has several advantages.  The domain classes can become simpler because they’re no longer interacting with any kind of data class.  You can also insulate the business domain from the database structure and vice versa.  Testing the business logic can be much simpler with a domain model.  My company’s main application today relies on far too many T-SQL stored procedures.  Some of our multi-billion dollar clients seem to think they have the right to run our application on Oracle instead.  We’re eventually going to arrange our business logic along domain model principles and take advantage of an O/R mapping tool for multi-database support.
    • Model View Presenter (MVP) might not be a true example of IoC, but it’s similar in philosophy.  When you use the MVP you make the “view” classes completely passive.  Instead of the view making requests to the controller, the controller tells the view what to do.  MVP is the best mechanism that I know for doing TDD with user interface clients.
    • A side effect of using Dependency Injection for configuration is that your classes are no longer dependent on any kind of external configuration file (or God forbid, the registry).  Here’s a simple example of “push” configuration.  The PushClass will be constructed by some kind of Builder class that reads the configuration and returns a PushClass object.  I’m a huge fan of this technique after a couple of projects now.

     

          public class PullClass

          {

                private int _threshold;

     

                public PullClass()

                {

                      _threshold = int.Parse(System.Configuration.ConfigurationSettings.AppSettings["Threshold"]);

                }

          }

     

          public class PushClass

          {

                private readonly int _threshold;

     

                public PushClass(int threshold)

                {

                      _threshold = threshold;

                }

          }

     

    • If you look at the example user story from my article on Assigning Responsibilities, I used IoC to isolate the functionality for creating HTML from an Invoice so that this functionality could be tested without a lot of interaction with other classes.

     

    The obvious example of IoC from the blogosphere is Dependency Injection.  My next post will be an introduction to Dependency Injection (DI) as a concept independent of the DI/IoC tools.   

  • Slides from the Continuous Integration Talk Last Night (With Fixed Link)

    As promised, here is a zip file of the slides from last night's Continuous Integration talk.  I also included the CC.Net configuration and the sample NAnt build file from the demonstration last night.  The easiest way to get started with the whole NAnt/CC.Net stack is to just find examples on the web and copy them.  It's also at the ADNUG site under downloads.

    Here is some other resources on Continuous Integration.

    Here's a longer explanation of the "Check In Dance"

    Bill Caputo on Enterprise Continuous Integration for larger projects and environments.

  • Inversion of Control with the Plugin Pattern

    (IoC) is an old principle in object oriented programming, but it’s gotten a lot of buzz the last couple of years because of the proliferation of Dependency Injection (DI) tools and articles.  Dependency Injection is a significant flavor of the broader Inversion of Control principle, but it’s not the whole enchilada.  IoC is an important technique to make your code easier to test with TDD, but the other major benefit is extensibility.

    Inversion of Control is also known as the “Hollywood Principle” – “don’t call me, I’ll call you.”  In short, this principle applies when you create classes that are passive, i.e. they do not direct the executing flow of the code.   It also applies to classes that are ignorant of the services that act upon them instead of directing the services themselves.

    The original usage of the term Inversion of Control referred to the creation of reusable whitebox frameworks that could be extended by creating plugin classes.  The general idea being that you extend the existing behavior of a framework by creating a class implementing an interface from the framework.  Your new class doesn’t call the framework; the framework code calls the new class. 

    The Plugin pattern as described by Martin Fowler in the PEAA book is a common pattern.  I went looking for examples today and found several just by looking in my current project and at tools that we use every day.  CruiseControl.Net is a very “pluggable” framework.  CC.Net has to work with multiple source control systems (Subversion, CVS, Perforce, etc.), different build tools (NAnt or MSBuild), and different strategies for publishing build results.  A former colleague has been setting up a CC.Net server against a CC/Harvest (unusable pile of manure) source control repository.  CC.Net doesn’t support Harvest out of the box, but it’s not a show stopper.  Just create a class that implements CC.Net’s ISourceControl interface and configure CC.Net to call the new class in the CCNet.config file.
     

    <cruisecontrol>

      <project name="StructureMap">

        <webURL>http://localhost/ccnet/Controller.aspx?_action_ViewProjectReport=
    true&amp;server=local&amp;project=StructureMap</webURL>

        <triggers>

          <intervalTrigger seconds="60" />

        </triggers>

        <modificationDelaySeconds>10</modificationDelaySeconds>

     

        <!-- Configure the connectivity to Subversion ISourceControl plugin and establish the working directory -->

        <sourcecontrol type="svn">

          <executable>c:\program files\subversion\bin\svn.exe</executable>

          <trunkUrl>file:///C:/PersonalProjects/StructureMapSVN</trunkUrl>

          <workingDirectory>C:\PersonalProjects\StructureMap-Working</workingDirectory>

          <autoGetSource>true</autoGetSource>

        </sourcecontrol>

               

        <!-- Configure the NAnt builder block -->

        <build type="nant">

          <executable>C:\PersonalProjects\StructureMap-Working\bin\nant\nant.exe</executable>

          <baseDirectory>C:\PersonalProjects\StructureMap-Working</baseDirectory>

          <buildFile>cruise.build</buildFile>

          <targetList>

            <target>cruise</target>

          </targetList>

     

          <buildTimeoutSeconds>1500</buildTimeoutSeconds>

        </build>

     

        <!-- Merge in test results from the NUnit tests -->

        <tasks>

          <merge>

            <files>

              <file>C:\PersonalProjects\StructureMap-Working\results\*.xml</file>

            </files>

          </merge>

        </tasks>

     

        <publishers>

          <xmllogger />

        </publishers>

     

      </project>

               

    </cruisecontrol>

     

    My StructureMap tool has a couple of plugin patterns to extend the basic framework with additional options.  I wanted multiple options for project configuration.  Simple projects would probably just use the basic XML configuration in the project path.  Larger multi-server applications might push a team to use a central database or some sort of LDAP tree structure to store the configuration in a common place.  StructureMap uses classes that extend the MementoSource abstract class to fetch configuration data for instance graphs.  To create and use a new means of configuration I first create a new class that inherits from MementoSource and override the virtual and abstract methods.  StructureMap is directed to use the new MementoSource in the StructureMap.config file in the project directory.
     

    <StructureMap>

      <!—Configure this PluginFamily to use an XmlFileMementoSource that pulls configuration from an Xml file named “FullTesting.XML” -->

      <PluginFamily Type="StructureMap.Testing.Widget.Column" Assembly="StructureMap.Testing.Widget">

        <Source Type="XmlFile" FilePath="FullTesting.XML" XPath="Columns" NodeName="Columns" />

      </PluginFamily>

    </StructureMap>

    Here are some other examples of the Plugin pattern:

    • Log4Net provides extensible logging options.  If none of the two dozen or so built in logging storage mechanisms fit your needs, you can happily create a custom implementation of the IAppender interface for customized logging.
    • It’s very straightforward and often advantageous to create custom tasks to use in NAnt build files. 
    • The Provider model in .Net 2.0 is an example of the Plugin pattern (and the Service Locator variant of Dependency Injection).   

     

    The Open/Closed Principle

     

    “Software entities (Classes, Modules, Functions, etc.) should be open for extension but closed for modification.”

     

    This sounds like a contradiction at first glance, but it’s not.  As explained by Robert Martin here, the Open/Closed Principle (OCP) pushes you to design software in such a way that new functionality can be added to system by creating brand new code rather than modifying gobs of existing code.  The thinking behind the OCP is to make a system easier to change by leaving currently working code alone, or at least minimizing the amount of code modification needed to add the new behavior.  An abstracted Plugin pattern is one of the best ways to follow the OCP. 

     

    I used to think that the OCP was only important for systems that really needed a lot of extensibility, but I’ve found that following the Open/Closed Principle helps make code that can evolve inside of an incremental design process.  You don’t necessarily have to use a Plugin pattern class that’s loaded via reflection and configuration to get the benefits of the OCP.  You do, however, have to follow the Dependency Inversion Principle to reap the benefits of the OCP.

     

    My CodeBetter neighbor David Hayden has a good discussion on the OCP here.  The OCP is also easier to achieve by following the Single Responsibility Principle.

     

    A Word of Caution

     

    Don’t use a Plugin pattern until it’s really necessary.  Speculative usage of the plugin pattern everywhere you think you’ll need flexibility later is a quick path to a sclerotic, over-designed application that nobody wants to work with.  Not that I've ever been guilty of that.  The Plugin mechanism creates more indirection in your code.  That leads to additional intellectual overhead trying to understand what’s happening in your code base.  I’m tangentially involved with a code base that extensively uses classes loaded by reflection.  The end result in this case is simply an application that is harder to debug and trace (and impervious to ReSharper code navigation).  If you’re using the plugin pattern, I’d recommend using an existing tool like StructureMap to take advantage of the diagnostics and troubleshooting features.

     

    One of the most wrong-headed sentenced in all of software development is “let’s build the framework first, and then the application will be easy.”  No, no, no.  I’m never going to be a part of (or be the cause of) this exercise in stupidity ever again.

     

     

     

    My next two posts will talk about using Inversion of Control for improved testability and using Dependency Injection as a crucial technique for TDD.

  • Journey into the Heart of Darkness

    My poor colleague (martyr) is trying to debug a production issue with some system generated emails today.  If I can get the facts straight, the chain of calls goes:

    1. ASP "Classic" page calling into a...
    2. Stored Procedure that calls...
    3. Another Stored Procedure that calls...
    4. A third Stored Procedure that calls...
    5. An external COM object via DCOM (!) that posts...
    6. Information to a different web page to create and send the email

    Of course, the auditing is lacking and all exception handling is done by the stored procedures.  Once again, stored procedure abuse is a very serious problem.  If you really think that T-SQL or PL/SQL is suitable for anything but CRUD or set-based logic, seek professional help immediately.

    On a serious note, if you're building a system that generates emails that need to be reliable, I would strongly suggest creating a full audit trail of the email messages sent with an easy way to replay the email messages if you have to.  Your support folks will thank you later.

    I'm *this* close to deleting The Daily WTF from RSS Bandit because I think it verges on mean spiritness occasionally, but they always save the day with a post like Integration Nation that's good for a laugh.  I showed it to my colleague today just to let him know that it could be worse.  He didn't seem to feel any better though.

     

  • Roadmap for the next StructureMap Release

    StructureMap is a Dependency Injection tool for .Net that I released on Sourceforge last year.  Somebody asked me last week if StructureMap is still alive.  The answer is yes, and I'm starting to pull together a new release.  I've been using it on a project most of this year that's caused me to make some extensions and improvements.  Most of my focus and need right now is on refining the troubleshooting support and creating some easier to use configuration options.  My feature list for the next release is below.  Feel free to send me any suggestions.

    What's Definitely In

    1. Update the website
    2. Bug fixes (done)
    3. Better error messages in some places
    4. Templated configuration.  I hit some things on my last project where the exact same object graph structure was used several hundred times with only some minor variations in a handful of constructor properties.
    5. Better troubleshooting support in StructureMapDoctor
    6. Creating a UI tool to explore and troubleshoot StructureMap configurations.  My last project was creating a pseudo rules engine with StructureMap as a configuration engine.  Think somewhere in the neighborhood of 7,500 individual object graphs, all about 4-5 levels deep. 
    7. More configuration choices. 
      1. File per configured instance
      2. Multiple search directories to make things easier with automated builds 
      3. Options for storing the StructureMap configuration information in different places (done to make it easier to run under FitNesse tests)
      4. An alternative XML configuration format that is simpler and more concise.  This does not break existing StructureMap formats.
      5. Store configuration as resource files for easier deployment
    8. Cleaning up and expanding the support for maintaining separate configuration profiles
    9. Enhancing the ability to do simple configuration with attributes

    Other Things I'm Thinking Of

    1. Aspect Oriented Programming support.  I'm looking at adding some support for using AspectSharp in the object creation pipeline to do runtime AOP.  Right now it's looking like this is going to be pretty simple and it's an excuse to learn more about AOP.  I'm certainly not going to write AOP support from scratch (My wife would kill me if I start a new OS tool.  You're doing what?  Shut that thing down and go clean the garage).
    2. Instance per HttpContext or Thread Local Storage.  I can see this being useful in a few cases, and it's low hanging fruit.
    3. Test StructureMap against .Net 2.0

    Over the Horizon

    1. Caching and Object Pooling.  I've always thought this would be an interesting problem.
    2. Configuration editing in a UI tool.  I started this once but didn't like the results.
    3. NHibernate integration.  I don't think this will be a big deal, but *I* don't need this for awhile.

    Just as an odd aside, StructureMap started as my attempt to create the ultimate Object/Relational Mapper (based on Reflection.Emit instead of reflection or code generation) back in 2002 before I had done any serious .Net development.  In 2002 I was in a really bad position as a non-coding architect on several projects that never managed to actually start coding.  I had a silly dream that I would write this incredible O/R tool and use it as a device to get "the hell out of dodge."  I escaped anyway, and the O/R stuff stalled out, but I'd done a cool little spike for the configuration piece to learn how to dynamically emit classes.  That spike code became the kernel of StructureMap after I'd read about Inversion of Control containers in the Java world.  Several of my friends gleefully tell me that Spring.Net will win the majority of the mindshare for .Net folks, but I still think that StructureMap has a solid niche nonetheless.  There's plenty of differences in my solution versus Spring.Net that I'll keep StructureMap going.  Besides, my company has a deep investment in StructureMap as a configuration solution for one of our products.

    Writing an open source development tool has been a great learning experience.  Most of us simply don't get the chance to do challenging (or resume-expanding) work very often at work.  Doing some kind of project on the side is a great way to learn new things in a directed way.  I used StructureMap to hone my TDD skills.  I can look at the oldest code to the newer code written 2+ years apart and see my personal coding style shifting away from being a "code and fix" VB6 guy to a more loosely coupled OO style and better unit testing.

  • I'm getting sick of using "hand me down" tools that are ported from Java to .Net

    I'm just ranting.  Don't take it too seriously, and feel free to tell me that I'm wrong.

    We're working with FitNesse as a means of automating our acceptance testing.  I'm pretty happy with the way its going so far, bu