Documenting my journey through the pratice of software development RSS 2.0
 Friday, April 25, 2008

A lot of people talk about software in terms of manufacturing and construction - laying the foundation, getting the architecture in place, building components, assembling the final product, make sure we have all the plumbing setup, wire it all together, etc, etc, etc.

"The problem with the construction and manufacturing analogies, is that they fall apart as soon as you start talking about software as construction and manufacturing." - me

Software developers are not construction or manufacturing workers. We don't sit on an assembly line, mechanically reproducing the same result over and over and over again. We don't (or at least, shouldn't) put all the plumbing and frames in place before anything else. We're not line workers, warehouse workers or laborers.

The only parallel that exists between any manufacturing or construction positions, and software development is that we are research, design and development workers. Some manufacturing companies have R&D positions, some don't. Some construction companies do, too. Software development is ALL research, design, and development.

When it comes down to it - source code is not a foundation, a structure, a component or any of the other parallels that people try to use. Source code is a specification for how an executable software package will be built and will behave. We don't build the executable software package - the compiler and build scripts do that for us (if you are manually building the software, go learn NAnt, Rake, Make files or some other automated build process for your environment). What we do when we write source code is R&D - research, design and development... hence the name, "Software Development".

Therefore,

"The only part of software development that even remotely resembles manufacturing or construction is the moment we click the 'build', or 'compile' button, or kick off whatever script or command, and the build process does the work for us." - me

Friday, April 25, 2008 7:49:32 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: General | Management

 Wednesday, April 23, 2008

Based on the proposed information and syntax from My Previous Post, I've created a basic Design By Contract unit testing framework. The intent of the code so far, is to provide a quick-and-dirty proof of concept. With that in mind, I give you

DBCUnit hosted on GoogleCode

You can get the source code via Subversion:

http://dbcunit.googlecode.com/svn/trunk/ 

Please note that the existing code only supports one assertion so far: Equals. Also, the execution engine is entirely made up of terrible code that assumes a lot of perfect-scenario input. I'm planning to flesh it out more and make the code more sustainable - actually adding Contract specifications for my execution engine, etc. Let me know what you think of the idea and the syntax. Also feel free to join the project and pitch in for syntax and implementation.

The one Contract I have specified so far, just to get rolling, is that a [PreCondition] should be executed once.

[Condition]
public class WhenPreConditionIsPresentInContractCondition
{
 
    private int preConditionExecutionCount = 0;
 
    [PreCondition]
    public void PreCondition()
    {
        preConditionExecutionCount += 1;
    }
 
    [PostCondition]
    public void ThePreConditionIsExecutedOnlyOnce()
    {
        Assert.That(preConditionExecutionCount).Equals(1);
    }
 
}

To run the test, run build the solution and run the DBCUnit.Console pointing to the DBCUnit.Contracts.dll, like this:

C:\...\> DBCUnit.Console.exe DBCUnit.Contracts.dll

If the test succeeds, there is currently no message printed to the console window. If it fails, it will write out a message saying what value it expected and what the value was. It's all very simplistic at this point, just a proof of concept. I also set up the DBCUnit.Console project to automatically start with the "DBCUnit.Contracts.dll" as the startup parameter, so you can step into the code via debugger and see it in action.

Have fun, and don't laugh too much. This is my first attempt at hacking together a unit testing framework.

Wednesday, April 23, 2008 7:50:08 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | DBCUnit | Design By Contract | Test Driven Development | Unit Testing

There's a lot of talk about Design By Contract (DBC) out there in the development world. Various development languages have varying support for it, but more importantly various processes have various levels of support for it.

It seems, though, that the farther down the path of development we travel, the more important it is for us to consider DBC in the code that we write. Large projects with multiple developers are in great need of DBC. Projects that have publicly distributed API's are in even greater need of DBC. Even if you are working on a simple, one person project for yourself, and you are the only one that will ever use it's methods and objects, I'm willing to bet that you will forget about the assumptions that you are making when writing the methods and objects, at some point.

So where does this distinct need for DBC leave us, in the world of .NET (C#, VB, and the other "common" .NET languages)? We still need a way to enforce DBC, but our language of choice doesn't support it, natively. So we have two real choices (excluding DSL writing, and/or switching languages) - documentation (via code comments or written / published documentation) or Unit Tests.

Yes, that's right - Unit Tests are not just for testing, anymore. Or more correctly, the tests executed by unit testing are not just for the sake of testing. The intention is verify the pre and post conditions of a design-by-contract. Of course, I'm not the first one to suggest this. It's mentioned briefly in "Agile Principles, Patterns, and Practices in C#" by Robert C. Martin and countless other times as well.

I am propose a new unit testing framework. I know, I know... "not ANOTHER xUnit framework... *sigh* ". In this case, I am proposing a semantic change along with the mechanical (syntax) change, specifically for the purpose of introducing unit testing to a group of developers that may not believe in "Unit Testing".

As an example of my proposed syntax, in a file called "SomeContract.cs", this test code would exist:

[Conditional]
public class WhenSomeConditionIsMet
{
    
    SomeValue someValue;
 
    [PreCondition]
    public void PreCondition()
    {
        Setup.My.Inputs inputs = Here;
    }
 
    [Execution]
    public void Execution()
    {
        someValue = Execute.TheContract.With(inputs);
    }
 
 
    [PostCondition]
    public void ThenSomeOutputIsSomeValue()
    {
        Assert.That(someValue).Equals("Some Known Value");
    }
 
 
    [PostCondition]
    public void ThenSomeOutputIsSomeValue()
    {
        Assert.That(someValue).DoesNotEqual("Some Unknown Value");
    }
 
}

To make this proposed syntax easier to understand, I'm basing it on the NUnit style of using attributes, at the moment; but it doesn't have to be that way. There is almost a one to one translation between NUnit and this.

  1. The [Conditional] attribute is equivalent to [TestFixture]
  2. The [PreCondition] attribute is equivalent to [TestFixtureSetup]
  3. The [Execution] attribute is equivalent to [Setup]
  4. The [PostCondition] attribute is equivalent to [Test]

In this simple example, I don't have an equivalent to [Teardown] or [TestFixtureTearDown]. I'm sure I'll need those at some point, but until I see the need, I'm not going to worry about them. I also don't really care about the Assert syntax. I'm just putting that syntax in place to illustrate the point.

Where I differ from typical NUnit style of testing is that I want to see a single "PreCondition" and "Execution" per test fixture, and have multiple "PostConditions" that only contain the assert statements. This style of test code more closely resembles that of Scott Bellware's SpecUnit.NET and for good reason - I like it. I'm a fan of having as little as possible in the method that does the assert - keep it simple and explicit.

The biggest problem I have with my proposed syntax is a problem inherent to Design By Contract - the idea that you know the object (contract) being executed. A huge part of why I love Behavior/Specification Testing vs. Unit Testing is that Unit Tests and TestFixtures typically tell you that for class/file "XYZ.cs" you have "TestFixtureXYZ.cs". Whereas, Behavior/Specification Testing says that we have "BehaviorSpecification.cs" regardless of the classes used to implement it. I love this about Behavior Driven Development - it freed my mind from the horrible constraints that I saw in standard Unit Testing / TestFixtures. Unfortunately, Design By Contract basically takes us right back to the same place. We are specifying contract (class) "XYZ" so we have a "XYZContract.cs" file to hold all of our [Conditional]s.

...

Does anyone else see any value in this style of unit testing? I can certainly see scenarios where this would appeal to some developers more than the standard xUnit frameworks.

Wednesday, April 23, 2008 12:48:39 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Agile | Design By Contract | Test Driven Development | Unit Testing

 Monday, April 21, 2008

I saw "The Forbidden Kingdom" this weekend. Overall it was a great movie - lots of good action, a good storyline, etc. But there was one scene that stuck in my mind specifically. Jackie Chan is pouring some drink into a cup while the person holding it is talking. The cup quickly overflows and the person holding it notes that the cup is full and now overflowing. Jackie Chan's response was something to the effect of

How can you fill your cup when it is already full? How can you learn anything when you 'know so much' already?

The point of this, of course, is that the student thought he knew so much already and wanted to get right to the advanced stuff rather than letting the teacher guide him through the basics into the advanced stuff. As silly as it is for a pop-culture movie to have deep wisdom, I really thought that this scene's message was applicable to more than just martial arts. The same can be said of any situation where knowledge, learning and growth are present.

One of my coworkers (Michael Adkins - who's blog is not publicly available, yet... *nudge nudge*) recently had a post that talked about the same thing, with a slightly different quote at the beginning. Rather than me re-hashing his post with my own interpretation, I'm re-posting his post in it's entirety (with his permission, of course).

So, you think you know everything about development eh?

A wise man once said, "He who knows everything, cannot be taught anything."  This is such a profound statement.  When it comes to learning, I attempt to look at the learning process as if I don't know any of the material (all things being equal of course).  This allows me to see things I did not see in the past.  It allows me to critically think about ways to solve problems with the new knowledge I have gained.

Sometimes when a person asks questions, it is perceived that the person doesn't have a clue as to what is going on with the process.  In my case, it is my acid or litmus test to locate a person; to see if they can articulate an answer that tells me if they are trying to help or build their ego.

Nevertheless, whether a person is helping or building their ego, they are still helping with all types of insight.  They just may not be aware of it.  This is something we all may be guilty of in some form or another.  But it just goes to show that we don't know everything.  It also goes to show that we continue to teach and instruct when we think we know everything.

This blog came about when I was going through a webcast that dealt with Delegates.

I couldn't have said it better. ... I just hope that I'm not the guy who's cup is already full.

Monday, April 21, 2008 1:36:48 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: General | Management | Philosophy of Software

 Thursday, April 17, 2008

Recently, my development team has started up our Friday Lunch-n-Lean sessions where we all read a chapter of a given book and discuss that chapter amongst the group during lunch on Fridays. We're now on Chapter 2 of Domain Driven Design, by Eric Evans.

When I first started reading DDD around a year and a half ago, I honestly thought the first 4 or 5 chapters were wordy, boring and repetitious. Going back to the beginning of the book with my experience and knowledge from the last year and a half, I can't believe that I thought this.

The first two chapters alone have been completely mind-blowing for me, on my second read of the book. I don't know if it's the combination of other knowledge, the experience I've had trying to implement DDD's concepts, or what... At this point, I can hardly turn a page without having 10 or 15 highlighted phrases and sentences. Seriously - there's rarely a page in the first two chapters that does not have something highlighted.

If your involved in any part of software development - management, analysis, development, documentation, or anything else - and you've never read this book; you need to read at least the first 3 chapters at least 3 times, if not the entire book.

Thursday, April 17, 2008 3:01:07 PM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: Domain Driven Design | Management

I found myself doing this, and I had all kinds of creepy-crawlies in the back of my mind.

image

It's a VirtualPC instance of Windows XP, and I'm installing VMWare Infrastructure Client so I can connect to VMWare ESX, to test out VirtualCenter's features, etc... it just feels soooo wrong. I need to buy a copy of VMWare Workstation so I can get rid of this dirty feeling that I have.

Thursday, April 17, 2008 12:42:29 PM (Central Standard Time, UTC-06:00)  #    Comments [1]. Trackback 
Tags: General | Management | VMWare

 Wednesday, April 16, 2008

I've been learning a lot lately - reading up on Agile, Lean Manufacturing, Lean Software Development; experimenting with NHibernate, exploring UnitOfWork concepts and generally trying to become a better software developer. In this process of learning, discussion with others, and application of knowledge to my environment, I've found that knowledge is very distinctly different than understanding.

Let's look at my use of NHibernate as an example. 2 years ago, I knew the basics of what NHibernate could do for me - I spent a few weeks learning the very basics to see how it worked and whether or not I wanted to use it. 1 year ago, I actually started using NHibernate for a project and my knowledge of it quickly grew. I knew how to create the appropriate mapping files, configure NHibernate, etc. As this knowledge grew, I became more and more interested in what NHibernate could do and how it could be applied to many different applications and situations. I knew a lot about how NHibernate was built, how it worked, and what it's capabilities were. However, all of this knowledge was not a substitute for a real understanding of NHibernate. My knowledge of how it worked led me to some conclusions that I don't think are correct anymore - trying to apply NHibernate in situations where it really was not the right answer. 

I've seen the same problem occur multiple times in the last 6 months, and in the last 11+ years of my career. There's almost a recognizable pattern to the learning process:

  • Learning curve to gain working knowledge
  • Knowledge growth and intimate familiarity
  • Assumption that knowledge gained is a substitute for experience and understanding
  • Attempts to apply knowledge incorrectly / in wrong situation
  • Realization that knowledge is not understanding or experience
  • Stepping back from knowledge to gain understanding of how/when to apply the knowledge

I've done this with Agile/Lean software development as well, recently. I've gained a significant academic knowledge of agile and it's processes and practices. Some of my knowledge is directly backed up by experience, so I believe I do have some understanding of the agile engineering practices. However, I've let my limited understanding mix itself into my academic knowledge a little too much. I've found myself in situations recently where I'm arguing a logical conclusion to a situation and applying it to another situation incorrectly.

One of my coworkers likes to apply this adage to situations like this:

If a hammer is the only tool you have, everything looks like a nail.

I need to remember to step back from my raw knowledge - be it academic or real world use - and let common sense and experience interweave into understanding or the realization that I don't understand. I need to understand that just because I am currently holding a hammer, and thinking about hammers, that doesn't mean that the problem in front of me is a nail that needs to be hammered.

The realization that knowledge is not a substitute for understanding can be a very distressing and/or humbling experience. The reality of learning, knowledge and understanding, though, is that I can have every last bit of knowledge on a subject - but without experience to guide me, I can't always understand the where/when/why/how of applying that knowledge appropriately.

Wednesday, April 16, 2008 8:43:31 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | General | Management | NHibernate | Philosophy of Software | UnitOfWork

 Tuesday, April 08, 2008

I'm chugging the cool-aid as quickly as I can mix it. This morning, I opened a pack of index cards with the intention of taking notes in a non-linear fashion (oh, the freedom my brain finally found). By the end of the day, I was hanging user stories on my cubicle wall to manage all of my administrative responsibilities. After all - if it's good for managing software development, why wouldn't it work for managing my daily / weekly administrative tasks (server maintenance, training coordination, permissions on various things, working with various people for various goals, etc).

IMAGE_113

On the left side of the divide (created by the wall segments - makes it easy) is my back-log. On the right is my in-progress list sorted by highest priority at the bottom. The done list is the trash can you can't see on the floor.

Tuesday, April 08, 2008 6:48:21 PM (Central Standard Time, UTC-06:00)  #    Comments [1]. Trackback 
Tags: Agile | Management | User Stories

 Sunday, April 06, 2008

Or communicate... or both.

  • If you have a problem in an application and there is more than one developer working on the project, be sure to clearly communicate who is working on the problem. Otherwise, you'll end up with two people writing the same code in the same place, duplicating the effort and wasting at least one person's time
  • If you need more than one person working on the problem, make sure that they are working together, closely, to avoid the same problem
  • If you need input from other resources, be sure that the entire team working on the problem is involved in those conversations or is at least given a summary of the conversation, so that you don't have to go back to the external resource over and over again, to get the same information
Sunday, April 06, 2008 3:20:32 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Management

One of the primary goals of Lean Manufacturing in the elimination of waste. This may seem like an obvious goal - after all, who wants waste in their system? What's really interesting, though, is seeing where the term "waste" is actually applied and how Toyota redefined what waste really is.

Muda, the concept of the seven wastes in the Toyota Production System, is a very different concept of waste than most of us would consider. It talks about not only physical waste (trash), but also logical, time, and effort waste. These seven wastes include (from Wikipedia):

  • Defects: Quality defects prevent the customers from accepting the product produced.
  • Overproduction: Overproduction is the production or acquisition of items before they are actually required.
  • Transportation: Each time a product is moved it stands the risk of being damaged, lost, delayed, etc. as well as being a cost for no added value.
  • Waiting: Refers to both the time spent by the workers waiting for resources to arrive, the queue for their products to empty as well as the capital sunk in goods and services that are not yet delivered to the customer.
  • Inventory: Inventory; be it in the form of Raw Materials, Work-In-Progress (WIP), or Finished Goods, represents a capital outlay that has not yet produced an income either by the producer or for the consumer.
  • Motion: As compared to Transportation, Motion refers to the producer or worker or equipment.
  • Overprocessing: Using a more expensive or otherwise valuable resource than is needed for the task or adding features that are designed in but unneeded by the customer.

In "Lean Software Development: An Agile Toolkit", Tom and Mary discuss The Seven Wastes and offer a great set of parallels in software development. Rather than copy & paste what they've already said, I wanted to offer my own interpretation of these wastes - some of which are the same as Tom and Mary's.

Defects

This is exactly what it sounds like - a bug, a piece of functionality that doesn't work right, or an exception that gets thrown in the system and causes problems. How many hours, days and weeks have you spent fixing defects in software, in your career? Personally, I can't even begin to accumulate the time spent - it's far too great.

Part of the problem here, and what really makes it wasteful, is when defects are found and fixed in most software development cycles. In Code Complete 2, McConnell talks about the cost of defects in software, relative to when the defect is found and corrected (pages 472 & 473). If the cost of fixing a defect goes up over time, then the amount of waste also goes up. In other words, the higher the cost of fixing a defect, the more waste that defect has generated.

With the increasing cost of defects in mind, we will want to reduce the time to find a defect so that the amount of waste generated can be mitigated. In Lean Manufacturing, this is achieved by only creating what is needed for an actual customer order, right now. If one part is produced with a defect, that one part is scrapped and a new part is created, correcting the defect - the waste is minimal. Imagine a mass-production system where parts are created in batches of ten thousand. What happens if there is a defect caused by the process? We end up with a significant amount of waste, because we will have to scrap the defective parts in batches of ten thousand - the waste here, is significant.

The same principle holds true in software development. If we are writing code for extensive periods of time, and that code is not being tested until the end of that period, then the cost of finding a defect in that code goes up. If we have ten lines of code that rely on the defect working the way it does, it is significantly cheaper to fix than if we have ten thousand lines of code relying on the way the defect works. The easiest way of reducing the number of lines that rely on a defect is by working in small iterations. If that defect goes into test after two weeks, it will be much cheaper to fix than if it had gone in to test after two months. Additionally, if automated tests are done and can be run against the system on an even shorter schedule, then the cost of finding the defect may be even less. If the automated tests are run every twenty or thirty minutes, you may only have two or three lines of code that are affected by the defect.

Overproduction

There are several common terms for overproduction, in software development - Over-Engineering and Coding For The Future, for example. Both of these problems result in the same thing - too many features and more functionality than is actually needed right now. Additionally, overproduction can be called technical debt. The idea is that there is code in our system that will need change - when this code needs to be changed, how difficult is it to change; what is the cost of the change (how much debt are we in).

If a developer is tasked with creating Feature-X, they should focus on the core business value of that feature when writing the code. It's very easy for that developer to think about "what-if" scenarios and "we may need to" future functionality. However, this type of thinking leads directly to overproduction. If the business has not identified the "what-if" scenario, then why should the developer assume that handling the scenario would add business value? If the business has not yet identified Feature-Y or specified any additional functionality in Feature-X, then why should the developer assume that coding for the possibility of Feature-Y is valuable? Take note of the pattern in those questions - assumption. Assumption on the developer's part leads directly to the overproduction of the system being built.

So how do we prevent this overproduction? First and foremost - stop assuming you know what's coming down the line, or what will provide business value. If you believe that the specs you are currently working with are not accounting for an actual problem, then the responsible action is to discuss that issue with the customer / business analysts. Secondly, if you find yourself wanting to code for the feature that may be coming down the line - stop. Don't do it. Even if you know that this feature or functionality is coming down the line, it may not provide any business value for the current feature(s). You may be causing detriments to the business value of what is currently being built. If you truly believe that the feature you want to code is required for the feature that you are coding, then you need to go back to the customer / business analyst again, and discuss it with them. Let the customer tell you whether or not there is value in adding that feature now vs. later (vs. if at all).

Transportation

Think of transportation in the context of knowledge. No one knows everything about a particular domain or project, and possibly an individual feature. We have business analysts and customers precisely because of this. Eric Evans discusses knowledge crunching (the process of learning and gaining an understand of the domain in question, to create a model) in Domain Driven Design, in the first chapter. Tom and Mary talk about the process of learning all throughout the "Amplify Learning" chapter of Lean Software Development. There are countless other books on requirements gathering, model creation and other learning processes for software development, as well.

The problem that we face in our learning is that the transportation of knowledge, from one person to another, will always introduce change. Every person in existence has their own unique way of understanding, based on their experience, existing knowledge and methods of knowledge retention. To illustrate this, look back at your childhood. Did you ever play the "telephone" game where one person whispers in the ear of the person next to them, then they whisper the same thing into the ear of the person next to them, and so-on until the last person in line? What are the typical results of this game? More often than not, the message had some fundamental change to it throughout the transmissions. As simple as the telephone game is, it's a perfect illustration for knowledge transportation that occurs in software development projects.

How many times have your received a functional specification or requirement for a feature, and had no clue what it was trying to convey or what the functionality was supposed to be? This happens on a very regular basis. The problem may not be that the documentation is inadequate, but that the transportation of knowledge from one person's mind onto the paper and into your mind is inadequate - what makes sense to the document writer(s) may not make sense to you, because your contextual knowledge of the subject is different. This problem is exacerbated by design-up-front project methods. The knowledge is often crunched from the customer's mind into the BA's mind, and then trampled down into a linear document or subset of knowledge in a documentation set where the developer has no direct access to the customer - the source of knowledge - for clarification and discernment of the details. Even if the customer is on-site sitting next to the developer throughout the creation of the documentation, there is still a transportation problem in design up front projects. Whether or not the developer understands the information during the conversations, there is little chance that the developer will remember every detail of the information when they finally get down to coding.

The solution for the transportation of knowledge is ensure that the knowledge is transported as little as possible. Rather than focusing the effort of documentation on every last possible detail - creating tomes of documentation that no one is really willing to read - we should focus on creating higher level guidance; enough knowledge to know the direction of the development effort and the features to be created, with the understanding that the final details will come from the customer just-in-time for the development effort. In the world of lean manufacturing, this is typically done through the Kanban system. In software development, we have adopted the same process through the use of User Stories being written on index cards. The stories are not the final word in the development effort - they are merely a placeholder for a conversation between the customer and the developer.

Waiting

This is likely the most obvious of the seven wastes, when applied to software development. Whether you are waiting for a customer or business analyst to be available for questions; waiting for a requirements document to be signed off; or waiting for your next assignment of work, the simple process of waiting creates lost time which directly translates to lost opportunity. In the extreme cases, the problem is compounded by context switching. If you are waiting for a question to be answered - whether this means waiting for a phone call, a document to be written, or just walking down the hallway - you can easily lose your focus or lose you place in the code or coding process. When this happens, most people take a while to restore that focus and get back into the mind set where the new knowledge is useful. In my experience (no real data, just my experience), the average time of context switching within the same project is as little as five to ten minutes for wind down, and at least ten or fifteen minutes for spin-up. If you are context switching between multiple projects, though, expect to spend much longer on the spin-up; hours, even days, depending on the project and time between wind down and spin-up.

If we can ensure that we never wait longer than it takes for us to wind down, then we should be able to eliminate the spin-up period; thus reducing the effort required for reestablishing our focus on the feature(s) at hand. However, the solution for waiting may not be as obvious as the problem. If you are waiting for documentation, or if you are waiting for the customer to sign off on a feature or change, the way to eliminate the waiting is to eliminate the cause. Don't rely on heavy documentation or require customer sign-off on features. If we are working with the customer every hour of every day, eliminating the knowledge transportation issues, then we can also eliminate much of the waiting game by having the customer available. When the customer is available immediately, we have a much greater chance of the conversation beginning within the wind down period. When this occurs, we can stay focused on the problem at hand, and mitigate the spin-up period when we return to the code.

Inventory

Inventory in a manufacturing or supply context is typically a product or component of a product that is in storage and waiting to be used; or "a list of goods and materials held available in stock by a business" (Wikipedia). In software development, we only need to translate "good and materials" into "code and resources":

A list of code and resources held available in stock by a business.

Think of software inventory as unfinished code (as defined in Lean Software Development) or as overproduction of code. If we have unfinished code in our system, this is like having a physical component for a product - the component by itself is not useful until it is in the completed product. Similarly, the unfinished code provides no value to the software until it is finished. Even if the code is complete, if it is not being used in the software then it is dead code and is inventory for the software.

Inventory, in software development, carries a significant technical debt - the unknown factor of whether or not the code actually needs to be in the system. The longer we let inventory live in our code, the more likely we are to forget whether or not that code needs to be there. This inventory also becomes a potential mine field for developers - what happens if a developer sees this dead code and assumes that it is still functional and valid? If we are lucky, the code will work as advertised. The longer the code sits in inventory, though, the more likely it is to be outdated, invalid and eventually non-functioning.

Motion

In addition to physical movement causing waste through waiting (walking down the hall to the BA's office), motion can also be applied to the processes of producing the executable software (not the source code and other resources). How much effort does it take for your team to compile the resources, create the executables, package it into an installation and deliver it to QA, the customer, etc? The goal should be to make this as simple as possible - as little movement as possible.

Are you able to click a button and have the build, package, and delivery processes handled for you automatically? Or does it take a team of developers, build engineers and other persons with a manual process and a checklist of things to do? If your process involves people performing manual tasks - even if that task is simply the order in which multiple buttons get clicked - then you are at risk of creating waste through defects. Every manual motion in your build process is another point at which mistakes can be made, allowing defects to be built or causing the build to fail completely.

Software production (again - speaking about production of executable software, not development of resources or code) is often a difficult, tedious chore, requiring many moving parts - there is no way around this. However, it does not have to be a manual process. Continuous Integration and Continuous Deployment practices are abundant in the world of software development, specifically to address this issue. If you can automate your build process and eliminate the manual movement involved, you can eliminate a huge source of potential waste.

Overprocessing

Overprocessing, or too much process, is abundant in software development. When a customer has a request for a feature, how much process does it take for that feature to become functionality? In design-up-front project life cycles, the process of adding or changing a feature can be very time consuming, involving many steps on both the requester and implementer side:

request; acknowledgement and change management / approval; design and documentation by implementation staff (BA's, developers, etc); sign off of design and documentation by customer; implementation in software; scheduled for testing; tested; and if any issues are found, back to design or implementation for corrections, repeating several steps.

Additionally, how much work does it take for you to get your job done, as a developer? Do you spend as much time updating task / issue management tickets and managing your manager, as you do coding?  Too much process in software development is as bad, if not worse, than no process at all. Unfortunately, the failures of too much process are often seen as an indication of the need for more process, causing further delays and waste in the system.

There are often situations where you cannot do anything about the process that is in place. Life-Critical systems (x-ray machines, air plane guidance systems, etc) are abundant with process for good reason - if anything fails, people could be injured or killed. In the world of business software, though, this is not usually the case. Most business has a level of fault tolerance built into it, and some waste is expected / accepted. This is not a get out of jail free card, though. The more significant the waste, the more repercussions there are - fix the defect; pay for lost revenue; lose your job; etc. If we want to eliminate waste through the simplification of process, then we need to ensure that defects are found and fixed as early as possible, to avoid creating waste for the business using the software.

Process simplification can be done many different ways. Start with the creation of a process flow char, or value-stream chart. Find out how much time and effort is wasted in your processes and look for the waste that can be easily eliminated. Simplifying a single process by removal of waste can lead to a revolution in your process. You may find that the removal of one process negates the need for another process. You may also find that a simple change to one process does the same. If you are able to bring your customer into the work area with your team, and work in short iterations where defects are found and fixed quickly, you will likely see many of your old processes quickly become obsolete.

Conclusions

No one wants waste in their systems. Waste is money lost and revenue not earned. Waste management, though, can be a difficult proposition. Many company are willing to accept waste as the cost of doing business and are not willing to spend money eliminating waste because they do not see the waste or do not believe it can be eliminated. If we are truly going to revolutionize the business we work in, we must eliminate waste. Start where you have direct control or influence. You'll quickly find others wanting to know how you are so productive and soon the entire business will be in full waste reduction cycles.

Sunday, April 06, 2008 3:05:30 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Behavior Driven Development | General | Lean Systems | Management | Philosophy of Software

Navigation
About Me
View Derick Bailey's profile on LinkedIn

Send mail to the author(s) Contact Me
Archive
<April 2008>
SunMonTueWedThuFriSat
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Derick Bailey
Sign In
Statistics
Total Posts: 65
This Year: 65
This Month: 4
This Week: 0
Comments: 25
Themes
Pick a theme:
All Content © 2008, Derick Bailey
DasBlog theme 'Business' created by Christoph De Baene (delarou)