var blog = new ThoughtStream(me); RSS 2.0
 Friday, February 27, 2009

Quality must be built in, it cannot be added on. … well, ok. I’ll admit that it’s not entirely true. If you don’t mind spending exorbitant amounts of money doing rework, causing projects to be late and over budget, and possibly losing the business, then by all means, wait until after-the-fact to try and add quality onto a product. No really. It can be done. You just have to accept that the system will be rewritten. After all, isn’t that the way software development goes? Build something… try to add on to it… recognize the problems that prevent you from continuing and then justify starting the same vicious cycle over. (How arrogant are we, as software developers and development teams, to expect our customers to accept this? But, I digress…)

We already know that the real world builds quality into their products by favoring defect prevention over quality inspection. What we often don’t realize, though, is the real cost of not building in quality from the start. So, what are the costs and effects of trying to add-on quality after the fact? Before I go down that rabbit hole, though, I want you to understand how I define quality, at the moment. Without this understanding, the illustration is far less effective.

Defining Quality

I’ve run across a lot of definitions of ‘Quality’ over the years. Some of them good, some bad, some so far off from the truth that they would cause me to laugh if I didn’t know someone truly believed them. After all this time, I’ve begun to settle on my current favorite definition of Quality as: conformance to requirements.

Yes, I understand the somewhat naive focus that this definition of quality presents. However, I have yet to find as solid a foundation for quality as this. The Wikipedia entry for Zero Defect, from which I take that definition, continues to say this about quality as conformance to requirements:

“Every product or service has a requirement: a description of what the customer needs. When a particular product meets that requirement, it has achieved quality, provided that the requirement accurately describes what the enterprise and the customer actually need. This technical sense should not be confused with more common usages that indicate weight or goodness or precious materials or some absolute idealized standard. In common parlance, an inexpensive disposable pen is a lower-quality item than a gold-plated fountain pen. In the technical sense of Zero Defects, the inexpensive disposable pen is a quality product if it meets requirements: it writes, does not skip nor clog under normal use, and lasts the time specified.”

In summary - the customer is the one that defines quality. That’s a much less naive view than the definition betrays.

More Than Meets The Eye

Saying that the customer defines quality is still somewhat naive – at least on the surface. It is true that the customer is the final authority on whether or not the product is quality. However, the reality of quality in software development is that there’s more too it than just meeting the current requirements. As I’ve previously talked about, I think quality is more of a two-sided coin in software. On the one side – the primary side – you have conformance to requirements. That is, what the customer actually needs to help solve their business needs. On the other side of that coin is the technical quality, as defined by the known best practices and standards that we adhere to as individual developers, team members, companies and larger communities. (Side note: More often, I’m finding it easier to define what quality in software is not, rather than what it is.) That being said, I’ll leave the definition of quality in software engineering to those previous and future discussions.

Getting back to the original point I was making, I’d like to illustrate a situation that I’m very familiar with on the cost of not building quality in from the start.

Creating The ‘Perfect’ Failure

A long time ago, in a company far far away… [insert star wars theme]… there was a product under development. To protect the guilty innocent, we’ll call this project “ProjectX”. ProjectX’s customer was a very large entity, with lots of software products and projects that had been developed by many many software providers in the past. So, when ProjectX was first delivered to this customer and the customer said “It’s PERFECT!”, there was much rejoicing on the part of the software provider. In fact, ProjectX was deemed so perfect by the customer – having met every requirement, with less than 1% of the functionality being deemed ‘flawed, but still usable’ – that the customer declared ProjectX’s test results and acceptance as ‘the new standard’, across the board.

But there is more to ProjectX than the initial quality that the customer observed. In fact, ProjectX had a deep, dark, disturbing secret just waiting to rear it’s ugly head. That secret was the distinct lack of quality that the software provider had built into ProjectX. Everyone at the software provider knew the lack of quality – it was a necessary business decision to role ProjectX out the door as quickly as possible.

Fast forward 5 years, now. ProjectX is still a living, breathing, changing system. The customer, over the last 5 years, has requested numerous enhancements, requirements changes, and other stuff for ProjectX to do. While working on these new requirements and changes, the software provider found themselves in a sticky situation. Since they had set ‘the new standard’ with the customer – a standard so high, that they were now expected to deliver ‘on time, under budget, with perfect quality’ – the customer expected the software provider to continue meeting ‘the new standard’. Since the software provider knew that the original business decision to sacrifice quality for speed would come back to haunt them eventually, the software provider spent inordinate amounts of time trying to rectify the situation. They re-implemented parts of the system that were being modified, and introduced new architectures and standards when features needed them, and they worked 60 to 80 hour weeks for months – nay, years – on end, trying to introduce quality into ProjectX.

With each successive delivery of new features and functionality, though, the customer began to notice a distinct drop in quality. In fact, there was an alarming trend in the quality of the product, over time. The customer began to track the ratio of defective to non-defective functions, and they began to complain about the problems that ProjectX was having. Eventually, the customer’s user base refused to install the latest version of ProjectX because of the large number of known issues in ProjectX.

The customer became very upset at this new trend and many discussions with many sad users were had. And there was much sadness at the software provider. Questions were asked. Fingers were pointed. Many more discussions were had, and so-on and so-forth. The software provider, not willing to accept the new state of their software, decided to fix things… but that’s another story.

How ‘Perfect’ Failed

So how did a system that was deemed ‘perfect’ by the customer come to fail so miserably in the eyes of the same customer? The simple, honest, oh-so-hard-to-believe truth is that the software provider was unable to ‘add quality on’ after-the-fact. The software development team grew in their capabilities. They brought in new eyes and fresh expertise in development practices and architectures. They re-thought, re-structured, and re-worked so much of the system over such a long period of time. But it was never enough. There was simply too much of ProjectX that could not reasonably be changed and still meat the deadlines for new requirements, changes and enhancements.

Over time, the initial lack of quality that was built into ProjectX rotted the system, from the inside out. Because ProjectX was unable to modified to meet the new requirements without breaking the old requirements, the customer no longer saw ProjectX as a quality product. The cost of this lack of quality was tremendous – the software provider’s reputation had been tarnished, the customer did not trust the provider and did not want to use ProjectX anymore, and the software provider had a legitimate chance of failing as a company and shutting its doors.

Conclusion: Build Quality In Or Risk Losing Your Lunch Money

Creating a quality product really is a two sided coin. If you create the perfect system in the customer’s eyes, but you can’t maintain that system and add new features and functionality – where is the quality? You’ve effectively put lipstick on a pig and called it a supermodel. But if you have the ‘perfect’ engineering practices and the ‘perfect’ system that is ultra-easy to add features on to, and no one wants to buy the product because it does not solve any real business problems or provide anything that a customer actually wants or needs, then where’s the quality in that? You’ve effectively delivered a Lexus LS-400 when the customer asked for a ham sandwich.

It is imperative that quality be built in to a product from the start. We know how to do this. We are (or should be) standing on the shoulders of giants. We only need to keep in mind both sides of the coin when creating the needed quality. Customer quality first, with engineering equally as important after the customer says ‘PERFECT!’.

This is not just a scary bed time story and this is not just a bunch of ‘ivory tower’ fluff. “ProjectX”, despite a fictitious name, was a real project at a real company and the story I told is the boiled down version of really happened. In fact, it has happened at least once in every job I’ve had as a professional software developer. I know the cost of not building in quality from the start. I’ve seen my friends, coworkers and bosses lose their lunch money. It’s not a happy scene.



_________________________________
Cross Posted From LosTechies.com
Friday, February 27, 2009 12:58:47 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Management | Philosophy of Software | Quality

 Friday, February 20, 2009

I heard the phrase “one team, one aim” while listening to the audio book version of “Extreme Toyota”. This is a phrase that marks part of the core philosophies of Toyota, according to the book. There are many different philosophies that underlie this specific phrase and I’m sure there is a very large amount of text that can be written about it. Rather than jumping off of that deep end without a greater understanding than I currently have, though, I wanted to point out one very specific word in this phrase: “aim”.

Wiktionary has a definition of aim that appears to fit very well in this phrase: “Intention; purpose; design; scheme.

So, why use the word “aim”, here? Why not talk about goals? Why not deal with something more concrete? I think the answer to this is found in one of the core principles of Toyota: Continuous Improvement. A goal is a concrete, fixed point to be reached. Although a goal can change, once it does change, it once again becomes a fixed point to be reached. If Toyota talked about goals then they would inherently be limiting themselves to such fixed points of achievement. By using the word “aim” instead of “goal”, they are illustrating the true intentions of Continuous Improvement. That is, they are not setting their sights on attainable goals. Rather, they are taking a philosophical, yet very practical and daily routine of continuously improving in all aspects.

This does not mean Toyota works without goals. Quite the opposite, really. They create some of the most ambitious goals that anyone can imagine - “impossible goals” as talked about in the Extreme Toyota book. However, these goals are always aligned with the company’s vision, their aim. Toyota recognizes that a single goal is never a place to stop, having accomplished something, but is only a starting point allowing them to define the next goal and begin that leg of the journey.

As I’ve talked about before, we should be focused on the journey – the aim of where we are heading - constantly adjusting that aim as we obtain new information. We then set goals to help us move in that direction, knowing that we are truly on a journey, not looking for a place to stop after a single, fixed point of achievement.



_________________________________
Cross Posted From LosTechies.com
Friday, February 20, 2009 11:00:18 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Lean Systems | Management | Philosophy of Software

 Saturday, January 31, 2009

In the manufacturing world, you would never find a company that assembles a bunch of parts into a final product before inspecting any of the individual parts, and they would not wait until the end of the assembly line to test for the quality of the product. The very notion of waiting until the product is “done”, to test it, would be appalling. How much time and money would be lost trying to figure out why something didn’t fit together properly, why it didn’t work, and why there was a quality issue with the final product? Rather, we see the manufacturing world taking an active role in preventing defects. Yes, they still do a final quality inspection, but the primary means of ensuring a quality product is delivered is not by waiting until the product is assembled to test it. They build quality in from the start and maintain that quality throughout the manufacturing process.

Prying Open The Case

IP Phone picture borrowed from Wikipedia

Imagine the inner workings of the phone to the left. This is a very complex piece of technology. Do you think Cisco would wait until they have assembled this phone and then try to pry open the case so that they can insert a set of electrodes to test and see that the circuit board is connected correctly? I certainly hope they don’t. Instead, when a manufacturing company is building something – anything – they start with the idea of preventing defects, not waiting until they are identified and correcting them. Many companies have an active Zero Defects policy where defect prevention is paramount and quality inspection is almost just a verification of what they already know – that the product is defect free.

When a part is stamped out, formed, molded, or otherwise created, it is done so to an exacting specification. After the part has been created, the part is then tested against the same specification to which it was originally built. If the part does not fall within the tolerance and guidance of the specification, it is scrapped and a new one is made. If a series of parts are found to be out of specification, it’s usually a sign that something in the process, tooling, or other portion of the manufacturing process is not right. When this happens, they fix the cause of the problem – whether the machines need to be calibrated, the people running the machines need better instructions or whatever the cause is. In the end, the specifications for the parts were used to create the part, identify whether or not the part was up to standards, and decide whether or not to keep that part.

Vernier caliper picture borrowed from WikipediaWhat’s more, the manufacturing company doesn’t wait until after they start creating parts to create the specification. Rather, they take the time to properly engineer the specifications up front. They take measurements, create prototypes with varying specifications to see what works best, record the success and failure rates of the various specifications that are tried, and use other design and engineering principles to scientifically calculate the exacting specifications that will be used to produce the parts. This occurs at all levels of the product’s design and creation. For every resistor, capacitor and microchip that builds a circuit board, each one of them has their own specifications that have been carefully engineered. If any single capacitor does not meet the specifications, it is not sent to Cisco with the hopes that it works anyways. Only when all of the specifications of each part are met will they solder the parts to the circuit board, creating a subassembly.

When a subassembly is created, it also has a specification to which it was built. The subassembly then undergoes the same quality assurance process – verification that it meets the specifications and operational requirements. The process continues from here – each subassembly gets connected to a larger system which is built to a set of specifications, with rigorous testing of the larger system as it is built, ensuring it meets the specifications. When the final phone is assembled, we don’t have to worry about whether or not a specific capacitor is soldered to the correct location – we don’t have pry open the case on this phone and insert a set of electrodes to see if the electrical current is flowing correctly. Instead, we only need to plug this phone into the correct connections (an Cisco IP phone system in this case) and verify that the phone actually performs all of it’s functions, according the functional specifications of the phone. There simply is no need to verify the capacitor that was used in the very first step. We know it works because it was built in a system that actively prevents defects.

The manufacturing world is obsessed with testing. They are willing to test from the lowest possible levels of the system, out to the end-product and the behavior that is expected. They do this because the consumers of manufactured products demand perfect. Why, then, are so many software development companies so willing to only test from one end of the process? To only test once, and only from the user interface, just before the product is shipped?

A Specification By Any Other Name

Unfortunately, the software development industry as a whole, is years behind the manufacturing industry. Our definition of quality and success are often skewed and we may consider fifty or more known bugs in a system of moderate to large size to be acceptable. It doesn’t have to be this way, though. We have the technical capabilities of following in the footsteps of the manufacturing industry, and we should.

I’m sure there would be no small number of people that would say we already employ the use of specifications in software development. After all, that’s what the requirements gathering phase is for, right? So many software development companies have put so much effort, time and money into the process of producing a piece of paper that can be understood by humans, and labeled this a specification. The problem we face with paper, though, is how to effectively verify the software against what the paper says. How do we verify that series of software lines and I/O statements that are understood by a computer have actually implemented the human readable text on the paper?

We are fortunate, actually. We don’t have to accept a Word document or a piece of paper as the specification to build to. We have the ability to create executable specifications! We can, and should, be creating specifications that can measure and verify our code. Most people call it test driven development (TDD). Some call it Behavior Driven Development (BDD). I like to think of it as Specification Driven Development (SDD? Not sure if that really exists. And really, do we need another xDD acronym?). We write code that exercises our code in the form of unit tests, integration tests, functional tests, acceptance tests, or whatever you want to call them.

We’re Not Just Stamping Out Parts

Image borrowed from Wikipedia One of the major problems that I have with the manufacturing/software development analogy is the obvious statement that we don’t stamp out the same parts over and over again. In spite of my previous comments on this analogy, I now think that we are more analogous to a specific part of manufacturing than I had previously understood. A more accurate representation of software development in the manufacturing world is new product design and development. The parallels work quite well from this perspective. I am not going to expound on this in great detail at this point. It should suffice to say, for the moment, that the process of product development described in Wikipedia is a fairly accurate representation of what we go through for the average software development project.

When a manufacturing company is working on a new product, they once again don’t stamp out parts without knowing what they are doing. Many different parts may need to be tested, many different designs may need to be tried, but every one of these is still built to a specification. The major difference is that the specifications used are expected to change over time, until the final specification for the final pieces are accurate enough to produce a production-ready prototype.  The same notions can be applied to the software development processes in TDD, with some additional benefits.

Built To Specs, Regression Tests And Change

Change happens. It’s a simple fact of software development. A customer thought they wanted X, but in reality they needed X-1/B – not quite what we originally thought. When this happens, we once again have a significant benefit created by our executable specifications. We only need to identify those specifications that are now wrong, correct them, and change the affected portions of the system to match the new specifications.

Our ability to change is direct evidence to one of the many benefits of TDD: regression tests. Every specification that we write becomes a regression test the moment we fulfill that specification’s requirements. With this in mind, we can work with an almost reckless abandon, free to add features, remove features, fix bugs (because let’s face it – we’re still going to find some issues somewhere in the system) and refactor the system to a higher standard, all without worry of breaking the system. We can act with this level of confidence because we have a safety net in our regression tests. If (when) we do break something in our new efforts, we will be notified the moment we re-execute our specifications – that is, run our regression tests. A specification test will fail and we will have a clear indication of what failed and why. This deep insight into the system gives us even further confidence in correcting any issues that we introduce. When a failed specification test tells you exactly which value from which class is wrong, and the context in which that class was executed is known (the exact input and expected output), pinpointing the problem becomes a rote process. Fixing the issue becomes relatively simple, and we begin to see true productivity improvements in our processes.

Start With Quality, End With Quality

Our industry is currently suffering from a lack of quality. We ship horrendously bad user experiences in products that are late and well over budget, yet we call this a ‘success’. It doesn’t have to be this way. If we change our perspective and start to take some cues from the manufacturing and product design and development world, we can dramatically increase our effectiveness as software developers. We can create high quality, low cost solutions like the world expects from manufacturers. Built to specification is certainly not a silver bullet. It is, however, the definition of quality in a Zero Defect environment.

By employing a built to specification mindset in our software development efforts, we can start with quality and maintain that quality throughout the life of our projects. This is the same process that is undertaken when a manufacturing company is working on new product design and development. It works well, it’s a proven process, and most of all – it makes sense. Build your software to specifications. Just make sure they are executable specifications.



_________________________________
Cross Posted From LostTechies.com
Saturday, January 31, 2009 12:04:38 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Analysis and Design | Behavior Driven Development | Lean Systems | Management | Philosophy of Software | Refactoring | Standardized Work

 Wednesday, January 28, 2009

I recently saw this question asked and answered in an after-project retrospective paper.

Was The Project A Technical Success?

While I am not trying to address who asked the question or what the answer was, the question on it’s on own, is flawed in my mind. Or, at least when taken out of context, it has become somewhat of a fallacy by standing on its own.

Not ‘Technical’, But ‘Operational’

The question we should be asking first is not about ‘technical’ success, but ‘operational’ or ‘business solutions’ success:

Was The Project An Operational Success?

That is to ask, did we effectively reduce or solve the stated business problems to an acceptable level, allowing the users of the application – the operational people - to be more accurate, efficient, productive, responsive, … etc, in their job? Only when we can answer “yes” to the project being an operational success, and provide sufficient evidence of this success, should we ask if the project was a technical success.

If we created the world’s most perfect architecture, design and implementation, but the project was a DOA failure because it did not solve or sufficiently reduce any stated business problems, resulting in no one to buy it or use it; what good would it be to have the perfect system from a technical standpoint?

The counter-perspective, though, is just as important. If we have managed to solve or sufficiently reduce the stated problems then we need to ask if we did so in a manner that allows us to maintain this system for the long-term life of it. Were we successful in our technical implementation of the business solution, thereby allowing us to continue solving additional / ancillary business problems, easily and efficiently?

Two Sides Of The Same Coin

We can’t sacrifice the needs of the business to create what we believe is a successful technical implementation. Yet, we can’t sacrifice the technical implementation just to satisfy the needs of the business. There is a marriage between the two – they are (or should be) two sides of the same coin. If we fail on either aspect and are not able to recover quickly, we will eventually fail as a project / product team.



_________________________________
Cross Posted From LostTechies.com
Wednesday, January 28, 2009 6:52:19 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Management | Philosophy of Software | Retrospectives

 Friday, January 23, 2009

Manage up. Lead out and down.

You ARE A Manager

If you work FOR anyone, in any context, you’re a manager. You mange your boss’ expectations of when you will have something completed. You manage your customer’s expectations of what the software will look and behave like, how it will perform, and when it will be ready for testing. You manage your own time and resources to make sure that you can get things done, prioritizing based on many factors (often external factors and influence). The point is – you ARE a manager. Period. All of you. End of discussion.

You SHOULD BE A Leader

If you work WITH anyone, in any context, you should be a leader. You should never manage those you work with or those that report to you in any capacity. You should lead them by enabling them and empowering them to get their job done. You don’t manage your peers – you lead them. You influence them by showing them new and better ways of working, discussing the pros and cons and coming to conclusions that benefit everyone involved. You lead your subordinates the same way, but with the option of overriding decisions for business and/or quality and technical reasons. You lead your subordinates by blocking the stupid and detrimental from them. You lead your subordinates by letting them get their job done while you head off the office politics.

Manager Or Leader?

Are you a manager? Yes. Are you a leader? You should be.



_________________________________
Cross Posted From LostTechies.com
Friday, January 23, 2009 10:56:47 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Management

Manage up. Lead out and down.

You ARE A Manager

If you work FOR anyone, in any context, you’re a manager. You mange your boss’ expectations of when you will have something completed. You manage your customer’s expectations of what the software will look and behave like, how it will perform, and when it will be ready for testing. You manage your own time and resources to make sure that you can get things done, prioritizing based on many factors (often external factors and influence). The point is – you ARE a manager. Period. All of you. End of discussion.

You SHOULD BE A Leader

If you work WITH anyone, in any context, you should be a leader. You should never manage those you work with or those that report to you in any capacity. You should lead them by enabling them and empowering them to get their job done. You don’t manage your peers – you lead them. You influence them by showing them new and better ways of working, discussing the pros and cons and coming to conclusions that benefit everyone involved. You lead your subordinates the same way, but with the option of overriding decisions for business and/or quality and technical reasons. You lead your subordinates by blocking the stupid and detrimental from them. You lead your subordinates by letting them get their job done while you head off the office politics.

Manager And/Or Leader?

Are you a manager? Yes. Are you a leader? You should be.



_________________________________
Cross Posted From LostTechies.com
Friday, January 23, 2009 10:56:47 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Management

 Tuesday, January 13, 2009

For so long there have been so many advocating the benefits of the various Agile, Lean, Iterative, or whatever-you-want-to-call-it-these-days methodologies. We, as software developers, seem to understand the benefits of these methods. So why, then, do we still have customers that insist on big design up front, waterfall based methodologies, and other practices that we know are wrong?

Some Ad-hoc Consulting

During my Christmas vacation, I had the opportunity to do some consulting / coaching for my dad’s current company. The employee list that I spoke to consisted of my dad, my aunt, and my cousin. It was a nice little family gathering, I got paid with some amazingly good barbeque, and it was a very enjoyable experience.

I’m a software developer working for a company that provides software development and related services. My dad’s company is a customer of a software development organization (not the one I work for), receiving some custom built software for a project. They have been running into some issues with quality and timeliness of delivery for the last year or so and were wanting to ask some very pointed questions about the state of the software development industry. Essentially, they wanted me to tell them whether or not the issues they were having are “normal” and / or “acceptable” when receiving custom software development services. My answer was an unfortunate “yes, this is normal”, but “no, this is not acceptable”.

Over the next few hours of our discussion, we touched on many different issues that they are having and how some of those issues can be addressed from their perspective and from the perspective of the software development supplier. In the end, I had successfully educated my dad’s company on a few key points, confirming their suspicions and observations, and giving some new directions to start heading with the company that is providing the development services. I can’t go into all of the detail, but the summary bullet points included the following:

  • The customer won’t know what they want until they see something they don’t want
  • The software provider should deliver a working, stable version of the system on a regular basis, allowing the customer to use it in it’s current form
  • The customer sets the priority of features and functionality to be implementing, in coordination with the technical needs and pre-requisites of the software development organization
  • The customer is allowed to say something is wrong, even when they receive what they asked for
  • The relationship between the customer and service provider must be a whole-team view. That is, “we are one team. we succeed together and we fail together”

On top of these bullet points, I laid out a simplified Scrum process for them, based on the already stated 3 week development cycle that the provider prefers.

In the end, my dad’s company was shocked, astounded, amazed, and energized by everything they heard. The light bulbs were clicking in their eyes, and I could see the value that they received form the conversations. They have dramatically changed their understanding of what it means to be a good customer and what it means to be a good supplier.

A New Perspective

As much as I believe I helped my dad’s company in their understanding of what they should expect and how they should approach their issues and needs, I also learned a great deal from this experience. It was very enlightening for me to hear the issues that we have known for so long as software providers, but from the customer’s perspective. Nothing that they spoke of was unknown or unfamiliar to me. I have lived through all of the same pains and issues that they are going through – from both a software provider and a customer of software services.

What really stuck with me from this experience, though, is the idea that our perspective on how to improve our industry is likely wrong. Yes, we need to continue educating our own ranks on the benefits of better software development techniques and processes. However, it does no good for us to have the perfect pneumatic toolset when the customer is asking us to use a rusted hammer and a broken hacksaw.

What I’m getting at is that its not us, the software providers, that need to change so greatly. Rather, our customer base needs to be educated and change. We need to stop being so self-centered and introspective for a while so that we can educate our customer base on what it means to be a good customer; how they can accomplish their goal of receiving quality software that provides true business value for them, at an affordable price. Until we have a customer base that expects software to be high quality, the first time, every time; expects to be given working software on a regular basis; and expects to be able to recognize that what they thought they wanted is not what they really needed; we will have no chance of our inward looking self-improvements taking hold.

I have to say, the Agile Manifesto got it right from a values perspective. The values espoused there are what we need to be looking toward, but I think our perspective needs to be changed on how we enable those values to be reached.

Of course, if we do succeed in educating our customers, we need to be able to respond appropriately. So please, continue the education of our own industry. Create better development standards that increase our quality and productivity. If our customer expects a quality delivery every 2 weeks, we better be able to deliver a quality product every 2 weeks. Just don’t stop here. Educate your customers. Help them understand the financial impact of poor development standards and processes. Change the norms and improve our industry by creating a customer base that requires perfect. The manufacturing industry did it 20 to 30 years ago. It’s time for us to step up to that level.

Where Do We Go From Here?

So where do we go from here? How do we start educating our customers? How do we change the social norms of software development so that our customers expect us to behave more like professional craftsmen and engineers, delivering quality faster?

I don’t claim to have the answers and I don’t claim to be the first to encourage this change. I only hope that we as an industry will begin to understand that the customer is usually the one that sets the expectation for how often software is delivered, and that we need the customer to expect something better.



_________________________________
Cross Posted From LostTechies.com
Tuesday, January 13, 2009 1:59:02 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Community | Lean Systems | Management | Philosophy of Software

 Monday, January 12, 2009

Imagine that there are three group of people going out for a hike. Within each group of people, we have a goal of everyone reaching a picnic table at the end of the hike (and no one can eat until everyone has arrived). One of the people in each group has a map and a compass, knows how to use them, and will be directing the group on where they need to be going (we’ll call that person “the Pathfinder”). Everyone else is just along for the hike and the picnic.

The Pathfinder in each group is given a specific set of instructions on how they are going to direct everyone else.

Group 1: Observe, Plan, Walk

  1. Stand on top of the large rock at the beginning of the hiking trail.
  2. Once you have a clear view of the area, plot a course in one hundred foot increments, with your map and compass.
  3. Using any means necessary (pencil and paper, verbal communication, etc), describe the direction that the group is supposed to be walking. Give an updated direction to walk every one hundred feet, enduring the group can go around any obstacles such as large rocks, impassable tree groupings, and small creeks.
  4. Once you have plotted the correct course, store the compass and map in your backpack with the understanding that you are not allowed to use them again, until you have reached the picnic area.
  5. Have the entire group read the instructions, then set out on your hike.
  6. You are only allowed to check that everyone is on course by re-reading the instructions that you wrote down, every 100 feet – when the team needs to change direction to avoid an obstacle.
  7. Once your group has reached the picnic table, record the time that it took for the hike to be completed by everyone – yourself included.

Group 2: Observe, Plan, Walk, Start Over, Verify; Repeat;

  1. Stand on top of the large rock at the beginning of the hiking trail.
  2. Once you have a clear view of the area, plot a course of one hundred feet using your map and compass.
  3. Using any means necessary (pencil and paper, verbal communication, etc), describe the direction that the group is supposed to be walking for the next one hundred feet, ensuring everyone in the group understands the directions.
  4. Place your compass and map on the rock, then hop down from the rock. Re-join your group and lead them in the right direction for one hundred feet
  5. Tie one end of a rope to a tree or post at the beginning of the one hundred foot walk.
  6. Travel the one hundred foot distance with your team, ensuring that they end up in the correct location.
  7. At the end of the one hundred foot walk, have the group stop where they are.
  8. Tie the other end of the rope to a tree or post at the end of the one hundred foot walk.
  9. Have you and your group observe the new surroundings and take note of any obstacles that were note previously seen, and offer suggestions on where to go next.
  10. With the help of the ropes to guide you, walk back to the rock at the beginning of the trails, by yourself, and climb back on to it.
  11. Plot the next one hundred foot leg of the journey from where the group currently is, using your map and compass.
  12. Repeat this process from step 3 through 11, until your entire group has reached the picnic area.
  13. Once your group has reached the picnic table, record the time that it took for the hike to be completed by everyone – yourself included.

Group 3: Observe, Plan, Walk, Verify; Repeat;

  1. Stand on top of the large rock at the beginning of the hiking trail.
  2. Once you have a clear view of the area and general understanding of how to get where you are going, plot a course of one hundred feet using your map and compass.
  3. Using any means necessary (pencil and paper, verbal communication, etc), describe the direction that the group is supposed to be walking for the next one hundred feet.
  4. Place your compass and map in your backpack, then join your group.
  5. Let the group know where they are heading (the end goal) and where they need to be in the next one hundred feet, ensuring everyone in the group understands the directions that you outlined.
  6. Tie one end of a rope to a tree or post at the beginning of the one hundred foot walk.
  7. Lead the group in the right direction for one hundred feet, ensuring that everyone is able to safely navigate any obstacles.
  8. Verify that that your group has stopped in the correct location, by using your map and compass and any other landmarks or means needed.
  9. Tie the other end of the rope to a tree or post at the end of the one hundred foot walk.
  10. Have you and your group observe the new surroundings and take note of any obstacles that were note previously seen, and offer suggestions on where to go next.
  11. Repeat this process from step 3 through 10, until your entire group has reached the picnic area.
  12. Once your group has reached the picnic table, record the time that it took for the hike to be completed by everyone – yourself included.

Predictions on Outcome?

  • Which group do you think will make it to the picnic site first?
  • Which group do you think will be the most happy with the way the group was organized and run?
  • Which group of people do you think would be most likely to do the same process on another hike?

Observations of the Groups

Group 1 didn’t get to the picnic site very fast and wasn’t very happy about the experience. While everyone in the group was standing around waiting, the Pathfinder was sitting on top of a rock, writing things down in a notebook, trying to describe – from a very high level, where people were supposed to be walking. When the Pathfinder finally came down from the rock – possibly an hour or more after he climbed up there – the initial directions were good and people could start finding their way. As time went on, though, the detail of where they should be going became more and more unclear, because the Pathfinder could not nee the actual pathways below the tree tops and behind the large rocks. This caused Group 1 to constantly stumble and struggle, creating a situation where the team had to find paths around obstacles that they couldn’t previously see. Every now and then, they got lost because the description of the landmark was insufficient from the distance that it was recorded. They eventually got to the picnic site – well after everyone was hungry and tired. In the end, no one was happy with the experience and just wanted to go home.

Group 2 had an easier time finding their way. Since the Pathfinder and the group were able to see all of the obstacles within one hundred feet, the directions that the Pathfinder described was much more enjoyable. No one stumbled over anything or got lost. But it was a difficult journey, at times. The group had to veer off the original course many time, in order to avoid some previously unknown obstacles. In the end, the Pathfinder did a great job of keeping everyone focused on the goal – the picnic table and food. The problem, though, is that the group took forever to get to the picnic area. At first, having the Pathfinder re-check the direction they were heading was great. Everyone knew that he was keeping the group on target. However, every time the group reached their next stopping point, the Pathfinder would gather information about the next hundred feet, across a wide arc since he didn’t know which direction to go next, with great certainty. Only then could he travel all the way back to the original rock to verify that everyone was on the right path, heading toward the picnic table. After a few iterations of hiking, the process of verifying the course and location took more time than the process of hiking. The Pathfinder was simply repeating the same hike over and over again, to verify that they were on the original path laid out. No one in this group was disappointed in the path that they took to get to the picnic table, but no one appreciated the standing around and waiting for hours on end – waiting for the Pathfinder to get the next one hundred feet plotted. When they finally reached the picnic table, group 2 was full of hungry, grumpy people who just wanted to go home.

Group 3 got to the picnic site in record time. It was a difficult journey, at times – the group had to veer off the original course many time, in order to avoid some previously unknown obstacles. In the end, the Pathfinder did a great job of keeping everyone focused on the goal – the picnic table and food. With the ability to see all of the obstacles in the surrounding area, and the ability for the group to make decisions that would get them around obstacles while still making progress toward the picnic table, the group was successful in getting to the picnic table before lunchtime. Everyone on the group loved the trip and appreciated the ability have input in how they got to the picnic table. As long as the direction that they headed for the next one hundred feet did not cause a serious delay in reaching the picnic table, or was justifiable by avoid an obstacle, all input was considered before setting the new direction. Several of the people in group 3 decided that the would take a few more hours and head off into the next set of hiking trails, trying to reach another picnic table before dinner time. Other decided to bring their family out to the trail the next day, and re-walk the well defined path (noted by the ropes tied to the starting and ending points of each leg of the journey). Overall, everyone in group 3 enjoyed the experience.

The Real World

Now imagine that the Pathfinder is represented by some aspect of your organization. It may be the company or project leadership; it may be the customer; it may be an individual person or group of people within a project team. Your Pathfinder may not be a person or other sentient being, though. Perhaps its the Methodology (capital M, as defined in Peopleware) or political environment in your company.

Which Pathfinder(s) do you have in your company? Which Pathfinder would you rather work with? More importantly – if you are not working for / with the Pathfinder that you want, what steps are you taking to correct that? Be a catalyst for change – appropriately and professionally.

Continuously improve – always within the context of the goal.



_________________________________
Cross Posted From LostTechies.com
Monday, January 12, 2009 3:41:35 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Community | Lean Systems | Management | Philosophy of Software

 Friday, December 19, 2008

My coworkers really do love me. This was their Christmas present for me, complete with shiny bow.

I was told to use it only for good, not for evil.

Dericks Soapbox Soap box closeup

And yes, that is me preaching from my soap box.



_________________________________
Cross Posted From LostTechies.com
Friday, December 19, 2008 12:23:08 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Community | Management

Let's assume that we are doing the appropriate amount of testing during our development process. If we include TDD, test automation, test engineers and customer acceptance testing, we should find the majority of the bugs in our system before they are released. However, not every bug will be found. There will be some situation that no one thought about before. There will be some special circumstance on someone's computer that hasn't been accounted for. There will be some client data that does fit the expected variance, despite the data being valid. The point is, there will be something that breaks after we deliver the software. Worse yet - it doesn't even take delivery to find bugs. What happens when the software gets to customer acceptance and the customer says that something is wrong, broken or whatever? We simply must account for the inevitable bug fixes and emergency patches in our system.

Our current kanban board, with all it's pipelines and queues, hasn't addressed the need to address problems. But before we get into any changes to the board, we have to define and create the culture of quality that we need in our team.

A Culture Of Quality

There are many different aspects of quality and many different ways to view and interpret quality. The individual specifics, as always, come down to your team, the project and the needs of both. Even with these variances, though, there are a few key concepts that should be found in any culture of quality, including Whole Team / Collective Ownership and Zero Defects.

Collective Ownership

I've talked about this concept before (see above link) and would recommend reading those prior posts. One thing I would like to add, though is that collective ownership can only success when the team takes their individual egos out of the equation. We must be able to accept criticism as a way to improve ourselves and our team. When we let go of our ego, we can be honest with ourselves and others, enabling everyone to own every part of the system.

Zero Defects

This is a subject that I have not talked about before, but is prevalent throughout the continuous improvement philosophies that I subscribe to. Wikipedia lists four principles of Zero Defect methodologies, all of which are paramount to our culture of quality.

  1. Quality is conformance to requirements
  2. Defect prevention is preferable to quality inspection and correction
  3. Zero Defects is the quality standard
  4. Quality is measured in monetary terms – the Price of Nonconformance

Don't be confused by "requirements" in item number one, though. In the world of software development, the word "requirements" has many meanings - not simply the feature list or functional descriptions set forth by our customers. Our teams and processes have certain requirements that are imposed on top of, and into each of the business requirements for the software. These often include the use of source control systems, test driven development, principles like S.O.L.I.D., etc.

Quality Checks in Kanban

Collective ownership and zero defects are only the tip of the iceberg. There is so much more to a culture of quality and so many different aspects of quality to account for. However we define quality, though, our ability to create a culture of quality is necessary for our kanban system to work. Without it, we lose the continuous improvement and elimination of waste that defines Lean. With it, though, we can introduce some specific tools to our process and improve our kanban system by having it handle the errors that are found in our systems.

Andon

From Wikipedia:

"a system to notify management, maintenance, and other workers of a quality or process problem"

When an issue is found in our system, we need to notify the team immediately so that the problem can be taken care of. The idea in a manufacturing line is to allow a worker to stop the line when a problem is found. In our grocery store example, andon could be invoked by a shelf stocker noticing a loose imagenut or bolt on the shelf and then notifying a maintenance person. In software development, andon can take many different forms. We report our issues list during our daily standup. We create issue tickets in our issue management system. If we're lucky and work in a company that supports the idea of a team room, we may just need to look up or turn around and let the team know that we have problems. We could even place an actual red flag on the desk of our developers, testers, customer representatives, etc., and have them raise that flag when they see a problem. Any of these ideas, plus many many more, can all be our andon system.

Andon itself is not intended to be an all encompassing electronic system with metrics and reports and yadda yadda yadda. It needs to be simple. It needs to be easily employed by anyone on the team. And it needs to mean something to the team. If a team member throws their andon card out on the table, the culture of that team needs to be ingrained with the knowledge that work may stop until the problem is addressed.

There's so little to andon, yet so much more than what I've described. However andon is enabled, it is critical to our zero defect policy in software development.

Jidoka

AKA "Autonomation", AKA "Automation with a human touch", AKA "intelligent automation", AKA ...

From Wikepedia:

"Autonomation prevents the production of defective products, eliminates overproduction and focuses attention on understanding the problem and ensuring that it never recurs."

I've talked about Jidoka in previous posts and would recommend reading them, at this point.

I don't have much else to add, other than to say that Jidoka and Andon go hand in hand. Automated build servers (such as CCNet, TeamCity and many others) can often combine Andon and Jidoka for us by giving us instant visual feedback when something is broken. I've also recently set up BigVisibleCruise in my team area, giving even the casual observer the knowledge of whether our builds are broken or not.

Applying Andon and Jidoka to Our Kanban Board

Once we have the concepts of Andon and Jidoka in our team and culture, we can use these tools to generate issue cards and then look at a few possible changes to our kanban board to account for them. The three basic methods that I have seen used include:

  1. Creating an Emergency Fixes pipeline
  2. Tacking a smaller bug notice onto an existing card
  3. Putting a Bug card in the backlog

I'm sure there are other alternatives, too. In my current team, we use the first and third method and are considering the second one as well. 

Options two and three essentially require no change to our kanban board. Implementing option two is a distinctive way of visually attaching a bug notice to one of the cards in our system. This could be done with little bug stickers, little red cards, or any other visual indicator that the team agrees on. Option three also needs something distinctive. Since we are creating an entire card for the bug, though, the entire card should be distinctive. I would recommend using a card that is colored red to signify issues. I would also recommend prioritizing the bug to the top of the backlog queue, when using option three. This will ensure that the bug gets worked as quickly as possible.

Option number one can also make use of number two and/or three. When we move a card into the Emergency Fixes pipeline, we may want it to be distinguishable as an issue by tacking on our bug symbol or by using a colored card.

Emergency Fixes Pipeline

Depending on the complexity or severity of the bug, we may want to include Analysis and Customer Acceptance in our Emergency Fixes. With andon and jidoka in mind, we will want to ensure that we fix any emergency issue immediately. This is not always possible, however. The customer may decide to delay the fixing of an issue for whatever reason. This leads us to only needing a single pipeline for Emergency Fixes, letting us set our limit to one.

We can easily add an Emergency Fixes pipeline to our kanban system, placing it directly underneath our existing WIP pipeline. This special pipeline can be designated with a name, color code, or other marks as needed.

image

If you are supporting production releases, you may also need to include a Delivery queue specifically for emergency fixes. This would allow multiple fixes to be compiled into a single patch release. There are other configurations to this, of course. As always, you will need to find what your specific team needs and create your process to suit.

Where Do We Go From Here?

With an Emergency Fixes pipeline in place, our kanban system is now set up to handle just about every situation that we will encounter. However, this does not mean that our system is perfect or truly complete. No process, no matter how well defined it is, is worth anything if the people running the process do not believe in it. I've said it before and I'll continue to say it - never stop improving your process. Always be mindful of waste, friction, smells, problems or whatever you want to call it. Inspect, adapt and continuously improve your process. Perfection is a journey, not an end-goal.

Stay tuned to my Adventures in Lean series, as I continue to explore the various aspects of lean software development in my own team and company culture.



_________________________________
Cross Posted From LostTechies.com
Friday, December 19, 2008 10:46:35 AM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: Analysis and Design | Community | Continuous Integration | Kanban | Lean Systems | Management | Philosophy of Software | Principles and Patterns

 Monday, December 15, 2008

In part 2 of my Kanban in Software Development series, I talked about completing a kanban board with queues, order points and limits. We saw how to take a complete development pipeline and work with a team, its processes and its bottlenecks. In the end, we had a kanban board that could easily represent the processes of the fictional team that we outlined.

One of the questions that I've often asked about a kanban board is how anyone would know when work in one column is done and ready to be pulled into the next column. For example - if a kanban card is sitting in the Analysis column, how does a developer know when that card is done so that they can pull it into Development and start coding it? I found the answer to this question when I was at the Kaizen Conference in October. Jef Newsom did a workshop on kanban and we ended up with this same question, and a solution.

A Pipeline for Analysis - WIP and Done

To facilitate the visualization of the difference between work in progress and work that is ready to be pulled to the next column, we can use the concept of a pipeline and split our existing queues into a WIP and Done step. For example, we want developers to pull work from the Analysis queue into the Development pipeline. We can show which cards are ready to move by splitting Analysis into sub-columns of WIP and Done.

image

When an Analyst is ready for work, they would pull from the Backlog into the Analysis / WIP column. When the analysis work is done and the card is ready to go into development, the card would be moved into the Analysis / Done column. Since we are wanting to maintain the concept of a queue for the overall Analysis column, we have create the WIP and Done subdivisions as a pipeline (noted by the dashed line). This allows us to keep our order point (3) and limit (5) in place for Analysis, and know what work is ready to be pulled into Development.

Applying Pipeline per Queue Across The Board

Not every queue needs to be a pipeline.

Consider the Backlog - the customer is placing the prioritized list of features in this column. The cards in this column exist so that the analysts will know what work needs to be done - not because any work needs to be done in this column, explicitly.

The Delivery column may not need a pipeline, either. If the delivery process is composed of sending an installer package to the customer, then there is no real work to be done in this column aside from sending that package. However, if there is some specific integration work (say, changing a web.config file) that needs to be done, we could include a WIP and Done pipeline for delivery. For this simple example, we'll say that there is no configuration change needed. Let's assume that the installation package changes all the needed configuration files based on user input.

With all of this in mind, we can apply our WIP and Done pipeline to the Analysis and Customer Acceptance columns.

image

Alternative Visualizations

There are other ways of visualizing WIP vs Done cards for a given column, of course. For example, you could forgo the pipeline idea and simply add a queue between Analysis and Development. This may require you to adjust your order points and limits between analysis and development - at least, where those order points and limits apply (Analysis vs. the queue between Analysis and Development). You could also split the column horizontally instead of vertically, creating either the top or bottom half as the WIP with the other being Done. Or you could just note the status on the kanban card itself. I'm sure there are a number of other ways to show this information, as well. The point is that the pipeline visualization that I'm showing here is not the only way. Find what works for you.

Where Do We Go From Here?

We have another tool in our belt, now. If need be, we can visualize the WIP vs work Done for a given queue, allowing us to see when we can pull work forward. But, like all tools in our belt, it is not *the* answer and this additional visualization may not be necessary for your team.

If your team is small or has great communication, you may not need any special distinctions to show work in progress vs work ready to be pulled. You could rely on the daily standup for people to report when they are done, or do it ad-hoc - when someone finished a card, they announce it to the team immediately. In a larger team, though, it may become necessary to have some visual distinction between work in progress and work completed for a given column.

Small teams might get away without it; larger teams might need it; its up to your team to decide. The key is not to apply these ideas as blanket rules that must be followed, but to allow the individual project and team to decide what is right for them. And as always, allow the process to change when it needs to. Always inspect, adapt and continuously improve.



_________________________________
Cross Posted From LostTechies.com
Monday, December 15, 2008 2:07:38 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Analysis and Design | Kanban | Lean Systems | Management

 Monday, December 08, 2008

In Part 1 of Kanban in Software Development, I introduced the concepts of kanban boards and pipelines. I also showed a very simple example of creating a pipeline for our development process. However, there were some obvious limitations in what I showed. The reality of software development is much more complicated than three simple steps (Analysis, Development and Testing). A software development team or company is going to have more to do than just these things, and there is usually a need for some team members to be cross-functional. Some team members will have to do development and testing, or analysis and development, or documentation and delivery, or any other combination of steps involved in creating software. In this post, I'll address these issues, creating a more complete pipeline and finishing our kanban board.

Working In A More Complete Pipeline

To create a more complete kanban board, we need more than just a three step pipeline. We need to allow for a fully functional team - developers, analysts, testers, technical writers, and others. We also need to allow the different team members to work on different parts of the system, as work is needed. The end goal is to enable the system to flow through the process and to ensure the work is "done done" before it goes to the customers.

For a more complete software development pipeline, let's use the following columns: Backlog, Analysis, Development, Documentation, Testing, Customer Acceptance, and Delivery. We can put together a pipeline diagram that follows these steps.

image

Now, let's assume that we have the following team (ignoring project managers, customer representatives, etc, for now): 6 developers, 2 business analysts, 3 test automation engineers, and 3 technical writers. Given this team, we would not be able to make a feature flow through this pipeline. We would have developers sitting around, waiting for work from the analysts. And, our documentation writers and test lab people would probably be pulling his hair out from boredom then pulling their hair out from too much work, in an unbreakable cycle.

Fortunately, we can account for the team makeup and the potential bottlenecks by introducing the concept of order points and limits that we saw in the grocery store, and by creating queues and multiple pipelines to be worked.

The Real World - Multiple Pipelines and Limits

In most software development efforts, it's unreasonable to expect an entire team to work on only one feature at a time. Most development managers want to maximize the throughput of development by working on tasks in parallel. Given this desire, we'll divide up our developers into three teams of two developers each. This development team division should allow three features to be developed at the same time. Since we want to work on three features at a time, we will need three pipelines for work.

image

These three pipelines constitute our first limit - we can have a maximum of three features in development at any given time. This limit is noted by putting a "3" in the upper right hand corner of the development column header, as shown above.

Having three development pipelines puts us in a tricky situation, though. We have very few business analysts compared to developers - even with our developer teams, we have less than one analyst per developer team. Fortunately, development work often takes longer than analysis. We can use this knowledge to our advantage and let the analysts work slightly ahead of the developers, creating a queue of work to be done.

Handling Bottlenecks - Queues, Limits and Order Points

If all three development teams happen to finish at the same time and need more work, we would need a minimum of three features that are ready to be worked. However, since we know that requirements change regularly, we don't want to get too far ahead of the developers. With this in mind, we can introduce an Analysis order point of three (the number of development teams) and limit of five. This gives the analysts the ability to work ahead of the developers and also makes them responsible for keeping work available for developers.

For an order point we'll introduce the number into the upper left hand corner of a column header, and we'll continue using the upper right hand corner to specify our limits.

image

Since we are now dealing with potentially more work in analysis than development, it seems we would have to increase our pipelines to five. This is not desirable, though, since we only have three development teams. What we will do, instead, is restructure the pipeline and turn the analysis column into a queue.

image

Since Analysis is now a queue, there does not seems to be a need for Backlog to be a step in a pipeline, either. The backlog is simply the list of features that the customer is expecting to be done next. Therefore, we will also turn the backlog into a queue - this time, with a priority (top of the board is highest priority) allowing the customer to tell us which specific feature should be worked on next. We will also want to keep the backlog column limited, to prevent the team from having too much information to think about. Since we only have two analysts on our team, it seems appropriate to keep at least two features in the backlog column at all times. With this in mind, we can safely set a backlog order point of two and limit of five (enough to keep the analysis column full).

image

The changing of Backlog into a queue has no made our Development column the first step in our actual pipeline.

Completing The Pipeline - Aggregate Limits and Work Cells

The next few column - Documentation and Testing - both have an easy amount of team members to deal with. There are three technical writers on our team, and three testing personnel. This distribution lets us keep the pipeline in tact between Development, Documentation and Testing, allowing us to set the same limit as Development (three).

image

With all three of these columns having the same limits, and with each column being properly staffed so that three pipelines could run at the same time, it makes sense to combine the team members from these three columns into a single workcell. If we consider all four team members (2 developers, 1 tech writer, 1 tester) as a team and allow them to work together as a team, we can aggregate the limits of the columns in the pipeline. We can also create a consolidated name for this pipeline - work in progress.

This consolidation can be shown by creating a parent / child header with the limit shown in the parent. We will also use a dashed lines between the columns of the pipelines. The combination of these two details will show us that we are dealing with a pipeline, and how many pipelines are allowed to flow, simultaneously.

image

By aggregating the pipeline limits, we allow the workcell for a given feature to focus exclusively on that feature. The development staff, technical writers, and test lab personnel will all be working on the same feature, allowing them to more easily share information between themselves. This will prevent the team members from having to switch back and forth between subjects, reducing cognitive load and allowing for greater quality to be attained in the individual feature.

Completing The Kanban Board - Customer Acceptance and Delivery

If the customer is on-site (co-located with the team or close enough to meet every day), then it may be possible to aggregate the Customer Acceptance process into the Work In Progress pipeline. If you can do this, you should. Getting immediate feedback from the customer, while work is still fresh in you mind, is critical to the quality and success of that work. What's more - you may not need this explicit column if you have the customer working with you every day.

Unfortunately, we don't always have the luxury of on-site customers. We may only have the customer around at specific timer intervals or only on request. In either of these cases, we have to account for the bottleneck of Customer Acceptance.  Additionally, the customer may not want to get delivery of individual features. They may want to wait for a quarterly release, or some other regularly scheduled release. Once again, we have to account for this bottleneck. We can apply the same principles that we used for Backlog and Analysis here, and create some appropriate order points limits.

Let's say that our customer wants to do Customer Acceptance testing once a week and wants a Delivery once every calendar quarter. To accommodate this, we can set the Customer Acceptance column as a queue with a 1 week limit. We can also set the Delivery column as a queue with a 1 quarter limit. Setting these limits puts a direct responsibility on the customer. If they cannot pull the features through these columns on or before the specified limits, then the entire system could grind to a halt. It's important to educate the customer in what they are committing to, and ensure that they can fulfill their obligations. This fulfillment may mean that they assign more than one person or group of people to the task of Customer Acceptance and accepting Delivery. Whatever the solution is, the customer has responsibilities to meet.

With Customer Acceptance and Delivery specified, our completed kanban board would look like this:

image

Put It In Action - A Kanban Process Is Never Truly "Complete"

Now that we have clearly defined our Kanban process and visualized it through our Kanban board, the next steps is to start using it! Start working through this process, pull value from the end of the process and allow work to flow through the pipeline. Respect the order points and limits, and above all, look for problems in the process and fix the process when you need to.

Perhaps you have too few or too many items in one of your queues - adjust the limits and order points. Perhaps the test lab is now a bottleneck - take them out of the pipeline and change them to a queue. There are many possible problems and many possible solutions. The key is to be aware - inspect and adapt and hold regular retrospectives - kaizen your process and continuously improve.

Where Do We Go From Here?

No process is perfect. Anyone that tells you otherwise is selling something. A customer may find a bug during Customer Acceptance; an issue makes it past all of our QA processes and is found out in production; or there's a feature that has a sudden priority over any other feature currently being worked. But our current kanban process doesn't address the natural problems that occur during a software package's lifetime. To address this properly, we'll need to employ the lean tools of Andon and Jidoka, and we'll also need to decide how to visualize this on our kanban board. These issues, and possibly more, will be addressed in another installment of Kanban in Software Development.



_________________________________
Cross Posted From LostTechies.com
Monday, December 08, 2008 4:06:45 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Kanban | Lean Systems | Management | Philosophy of Software | Retrospectives

In the world of Scrum, XP and other forms of Agile software development, many teams use visual control systems to outline the various steps that software goes through during development. These boards are known by various names -  Scrum boards, card-boards, task-boards, swim lanes, and probably a few other names that I'm not aware of at the moment. Whatever you call it and whatever agile creed you live by, the primary use of these boards is the same all around - information radiation. Anyone can look at the board at any given moment in time, and know where in the development process a given card is. If you're doing iterations or sprints, the board also tells you where you are in that time box - if you're ahead, behind, or on time. The far left column - the iteration backlog - will be filled with cards at the beginning of the iteration. Over the coarse of the iteration, cards will be pushed through each of the columns until they are in the done column. The goal is for every card to be "done done" by the end of the iteration, with a set of features that is now deliverable to the customer.

Kanban Boards

Visual management tools are very common in agile shops, and for good reason - they work very well. It should come as no surprise, then, that kanban software development also employs various visual management tools, including a kanban board.

On the surface, there isn't much difference between an average task board and a kanban board. Each of these boards has various columns that represent the stages that a card needs to go through before it is considered done. The real difference in a kanban board, is not the board itself. The board is just a visual indicator, the same as any task board, and the intention is still to get the cards to the "done done" state - that is, delivered to the customer so that they can use the features from that card. The real difference is how the process is approached - by pulling value through the system.

Kanban Pipelines

When dealing with a kanban process and visualizing it into a kanban board, the various steps that a card goes through is often called a pipeline. A single card starts at one end of the pipe and flows through to the other end. This flow is enabled via the pull system that happens at the end of the pipe.

In the grocery store example from my previous post on pulling value, the pipeline would would likely include the store shelf, the store back room, the warehouse, the supplier and the product creator.

image

A Simple Software Development Pipeline

A software development pipeline works the same way as the grocery store pipeline. In this case, though, the product flowing through the pipe is likely to be a feature of the software package.

Consider the following three columns in a simple pipeline for software development: Analysis, Development and Testing. When a customer requests a given feature for a software product, they want to pull that feature out of testing so that they can start using it.

Customers Pull From Testing To Use A Feature

Once that feature has been moved out of Testing and the customer is ready to pull the next feature out, there isn't anything to pull. At this point, the Testing people would then try to pull the next feature out of Development.

Testers Pull From Development To Test A Feature

And the same pull happens from Analysis to Development.

In the end, we have created a pipeline for how our development process works. The work that is done flows through that pipeline based on how often the customer wants to pull features out. As one feature exits the pipeline, another feature can be added into the pipeline.

Kanban Pipeline - Features Flow Through

The key to all of this is, again, pulling the features through the system.

Where Do We Go From Here?

I've briefly shown how we can take three steps and produce a simple pipeline for work to flow through. There is more to software development than just Analysis, Development and Testing, though. We also have to consider team size and makeup, parallel work, and other constraints. In the next entry of Kanban in Software Development, we'll flesh out a more complete pipeline and take the next steps to show how to complete our Kanban board, enabling our customers to pull features out of our development process.



_________________________________
Cross Posted From LostTechies.com
Monday, December 08, 2008 12:45:24 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Kanban | Lean Systems | Management | Philosophy of Software

 Thursday, December 04, 2008

For the last month or so, I've been having a serious problem with the apparent lack of professionalism in the software development industry as a whole. There are many factors contributing to this and many different aspects of the problem. I'm not going to go into any detail on the issues I'm seeing, at this point, though. It will be sufficient, for the moment, to simply state that there is a serious lack of professionalism in our industry.

I've been discussing this issue with my dad, recently, and this morning he sent me an email that I thought was worth sharing with the world.

Today’s thought is to remind the team that life in general is determined by the 2nd Law of Thermal Dynamics. All matter (systems) go from a state of order to disorder with out any outside input.

[From Wikipedia]:

"The second law of thermodynamics is an expression of the universal law of increasing entropy, stating that the entropy of an isolated system which is not in equilibrium will tend to increase over time, approaching a maximum value at equilibrium.

The second law traces its origin to French physicist Sadi Carnot's 1824 paper Reflections on the Motive Power of Fire, which presented the view that motive power (work) is due to the fall of caloric (heat) from a hot to cold body (working substance). In simple terms, the second law is an expression of the fact that over time, ignoring the effects of self-gravity, differences in temperature, pressure, and density tend to even out in a physical system that is isolated from the outside world. Entropy is a measure of how far along this evening-out process has progressed.

There are many versions of the second law, but they all have the same effect, which is to explain the phenomenon of irreversibility in nature."

 

Bottom line is that the point of natural human equilibrium is far below the level of professionalism demanded by our responsibilities to work, self, family and others.

The Point … doing what’s natural or going with the flow points life in the downward direction every time.  Let’s tweak the line upward… put some thought and energy into it.

Robert D. Bailey   12-04-2008  



_________________________________
Cross Posted From LostTechies.com
Thursday, December 04, 2008 10:53:57 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Community | Management | Philosophy of Software

 Thursday, November 20, 2008

Before I start talking about how our team is going about our implementations of Lean and Kanban, I wanted to start by outlining my current understanding of what kanban is. I'm hoping that this will set the ground work for the rest of my Adventures in Lean series, and implementing Kanban in a Scrum shop.

Groceries, On And Off The Shelf

The next time you're in a grocery store looking at a shelf stocked full of products, take note of the little stickers that adorn the shelf just below where the product is placed. This sticker is usually crammed full of information - some of it useful to you, the consumer, and some of it not useful to you. So why is all of that information there? Who is getting any value out of that information? The answer is surprisingly simple - the people that stock the shelves. When the supply of good on the shelf is running low or is empty the information on those stickers tells the stock-persons what to put back on that shelf. This person is then able to create a pick-list of goods to retrieve from the back of the store so that they can restock the shelves.

Now consider an extended example of more than just the grocery store. When you, the consumer, take an item off the shelf, you have created room for one more item to be placed on the shelf. The stock-person sees the sticker in that space, goes to the back of the store to retrieve the item and places it on the shelf where the space is. At this point, there is another person paying attention to how much is actually in storage in the back of the store. When the stock-person grabs an item from the back of the store, the back-room person sees that space and determines whether or not they need to order more of those items from the warehouse. When the back-room person orders items from the warehouse, the warehouse workers check to see if they need order more of those items from the supplier. When the warehouse orders those items from the supplier, the supplier checks to see if ... and on and on until we finally get to the point where the products are being made - the manufacturer or farm or whatever the ultimate source of supply actually is.

What Is Kanban?

This simple act of seeing that a space on a shelf needs to be filled, and filling it, is the core of what kanban is. Quite literally, a kanban is a sign or signal. In more conventional terms, though, it is a sign for action that must be taken to replenish the empty slots on the shelf of the grocery store, the back room, the warehouse, etc.

From Wikipedia:

"The Japanese word kanban (pronounced [kambaɴ]) is a common everyday term meaning "signboard" or "billboard" and utterly lacks the specialized meaning that this loanword has acquired in English. According to Taiichi Ohno, the man credited with developing JIT, kanban is a means through which JIT is achieved."

When a consumer takes an item off the shelf, the process of pulling products - pulling value, really - from the upstream suppliers begins. It's the pull of kanban that makes it such a powerful system. We let the customer pull the items they want which drives the rest of the pull system. If no one takes the item off the shelf, there is no need for the stock-person to put another item on the shelf, and no need for the store to order more from the warehouse, etc. Think of it as a form of Demand-And-Supply instead of Supply-And-Demand. The customer demands a product, the grocery store supplies it. The store demands the product, the warehouse supplies it, and on and on up the stream.

What Is An Order Point?

When a space is empty on a shelf, a stock-person may not immediately fill it. In fact, the stock person may wait until there are several spaces on that part of the shelf before filling them. On this shelf, the maximum number of empty spaces allowed is the order point. For example, if the shelf has three empty spaces and the order point is set at three, the stock-person knows that they need to replace the items on the shelf soon. If the number of empty spaces goes up to four, the stock-person knows that they need to replace the items on the shelf now.

Order points can be specified in a few basic ways:

  • Maximum number of empty spaces needing to be filled
  • or Minimum number of products on the shelf

I'm sure there are other ways, as well. These are the two that I've seen the most often, though.

Each area of the grocery store is going to have it's own set of order points. The shelves that consumers pull from will probably have a very low order point - may two or three items missing. The storage area of the store will probably have a larger order point - two or three cases missing. On up the supply stream, the warehouse may have a larger order point of two or three pallets, and on and up the stream the order point may grow larger.

In the grocery store, the kanbans that adorn the shelves often have the order point printed directly on them. This gives a stock-person the knowledge they need, when they need it, and prevents them from having to remember the order points for all the products in the store.

What Is A Stock Limit?

When a shelf at the grocery store is full of products - there is no space left to put anything else - that shelf is full. However, the individual products on that shelf may not be at their stock limit. A stock limit is the maximum number of a given item that can be stocked at a given time - wether that stock is on the shelf or is in the storage area of the store, or wherever it is. If a shelf has a stock limit of five, for a given product, then there should be no more than five of that product on the shelf. Both the shelf and storage area have their own stock limits. It's these stock limits that prevent the store from being overrun with too many of one product, and not enough of another product. 

Like order points, the kanbans that adorn grocery store shelves often have the stock limit printed directly on them. This tells the stock-person when to stop putting items on the shelf without them having to remember the limits for all the products in the store.

How Does This Apply To Software?

I'm not going to give away the farm just yet. Moving forward, though, I will be using the terms Kanban, Order Point, and Stock Limit (or just Limit). I wanted to get these core terms defined up front, so that they will make sense in the context of what is still to come.

Stay tuned for the next entry in my Adventures In Lean!



_________________________________
Cross Posted From LostTechies.com
Thursday, November 20, 2008 6:03:08 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Kanban | Lean Systems | Management

 Wednesday, November 19, 2008

In the last six months, my team has undergone some very radical changes and has turned into a full blown Agile team. I'm very happy with our success and I consider this team to be the shining example in our company, at the moment.

Now, in keeping with the tradition of this team in changing at least one thing every few weeks, we are about to embark on a new journey in our project management processes: Lean Software Development.

Starting at 1pm, Central Time, today, my team will be kicking off the following processes:

I am going to be posting a series of entries on each of these specific items over the next few weeks, and will most likely keep this post updated as the index of entries for a while. So stay tuned for a whirlwind of opinionated posts on our next great experiment!

Table Of Contents For Adventures In Lean

Here are the articles that I have written or am writing for my Adventures In Lean series:

Kanban

  1. Kanban - Pulling Value From The Supplier - In this post, I am laying the foundation of what Kanban is along with a couple of other important terms that I will be using throughout the series. Kanban is only one of many tools, techniques and philosophies found in lean, though. Trying to sell kanban as lean would be like selling a steering wheel as an entire car - you're only getting part of what you really need.
  2. Kanban in Software Development
    1. Part 1: Introducing Kanban Boards and Pipelines
    2. Part 2: Completing the Kanban Board with Queues, Order Points and Limits
    3. Part 2.5: A Variation on Queues - Pipelines for WIP and Done
    4. Part 3: Andon and Jidoka - Handling Bugs and Emergency Fixes in Kanban
  3. Our Kanban Board and Process 
  4. Release Per Feature - Delivering Value As Soon As Possible
  5. Just In Time Retrospectives - Fixing Problems As Problems Occur

There are likely to be other articles added to this list as well. Please check back now and then to see what has been added!



_________________________________
Cross Posted From LostTechies.com
Wednesday, November 19, 2008 1:30:07 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Lean Systems | Management | Retrospectives | Standardized Work

 Wednesday, September 10, 2008

After some additional Twitter discussion with Jimmy last night, I realized that my previous response had neglected to distinguish between two very important contexts - new code and legacy code.

Considering a legacy system (as defined by Michael Feathers), I'm 100% on board with everything Jimmy is talking about and all of the techniques, troubles, and diminishing returns that he identifies.

I still maintain that 100% coverage should be the default result of true TDD when writing new code - and I apply this philosophy when writing new code inside of a legacy system. Write a test to prove you need the new code that you are writing... unfortunately, the distinction between new and legacy code does get blurry and can be difficult to navigate when working in a legacy system.

For more info on legacy code, in this context, and how to deal with it:

Wednesday, September 10, 2008 7:25:17 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Code Coverage | General | Management | Philosophy of Software | Principles and Patterns | Refactoring | Test Driven Development | Unit Testing

 Tuesday, September 09, 2008

I've talked about code coverage and software quality with a number of people on Twitter in the last month or so, including Jimmy Bogard, who has a nicely written post about Quality and code coverage.

It's no secret that I have some fairly radical opinions on code coverage and that I don't agree with Jimmy in these regards. I firmly believe that 100% code coverage, in whatever form we can get, is a reasonable goal and not past the point of diminishing returns. As such, I'd like to respond to some of what Jimmy is saying and expand on it with my own thoughts.

But first - I don't like to draw hard lines between "Unit" tests and "Integration" tests - that just blurs the problem even more because we can argue that you are covering code or not, in "unit" tests all day long, based on this blurry line. This is not the discussion I want to have, so I am lumping "Unit" and "Integration" tests into "Unit" tests as a whole.

Secondly, I'd like to say that code coverage is not always an indication of quality - in poorly written systems, it's merely a measure of code coverage. However, quality code is another subject of much debate.

On to the response!

.............................................

"The idea is that the team, all practicing TDD, should dutifully measure and add unit tests until they reach the assumed pinnacle of unit testing: 100% coverage."

There are several assumptions and statements in this that I don't believe are true.

For one, TDD and Unit Testing are not the same - no where near the same. Unit Testing lets you add tests as you see fit - after you write the code, while you write the code, whenever you want. You can even do test-first unit testing. True TDD, however, is a pure pragmatic approach to software development in that you never write code that does not have proof of need to exist - a test that says it needs to be there. 

The "pinnacle" of TDD and Unit Testing are not the same thing. Unit Testing - the act of adding unit tests when you see the need - may have a goal of 100% coverage. TDD, on the other hand, has a goal of only implementing the code that has been specified as needed. 100% coverage is the default in TDD because you never write code you don't need.

If you are going through the "measure and add unit tests" process, I would put money down to say that you are doing Unit Testing and very little TDD. The process should be something more like "measure to make sure we haven't added anything we don't need yet". 100% coverage is a side effect of TDD.

"The general motivation behind 100% coverage is that 100% coverage equals zero bugs."

Unfortunately, this is the motivation for many people who write unit tests - but it's the wrong motivation. You will never be 100% bug free just because you have 100% code coverage. There will always be some business case or external system factors that cause a bug now and then. That doesn't mean we should be ok with letting bugs into our system. On the contrary, one of our motivations (not the only one) should be to prevent as many bugs as possible from getting into the system.

"NCover is a powerful tool, but it still doesn't support all types of coverage.  Attaining 100% coverage in NCover still means there are paths that we haven't tested yet, which means there are still potential bugs in our code. "

I think the logical conclusion of this argument is that if we don't have a tool that supports true 100% coverage, then we shouldn't use that tool at all. I know I'm inserting my own conclusions into Jimmy's words - that's simply the conclusion that I came to from these statements. And this is a very bad conclusion. Do you walk around naked simply because wearing clothes would get them dirty and you'd have to wash them? Both of these are akin to the broken window syndrome. Use the tools that are available to the extent that they can operate, and find better tools when you can.

"If 100% coverage is a goal,"

100% coverage should NEVER be a goal - it's merely an indication that you are on the right path and working pragmatically.

"In recent projects where we measured coverage several months in to the project, we saw regular numbers of 90% coverage.  This was on a team doing 100% TDD." ... "So are we doing TDD wrong?"

So, are you doing TDD wrong? Yes. You are unit testing in the guise of Test-First-Development and not adhering to the spirit or pragmatism that TDD wants.

"Every test introduced covered behavior we considered interesting.  If behavior isn't interesting, we don't care about it. "

If you have code that is not interesting and you don't care about it - why is it in the system? If you don't care about the code, then it makes no difference whether or not that code works correctly. I would be appalled to hear that this is true. If it is true, then that code should not be in the system to begin with.

"If tests are a description of the behavior of the system, why fill it with all the boring, trivial parts?  The effort required to cover triviality is just too high compared to other ways we can increase value."

I think your definition of "behavior" is wrong. From wordnet.princeton.edu/perl/webwn:

Behavior: "the action or reaction of something (as a machine or substance) under specified circumstances;"

So, how is throwing an exception when a parameter is null, not behavior? If you are doing defensive programming to make sure you have all the data you need, then you are creating behavior - system behavior, not business process behavior. Behavior is still behavior, though. The only possibility of code not being behavior is a simple data point. If you have a data point in your code that is not covered by a unit test of behavior, then you don't need that data point. Yes, yes, I know - "integration", "nhibernate", "not my data source", "it has to be there for ...". If you argue that you need a property for some external portion of the system to operate correctly, then you should be proving that you need the property by covering it with a unit test that specifically says what it is for and shows how it is used. If you don't, then there's no way of knowing why the property exists and it may be deleted because it looks like nothing in the system uses it. Or, possibly worse, you end up with a lot of dead code in your system because you are afraid of deleting anything.

"Missing in the 100% coverage conversation is the effort required to get to 100%.  Attempting to get another 5% takes equal effort of the previous 10%.  The next 2% takes equal effort of the previous 15%, and so on."

I'd like to know where you got the math. If you are talking about unit testing - even test-first unit testing - i can understand the pain you're talking about, here. Why should I bother setting up another test fixture and getting all the state of my objects in place for a simple null reference check? blech - that totally sucks, is boring, is tedious, etc.

However, my typical process of achieving 100% is to only write code that is needed for the system to work, by specifying how the system will work through tests and then coding it. If I have a null reference check somewhere in my code it should be because I already have a test that specifies why it's needed.

"This is called the law of diminishing returns.  As we get closer and closer to 100%, it takes vastly more effort to get there.  At some point, you have to ask yourselves, is there value in this effort? "

Here's the real crux of the problem - you are assuming that you started with, or at some point has less than 100% coverage. It takes zero additional effort to stay at 100% coverage if you start at 100% coverage and maintain it through pragmatic TDD.

"Often, bending code to get 100% can decrease design quality, as you're now twisting the original intent solely for coverage concerns, not usability, readability or other concerns."

If you find yourself bending code to get 100% coverage, you have one of two situations (if not both): 1) poor design in your code, 2) poorly written tests. I would bet that you have both because they are a vicious circle.

"Measuring coverage is an interesting data point, as are other measures such as static analysis.  But in the end, it's only a measure, an indication. "

100% agreed!

"It's still up to the team to decide on the value of addressing missing areas,"

This implies that you don't have 100% coverage, already. In this situation, 100% agreed. I'm in this situation right now - it's hard to know what tests create the most value, at this point. However, any new code - even code changes to existing code - are done TDD style. So, while we don't yet have 100% coverage, we are increasing coverage all the time by never writing code without a test (that's part of the goal, anyway... no one is perfect, and it takes serious discipline to do this)

"with the full knowledge that they are still limited to what the tool measures."

Agreed, again. If you don't know the limitations of the tools you are using, you're in trouble.

.............................................

The boilerplate argument that I am making is that you should never write code that is not required by a customer / consumer. However, as I've Previously Talked About, there's a high likelihood that you have not identified all of your customers / consumers. Take NHibernate, for example. I have a project that needs about 30 different properties for a specific NHibernate query to be executed. The NHibernate query is the only place they are ever used - no code reads them, only a search screen writes to them, then the NHibernate query loads data from the table that they are mapped to. When I first wrote this code, my coverage was at around 30%. This situation is one of many that I've been in recently, that has lead me to believe that other code must be considered a customer / consumer of your code. If I deleted any of these properties, then the NHibernate query would fail. Therefore, the properties are valuable to NHiberate. Since these properties are valuable to at least one of the consumers of my code, I should prove that they need to exist by writing a test that proves they are needed and why.

Tuesday, September 09, 2008 12:39:11 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Code Coverage | General | Lean Systems | Management | Philosophy of Software | Principles and Patterns | Refactoring | Test Driven Development | Unit Testing

 Thursday, August 28, 2008

Earlier today, I had a conversation with a coworker concerning dependency container, dependency injection frameworks, and the root dependency inversion principle. My advice in the end, was to completely avoid the use of DI tools until the team as a whole understands the cost, benefits, and potential pains of manual dependency injection (pain being relative, and usually a sign of a learning opportunity). Part of the conversation also revolved around what constitutes the complete overuse and abuse of DI or IoC tool - which I can easily speak about due to extensive personal, self-inflicted, love-affair-of-IoC induced pain over the last year. However, the one thing I could not speak to was the correct use of a DI / IoC tool, because I believe that I have never used one correctly - or at least, my limited experience in using one correctly is so limited, I can't seem to separate it from the incorrect use.

I’ve heard other developers (Jeremy miller, jimmy bogard, and others) say that they want to see as little of a dependency container / injection tool in their code as possible. This gets to the heart of what I was trying to convey earlier, but I’ve never had a good understanding of where you would actually allow a dependency tool to be used under those guidelines.

On the way home from work tonight, I had (what I think is) a small epiphany around the idea that the dependency container should be limited to two key areas: the various implementation specifics (UI, database, etc) and the application layer. I think the use in the implementation specifics, for whatever use they're needed, is valid since these implementations are not unit tested to begin with. But I would highly recommend limiting the container’s use in these scenarios, for the same over used, abused reasons that I'm so intimate with already.

More appropriately, the application layer seems to be the appropriate location to resolve the dependencies by using the DI tool to instantiate the object that needs the dependencies, automatically resolving the dependencies for us – not requesting the dependency directly.

The best example I can think of, off-hand, is a workflow coordination service in the application layer. Let’s say your workflow moves from FormA to FormB in a windows app. The workflow class would use the DI tool to instantiate the ProcessAPresenter, which would resolve the registered IProcessAView as a constructor dependency. Then when this form is done, the workflow coordination class would use the DI tool again to instantiate the ProcessBPresenter and resolve the IProcessBView (and ISecurityService and whatever else) constructor dependencies.

The key here is that we are allowing the application layer to use the DI tool, and not the other way around – not letting the DI tool instantiate the application layer - and not using the tool as a simple IoC container to resolve dependencies internally from the object that needs the dependency.

These are primitive, unverified thoughts at this point, and need to be taken as such. I think this is a good start for a correct use of a DI tool, though. Additional implementation experience within this model would help to expose additional constraints and allowed uses, I would imagine.

How are you using your DI / IoC tools? What are your thoughts on the subject? Your pains, your joys, your sorrows? And from a purely selfish perspective - am I on the right track, here?

Thursday, August 28, 2008 7:54:38 PM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: Design Patterns | General | Management | Principles and Patterns

There's been a lot of recent talk about what is "done" in the Lean / Agile development communities, and the primary focus of these discussions has been focused on individual features or stories and the need to get them completely "done" (dev, test, acceptance test, documentation, delivered to customer) before they can be considered done. I wholeheartedly agree with this philosophy, to the point where I active introduce painful elements of software development to my team members, because the work must be done before we can deliver to the customer.

All that being said - I think we're missing out on some potential benefit by not applying "done" at various and different levels of our software development projects. For example, the concept of "done" can be applied to an iteration. What constitutes an iteration being "done"? It's certainly not just the time-box of 2 weeks, 1 month, or whatever our iteration length is defined as. However, that time box is still important. We don't want arbitrary lengths of iterations.

So how do we know when an iteration is completely "done" versus just being over? My initial thoughts revolve around a pass/fail checklist, similar to the swim lanes (or kanban board, if you want to call it that) that our stories go through. At this point, I would likely include the following:

  • Iteration length passed
  • All stories in iteration "done"
  • Code reviewed (possibly part of story being "done")
  • Software is in a stable, working state
  • Software acceptance tested by customer (or customer representative / SME)
  • Retrospective held

There's probably some additional items to include here - this is just my initial idea list.

Like the user story "done" criteria, an iteration cannot be considered "done" until all of the items in this list have been checked off. We don't give partial credit for a story making it to "in test", when there are 2 more columns to move through - the story is not done until it's completely "done". The same should apply to the iteration.

Why bother making an official "done" list for iterations? For the same simple reason we do this for user stories - transparency and visibility into bottlenecks and problems. It's easy for a team to ignore problems like broken software at the end of an iteration - "oh, it's just XYZ... i'll take care of that tomorrow" - when we don't have the same accountability as we do in our stories. By making the iteration a pass/fail set, we expose those problems for the world to see. This exposure is a great motivational tool - who wants to be caught with an un-"done" iteration because of a "simple" bug?

Do you and your team have an iteration "done" list? Do you even have a user story "done" list? It's all about exposing weakness and waste, then eliminating it and creating the official iteration "done" list is just one more step along the path. Don't stop there. What other processes - higher or lower level - can we standardize and improve?

Thursday, August 28, 2008 2:04:22 PM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: Acceptance Criteria | Acceptance Testing | Agile | Code Reviews | General | Lean Systems | Management | Philosophy of Software | Retrospectives | Standardized Work | User Stories

The one and only goal in software development is to provide useful, functional software that creates value for the customer or consumer. Period. End of story. Not open for discussion or opinions.

If you want to deliver software that the customer or consumer wants to use, likes to use, and ultimately does use to help solve problems and/or automate business process, etc, then you must know what the customer or consumer values. In other words - you can't identify your software's 'value' if you don't know who/what ALL of your customers are.

I'd put money down to say that most software developers - perhaps most software development companies - have no clue how many customers and consumers there really are for any given software project. The one consistent answer that I would expect from every developer or company is that the person, group, or company paying money for the software is the customer. This is 100%, absolutely true. In addition to the paying customer, though, there are many other customers or consumers that need to be identified.

As a starter, consider the following list for the customers / consumers of your software:

  • The paying customer
  • Integrated external systems
  • API consuming systems
  • Software Testers and Test Lab personnel
  • Technical and documentation writers
  • Software developers (the ones writing the code!)

I know, I know... how could a software developer possibly be considered a customer or consumer of the software that they are writing? The answer should be obvious - who reads and writes the code? who maintains the code and needs to understand how the code is structured so it can be maintained? If you don't believe that your software developers are first class consumers of the system that they are writing, I would bet that you have a horribly complex kludge of code that no one wants to work on. If your developers are considered first class consumers of the code they are writing, I would bet that your team is happy and is constantly working toward better code - simple, readable, maintainable systems that are fun to work on.

So, who are your customers or consumers? What value do they need in your system and from your system? And, how are you and your team responding to those value needs (if at all)?

Thursday, August 28, 2008 7:33:54 AM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: General | Lean Systems | Management

 Wednesday, August 27, 2008

Derick’s (brand new, just thought of it, but is now elevated to ‘mantra’ status for me) golden rule of Acceptance Criteria:

If it’s not usable by every team member, it’s not Acceptance Criteria.

And I do mean every team member - Customers, Testers, Tech Writers, BAs, Developers, UX Designers, and anyone else on your team.

You can specifying the technical or UI details in the story’s detail, but it’s not acceptance criteria – it’s Technical Criteria, or UI Criteria, or Test Automation Criteria, or … etc. Generally speaking, don't include these alternate criteria in the story detail – let the specific team members determine their specific criteria and record it how they need to (through unit test for devs, interaction design mockups for ui peeps, etc).

Wednesday, August 27, 2008 8:37:45 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Acceptance Criteria | Agile | Behavior Driven Development | Interaction Design | Management | User Stories

The entire team – BAs, Devs, UX, Testers, Tech Writers, Customers and Management (especially customers and management) – all need to understand that the first few iterations of a team that is trying to convert to an agile methodology, will be slow and painful. You won’t get as much done as you think you should. You’ll run into constant problems, questions, points of clarification, and unknowns.

 

Iterative development processes expose every single problem that your team never knew it had, and more – and if you’re honest and working with integrity, you won’t whitewash the problems and try to hide them; rather, you’ll embrace the transparency that iterations create and use it to drive improvement in your team.

 

Converting to Agile is painful and it’s embarrassing at time. There's no question that it’s difficult to convert – especially if the team has any significant habits or experience from previous projects (and who doesn’t, aside from entry level people). Work through the pain, solve the problems one at a time and continue to improve the process. Eventually, the team will find it’s groove and productivity will increase. Over time, if the team truly is honest with itself and is continuously solving problem, productivity should skyrocket and you’ll wonder how you ever worked without iterative / agile methodologies.

 

The key is - don’t expect it to be perfect… ever… take one step at a time and never stop moving forward.

Wednesday, August 27, 2008 8:33:56 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Lean Systems | Management

 Friday, August 08, 2008

In addition to our 'Code Review Challenge' that I discussed recently, we have been using another retrospective game - 'Name That Standard'.

The idea is fairly simple. At the beginning of any retrospective, we go around the room and ask each team member to list out a standard that we are using in our project. This can be any standard that anyone feels the team is using or needs to be using, including coding conventions, architectural patterns, business and project management processes, communication means, etc. The intention is similar to the intent of 'The Code Review Challenge' - socialization of the the system. Only in this case, we are applying the term 'the system' at a much higher level - our organizational and project management / implementation system as a whole.

Some thoughts on running 'Name That Standard':

  • Require not only naming of the standard, but accurate description of the standard and an example of where it is used. Alternatively, you may want to list a brief description out on a projector or whiteboard and see who can name the standard being described.
  • Encourage the team to think about the team as a whole, not just their area of responsibility.
  • Encourage the team to list standards that they don't understand, so that the rest of the team can chime in with assistance and help the team member in question grow
  • Don't just let people yell out standards. go around the room, one person at a time. we got a little chaotic at first, and it was hard to know who said what.
  • Encourage people to ask questions like 'i thought we were using this standard, but i saw someone else doing that standard'
  • Encourage the standards to become more and more low level and detailed, over time (over multiple iterations)
  • Encourage the standards to evolve and change for the better, over time (over multiple iterations)

In our implementations of this game, we've managed to get a fairly good list of standards written down and also resolved some questions on what standards we actually are using. For example, we had 3 dynamic mocking frameworks in our code base - Rhino Mocks, Moq, and a home grown one that we lovingly called 'BrandoMocks' (named for our team member, Brandon, who wrote it for fun one night). The end result of that discussion was to throw out Moq and BrandoMocks, adopting Rhino Mocks as our standard for this project.

Having done 'Name That Standard' in two consecutive iteration retrospectives, I think I can say that it has been very successful. The team as a whole is becoming more and more aware of the standards that we are using, and the individual members are beginning to contribute more and more to the standards.

With each passing iteration, and each new technique for creating collective ownership and socializing the system, I see the team coming together and really forming a team vs. a bunch of individual developers working on the same system.

Friday, August 08, 2008 7:58:10 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | Code Reviews | Community | Management | Principles and Patterns | Retrospectives | Rhino Mocks | Standardized Work

 Thursday, August 07, 2008

My team tried out 'The Code Review Challenge' in today's retrospective. Overall, I think it went pretty well for the first time that we've tried this. Here's some initial thoughts after our first attempt.

  1. Make sure the team knows what's going on before you start. I was not leading the review, and I had to step out right when it started. I believe the team lead explained the idea, but I'm not sure I had fully explained to her. In the end, ensuring that each team member is comfortable with the idea and the process is important.
  2. Encourage discussion with the group during the review. Don't force the talk from the reviewer, but ask questions that will help lead them to conclusions and descriptions of what is going on.
  3. Don't expect everyone on the team to be able to recognize the same standards, practices, or issues. each team member will have a different understanding of the standards that we are trying to apply, at any given time. encourage learning help others to see what you see.
  4. make sure everyone on the team has a chance to review someone else's code. i think we ended up with a good mix of people reviewing and being reviewed, but it wasn't planned, it just kind of happened. next time around, we're going to ensure that it happens by planning ahead based on the work done by the people in the review.

i think there was a lot of benefit in doing the reviews in this manner. we ended up with a lot of good comments, suggested improvements, etc. i'm happy to say that the code review challenge was a success and that we'll continue to do it in future retrospectives and reviews.

Thursday, August 07, 2008 6:07:38 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Code Reviews | Management

 Sunday, August 03, 2008

A Food Network Challenge

During this season's 'The Next Food Network Star', there was an episode where the contestants had to cook a dish and review it in front of a camera, describing it's visuals and taste. The twist to the challenge was that they were assigned someone else's dish to review, after everyone had already cooked. Once the assignments were made for who was going to describe who's dish, they were not allowed to see the dishes anymore. A given contestant was then put in front of a camera and had their assigned dish uncovered in front of them. From that point, they had 90 seconds to describe the dish that was in front of them - that included figuring out what it was, what it looks like, what it tasted like and what it smelled like. This was a rather tough challenge to watch, and a few of them didn't do so well.

A Code Review Challenge

What if we take the Next Food Network Star's challenge and apply it to code reviews? When we sit down in a code review session, rather than having the person who wrote the code doing the driving and telling us what is going on, have someone who has not seen the code do the driving - read the code, read the unit tests, etc - and describe to us what is going on. 90 seconds wouldn't be nearly enough time, though, so we'd have to change that time limit based on the size and complexity of the functionality being reviewed. Other than that, though, it seems like it would be a great way to test the team's ability to pick up an area of the system that they have not seen before and quickly learn it so that they can work in it.

Standardized Work - Judging Code And Code Reviewer

There are 2 real benefits to the code review challenge, as I see it:

  1. Judging how well did the coder apply our coding and development standards
  2. Judging how well the reviewer can recognize and describe the standards being applied

We are now building our system from User Stories, with Context / Specification style unit testing. One of the intents of this style of unit testing is to provide an easy-to-read and easy-to-learn set of examples for developers that need to know how to do something or how something works in the system. If the unit tests are properly written and expressive of the code's intent - it should be really easy to see what's going on. If we have good standards in place, a developer should be able to find the code in well organized areas, easily, and know where to look for the various components and parts.

It seems to me that the code review challenge would help to prove a number of these key factors in our projects and our teams:

  • Coding and architecture standards
    • How well the standards are known
    • How well the team follows the standards
  • Expressive Code
    • How easy is it to read the code
    • How easy is it to understand the code's intent
  • Maintainable Code
    • How easily can the code be changed and extended
    • How quickly the team can socialize and collectively own the system

A Challenge In Name, A Learning Experience In Practice

I would avoid applying any sort of point system or other reward / incentive for the code reviews. It seems that this could easily backfire and cause junior team members (in skill or time on the team/project) to feel intimidated or feel that it's an unfair process comparing them to the senior level team members. The intention of the code review challenge is not to cause dismay in any team member, but to create a learning environment by continuously challenging every member of the team. Ultimately, the code review challenge should foster the socialization of the system and lead to a strengthened sense of collective ownership, resulting in a better system.

 

Nothing New Under The Sun?

With all that being said - I'm doubtful that I'm the first person to ever hold a code review like this. I'd be interested in knowing if there's any standard development practices (Agile or otherwise) that are heading in the same direction. Any advice or opinions of you, the reader, would also be very welcomed.

If you know of a resource that describes the same basic ideas or if you have any input to help me improve the idea, please leave a comment and let me know.

Sunday, August 03, 2008 10:57:04 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Analysis and Design | Code Reviews | Community | Lean Systems | Management | Philosophy of Software | Standardized Work | User Stories

 Monday, July 21, 2008

Test Driven Development Is To Unit Testing As Interaction Design (IxD) Is To Accidental Design

One of the major problems with writing unit tests after the code is that it is very natural to write tests that prove the code works the way it was written, instead of the way it should work. Writing code test-first (via whatever flavor of Test Driven Development) flips that scenario right side up. TDD helps to ensure that code is written to work according to specifications and not the other way around.

Similarly, designing and/or implementing a UI after a behavior or process has been coded is a likely to result in a UI that fits the code model and not a model that fits the needed interaction and workflow. This situation must also be flipped right side up - interaction design should be done before, or at least in parallel, with coding. It cannot be left to accidental or incidental happenstance - interaction design must occur with proper interaction patterns and practices in mind.

Overlapping IxD and TDD

To overlap interaction design and test driven development, there are a few key words that need to be borrowed from interaction design. Fortunately, they easily fit within TDD development techniques and philosophies.

Epistemic work is exploratory in nature, or a process of trial and error through research. TDD and interaction design sketching are both epistemic. TDD explores API possibilities and allows easy trial and error to find the simplest implementation for what you need at the time. UI design sketches also allow you to quickly explore interaction designs - whether it's a white board, pencil and paper, graphics design software, or even quick-hack forms layout in IDEs. You can quickly and easily throw away a bad API in TDD and you can quickly and easily throw away a bad UI/Interaction design when you have nothing more than pencil sketches or white board drawings.

Pragmatic work is very structured and step-by-step in it's nature, implementing patterns and practices to fulfill what is needed at the moment. Implementing Code after writing unit test and implementing UI after designing around constraints are both pragmatic. TDD is pragmatic in that you only implement what is needed to properly pass the tests that have already been written. Similarly, with previously designed interactions and UI elements, implementation can be easily limited to what is needed for the UI.

With epistemic and pragmatic work covering both interaction design and test driven development, it seems that they are a natural pair. An analysis of a user story and it's acceptance criteria will create the unit tests that we need. At the same time, the same analysis can be applied to interaction designs. Additionally, a strong understanding of how a UI will look can have a profound impact on the code that is written, and vice-versa. Therefore, it is natural that interaction design and test driven development are done at just-in-time intervals - before the real work is implemented in the real code and UI platform.

IxD As Part of "Done"

Despite interaction design being a required part of UI development, not all user stories require a UI. Interaction design may not fit into a swim lane board or be part of every story's "done" criteria. However, interaction design will always be done for any story that does have a UI - it may simply be an accidental or incidental part of the software development process for a team, though. If it's safe to assume that the work will be done, then it is the team's responsibility to ensure that it is done correctly. Don't let interaction design happen accidentally or incidentally in the development process. Set a standard of always including interaction design in the development process, the same way Model View Presenter/Controller is a part of development.

Monday, July 21, 2008 8:47:04 AM (Central Standard Time, UTC-06:00)  #    Comments [3]. Trackback 
Tags: Agile | Analysis and Design | Behavior Driven Development | Interaction Design | Management | Model-View-Presenter | Principles and Patterns | Test Driven Development | Unit Testing | User Stories

 Sunday, July 20, 2008

Collective Ownership

One of the principles that I’ve tried to instill in my team(s) is that we are a collective ownership team. I've talked about Collective Code Ownership before, and I still believe it is needed to have a solid team. My views have recently expanded a little to include more than just the software developers on the project team - crossing all functional boundaries in a given project team.

Collective Ownership means that there is no one person on the team – developer, ba, tester, etc. – that "owns", controls, or is solely responsible for any one portion of the system. Code, documentation, and all other artifacts are owned by the entire team, as we should be working as a team to complete the project.  Obviously there are people who specialize in one area or another, so they will have more influence in those areas. Depending on the corporate culture that you work in, there may also be some boundaries that we can’t cross due to politics, etc. At the very least, though, every last line of source code in a project is owned by the team and is the responsibility of the team. The moment any artifact (code, images, documents, etc) is committed to source control or any other common project storage, the person that wrote/created/modified it is no longer directly responsible for it – the entire team is, and anyone on the team that sees a problem is expected to fix it or call attention to it so it can be fixed.

This principle is key to the team being able to create great software. We don’t want people to say "my code is better, and my area of the application works, but your code is bad and doesn’t work". This kind of divisive thinking will create a poorly constructed system that doesn’t fit together very well. We need to ensure that the entire team is saying "our code is good", or "our code needs work", and "I can help improve the team’s code base".

Your Code Is Terrible Because My Code Is Terrible

I’ve heard several times that a code base is only as good as the weakest developer on the team. I believe this is true – especially in a collective ownership environment. The moment a developer commits code, it is available for any other team member to modify, and therefore the quality of the code is immediately suspect and subject to the standards of the weakest team member.  Despite the potential problems that collective ownership creates, its very nature should help to bring the skill level of every developer on the team up, alleviating the 'weakest code' problem.

When a 'strong' developer sees the code of a 'weak' developer (those terms being relative to a lot of factors, of course) the strong developer should instinctively want to help the weak developer so that they are both producing better code. When a weak developer sees code that they believe is strong, they should instinctively want to mimic the qualities of that code and either ask for assistance or work to understand how to produce it on their own. Though it does take time and a lot of hard work, the end result should be that the collective weakness of the team disappears. The 'weakest' developer on the team will become an unknown – even irrelevant. Everyone will have strengths and weaknesses, but the team will balance each other out and the code that is delivered will be good.

Socializing The Design

For collective ownership to work, though, we have to ensure that the entire team is comfortable with the entire system. Each team member must be able to understand, update, and "own" any part of the system that they are currently working on (ownership being transitive, and forfeit once they commit the change, of course). For an entire team to be comfortable with the entire system, we need to socialize the design - that is, ensure the team understands the architecture and design fundamentals through the social aspects of working on a team. When we do a good job of socializing the design, it becomes much more natural for the team to collectively own the code. A given developer may not know anything about a given area of the system, but because there are good standards in place and everyone is aware of the overall design of the system, everyone on the team should be able to dig into any given area and learn it quickly.

The real challenge in socializing a design is figuring out what works for your team. There are as many ways of socializing the design, as there are systems and teams - some of which include:

  • Code reviews (formal and informal)
  • Pair programming
  • Email, Presentations, and other “here’s how you do xyz”
  • Wiki's, Forums, and other ways of asking “what do you think about xyz or 123”
  • Iteration retrospectives
  • Etc, etc, etc

No two teams or situations are alike, either. If you are limiting yourself to just a few of these techniques (or only the techniques listed here), you may not reach the full potential of your team's understanding. Try different combinations of socialization techniques and see what works well for your team.

End Goal: Continuous Improvement

In the end, a socialized design and collective ownership enable teams to work more efficiently by preventing the bottlenecks that 'I maintain XYZ' will create.  Code quality will rise, the team work work together, and we can start to move forward into better standards, better practices, and continuous improvement.

Sunday, July 20, 2008 8:47:09 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Community | Management | Philosophy of Software

 Tuesday, July 15, 2008

My team's first swim lanes!

IMAGE_236 IMAGE_239

From left to right: Backlog, In Dev, In Test, Docs, Done.

sweeeeet.

Tuesday, July 15, 2008 3:51:42 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Lean Systems | Management | User Stories

 Friday, July 11, 2008

Scott Bellware (who finally started blogging again), is posting a series on Sustaining Capacity in Maturing Agile Software Teams. It's worth a read, and may be familiar territory to anyone who has done Agile and been reading about Lean.

In the 3rd Post - Recognizing Entropy - he talks specifically about synchronizing the development testing and QA testing efforts:

Development and QA Test Synchronization. Without greater synchronization between development and QA testing, valuable input often comes too late in a development or release cycle to be effective. Test design and test architecture are valuable inputs to development, and software design and architecture are valuable inputs to QA testing. Teams often loose unrealized capacity by not pursuing means to do more development and testing in parallel.

This one really hit home for me, and is a shining beacon to the problems that my current team is going to face, soon. We had our first iteration planning and kickoff meeting yesterday, and the whole team was involved - except the testers from the QA department. For reasons that I have no control over (and honestly - they are legitimate business reasons), the QA department is not coming on to the project for another 2 months (at least).  Today, the team leadership was discussing how the QA personnel would create their test scenarios, and I brought up the point that creating the test scenarios after-the-fact (after the iterations are done) is going to be very problematic.

If a dev team is working from User Stories, and those User Stories are divided along various aspects of behavior, it is very likely that a single screen, workflow, or 'function' of a system is going to be divided into multiple user stories. When the QA team is involved with testing in parallel with the development team, this is not an issue because the QA team will be updating their test scenarios in each iteration. This allows them to keep the scenarios for a given screen, workflow, or 'function' of the system, growing over time. However, since our QA team is going to come into the project at least 2 months after the development team has started coding and testing, the QA team would have to sift through all of the current and previous iteration stories, try and aggregate them down into the screen, workflow, or 'function' of the system, and build test scenarios from there. If there is even a modest number of stories to sift through, this would be a daunting task for the QA team - they would be in a 'catch-up' mode from the beginning of their QA cycle, likely through the end of the project.

As a result of the QA team being unable to join our project immediately, we are forced to modify our entire development process and account for the needs of the QA team, after the fact. Essentially, we are creating additional swim-lanes for our stories to travel through, during an iteration:

  1. Backlog
  2. In Development
  3. Developer Testing
  4. Ad-Hoc Testing (BA's, Developers, etc. testing the app)
  5. QA Functional Spec Documentation
  6. Done

Swim-lane #4 and #5 are directly affected by the QA team not being able to enter the project immediately, and are causing the rest of the team to lower it's capacity. We (developers and BA's) are now required to do our own ad-hoc testing during the iterations, instead of letting the QA team take care of that; and we (the developers and BA's) are now required to create functional specifications, based on the user stories that are completed, to hand to the QA team once they are on the project. The functional specification documents will need to be updated for any given User Story, before the ticket is considered complete (the functional spec updates have become an acceptance criteria on every User Story).

End result - because we cannot get the QA team on our project immediately, and ensure that they are testing in parallel to the developers, we as the development team are losing capacity and building entropy from the very first day of the very first iteration.

Friday, July 11, 2008 4:11:41 PM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: Acceptance Testing | Agile | Lean Systems | Management | Pair+1 Programming | Test Driven Development | User Stories

 Wednesday, July 09, 2008

Visual Studio 2008 installs .NET 3.5 SDK v6.0A, which is what NAnt 0.86 expects to run against – however, the .NET 3.5 SDK that is available for download, via the "Windows 2008 and .NET 3.5 SDK", is v6.1

It’s a small difference, but that difference will cause NAnt 0.86 to not be able to target .NET 3.5 if you are using the downloadable .NET 3.5 SDK. When you try to run NAnt 0.86 and have it target .NET 3.5 with the downloaded .NET SDK, you will get an “Object reference” error from NAnt and the build will fail immediately.

image

Page Brooks has the details of how to fix NAnt to work against the v6.1 SDK. It is an easy fix, but it requires that every machine running NAnt have the v6.1 SDK installed (and if you want your devs to be able to run NAnt from their local machine, you’ll need all of the developers to install the updated version of the SDK).

End Result:

If you want to automate your VS2008 project builds with NAnt, you should probably have every developer on your team to install the new version of the SDK and have NAnt target that version.

Wednesday, July 09, 2008 12:10:31 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | General | Management | NAnt | Scripting

 Tuesday, July 01, 2008

Anyone that has worked on a project with me is familiar with my usual "I just fixed … whatever" emails. For example - yesterday, I sent out this email to my team:

FYI – I just pulled down the latest code from subversion, with the new solution and project reorganizations… there were several project reference errors in the {our project} solution – many of the projects were trying to reference the \Trunk\Code\Library\ folder for the compiled output of a project that was in the same solution.

We need to make sure that projects within the same solution reference the project directly, not the compiled dll file. You can make sure this is correct by deleting everything out of the Library folder, than updating it from subversion (to make sure you have no {our project}.dll files in the Library) and then see if you get any missing file errors in visual studio, for the project references.

I’ve been sending out similar email for several years now, and I’ve always felt that it was important to do so, so that the entire team can gain new insights, move forward with better techniques, creating better software, etc.

Yesterday, I found An Article on the Lean Manufacturing concept of Jidoka and a few items stuck out in my mind and helped me to understand why I think that it’s important to call out these items. The core of jidoka goes well beyond the basic idea of "If it's broke, fix it now". It gets much more involved than just that. The article has a list of steps that should be taken whenever something is found to be 'broken' or 'abnormal':

  1. Detect the abnormality
  2. Stop
  3. Fix or correct the immediate condition
  4. Investigate the root cause and install a countermeasure

There's a lot more to the real implementation of jidoka than just fixing the problem - finding the root cause and installing countermeasures to prevent it from happening again is by far the most important step in this process. If you fix the problem in isolation and no one else knows that the problem occurred, then it's likely that the problem will happen again for the same reasons. This gets straight to the core of why I send out the “I just fixed …” emails. I found this quote in the article that further illustrates the point:

What I would not want to happen is to expect the team member who discovered the problem to try to fix it without telling anyone. But many times we expect them to do just that, and the rework becomes so deeply embedded into the routine that we can't even tell it is happening. It seems normal because it has never been flagged as abnormal.

I don’t send out those emails to chastise anyone, point out that someone broke something, or anything negative like that. Honestly – I don’t care who broke something; I only care that it is broken, it gets fixed, and we find the cause and do what we can to eliminate that cause. I send out those emails because when we (as a team – any of us; developers, testers, subject matter experts, etc) find a situation that is not right, we need to fix it – but more importantly, we need to notify the rest of the team so that we can learn as a team and find ways to not make the same mistake in the future.

I highly recommend that everyone go read that article and I also want to suggest that any time any of us runs into a situation where something is wrong – whether it’s code that is written or designed poorly, a references issue, the build being broken, or whatever it is – we not only fix the problem, but we inform the team of what the problem is/was and how to fix it and prevent it. We need to have this level of communication in the team, or we are not going to grow as a team or as individual developers, as fast as we could.

Tuesday, July 01, 2008 7:50:11 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Community | Lean Systems | Management | Philosophy of Software

 Tuesday, June 03, 2008

Yesterday, I posted a quick thought on code generation, and one of the statements I made is worth re-stating to stand on it's own.

In Agile/Lean software development, a single User Story is one piece flow when implemented via TDD, in a Workcell

In Lean Manufacturing, one piece flow is the idea that you do not produce anything in batches, but that you produce one product from start to finish per a customer's order. In Lean / Agile software development, this is analogous to an iteration with user stories. An iteration backlog is a customer order - a set of behaviors or features that are requested to be delivered in the current iteration. A user story is the single piece that we want to flow from beginning to end - from the start of coding all the way to acceptance via user testing.

In manufacturing, a Workcell is used to facilitate one piece flow through the manufacturing process. In software development, a Workcell is also used to facilitate the one piece flow. The Workcell may be 1 person, pair programming or a three person team. In order for it to truly be one piece flow, though, strict standards such as TDD and automated acceptance tests must be followed.

I'm not going to detail the benefits of one piece flow, here (not yet, anyway... another post for another time). I highly recommend that you read The Toyota Way and Lean Thinking for a good understanding of this concept and the benefits it provides.

Tuesday, June 03, 2008 9:44:41 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Acceptance Testing | Behavior Driven Development | Lean Systems | Management | Philosophy of Software | Test Driven Development | User Stories

 Wednesday, April 30, 2008

I'm reading "Lean Software Development: An Agile Toolkit", and the first paragraph under "Tool 11: Queuing Theory" talks about the bottleneck that often occurs in the test lab - not enough testers, too much work for the number of testers, etc.

"We have often heard the lament 'My biggest problem is the testing department.' Now, testing people are very nice people: dedicated, hard working, and very important to the development effort. But there never seems to be enough of them to go around. And although the developers might write their own unit tests, testers frequently do acceptance testing. So, without enough testers, the whole development process bogs down."

The rest of the chapter talks about the queuing theory that can be applied to help alleviate the issue. It's a great chapter with lots of good information. I have a problem with the idea of applying this type of queuing theory to the the test lab, as a bottleneck, though.

First, let me state some assumptions about the primary responsibility of the testers in the test lab:

  • Testers are writing automated acceptance tests, for automated regression testing and integration testing
  • Testers are also doing human interaction testing, for the "human touch" of usability, etc.

If the testers are the bottleneck, and the two primary functions of the testers are as I have listed, then I think the there is a much more simple solution to the problem, from a lean perspective:

let the developers write the automated acceptance tests.

Assuming that the developers are already writing unit tests, and are therefore capable of writing code to test code, it makes a lot of sense in my mind that the developers should be writing the majority of the automated acceptance tests. It all goes back to the idea of flow - ensuring that the entire system (or process) has a smooth flow from beginning to end. This means that we may need to sub-optimize one area for the benefit of the whole, but the end result is that we will have a better system or process by making the entire flow as smooth as possible.

Counteracting Mura - or "Let's make it smooooooth"

If we are looking at the test lab as a bottleneck - a rough spot in the flow of our software development cycles - then let's take the most simple course of action possible, to reduce that rough spot as much as possible. Rather than spending so much time and effort on queuing theory and implementation, let's find a way to remove the bottleneck.

Assume that the software developers are experts at writing code - and writing code to test their code. Doesn't it make sense, then, that the software developers should be writing the acceptance tests, even if the acceptance tests are being specified by the customer and test lab personnel? If we allow the developers to take a little more responsibility, we may be sub-optimizing the development department a little. But, by doing so we are freeing up the much more scarce resources of the test lab and we can then make adjustments to the test lab's queue and workload, if needed. The idea of leveling out the flow of the system like this can be traced back to the Japanese term, Mura. The Wikipedia entry says it all:

"The fact that there is one operator will force a smoothness across the operations because the workpiece flows with the operator."

In this case, we are calling the combination of production code, unit tests and acceptance tests, the "workpiece". I believe this is a fair assesment, since the code and tests are all going to be based on a feature, use case, or user story. In fact, I would say that the workpeice actually is the feature, use case or user story that is being worked on. The code, unit tests and acceptance tests could be considered the artifacts products by the workpeice flowing through the system. ... but that's just splitting hairs, really.

It's all about Occam's razor, Parsimony, KISS, or whatever you want to call it - the simple solution is often the correct solution (simple, however, doesn't always mean easy).

The Need for the Test Lab

I'm certainly not saying we don't need a test lab. The testers are (supposed to be) experts in interaction testing, usability testing, and adding that "human touch". We absolutely need that perspective on those aspects of software testing that can't reasonably be automated. I am advocating that we find a better way to smooth the flow of the system - rather than apply complex theories and equations to the situation, find a solution that doesn't require anything complex.

Conclusions

In the end, the problem of the test lab bottleneck can be solved many different ways. You might level the system via Pair +1 Programming or some other form of involving the developers in writing the automated acceptance tests. Perhaps you make the testers part of the team and have them writing the automated tests at the same time as the developers writing code. You might still need to employ queuing theory. Either way, try to find the solution that works best to smooth out the process for your team.

Wednesday, April 30, 2008 2:22:44 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Acceptance Testing | Agile | Behavior Driven Development | Management | Pair+1 Programming | Test Driven Development | Unit Testing

 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

 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

 Saturday, April 05, 2008

I've been hearing this a lot lately, and finally started reading up on the roots of the Agile movement. It all goes back to Lean Manufacturing. Oddly enough, I've had exposure to Lean Manufacturing at a previous job. So the concepts and names are all very familiar to me. Back in those days, I had heard of the concept of Lean Software Development, but it never really made any impact on how I wrote software. These days, though, I'm diving into as much Agile as possible and the further down the road that I travel, the more and more parallels I see, to the lean manufacturing world.

If you are at all interested in the roots of agile, here's some recommend reading (mostly Wikipedia) to get you started.

Wikipedia:

Books:

I'm hoping to absorb more of this information, quickly. It seems the more I learn about lean manufacturing, the more I understand about software development. I certainly don't claim to be an expert on either subject... hopefully I can change that.

Saturday, April 05, 2008 11:58:24 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Behavior Driven Development | General | Lean Systems | Management | Philosophy of Software

 Wednesday, April 02, 2008

Way back in the day (somewhere around 1994 or 1995, I think), I saw the movie, "Search for Bobby Fischer". One of the lines that has always stuck in my head is from the teacher, Vinnie:

He didn't teach you how to win, he taught you how not to lose.

At the time, I didn't like this line - I didn't understand why playing "not to lose" was different than playing to win. Over the years, I've seen variations of this statement and had a little more understanding of what it actually means. Last night, though, I was involved in various philosophy-of-software discussions with a friend and this quote popped up in my mind again, in the context of project failure and the fear of failure. I think I finally understand what this quote is saying, now - and it all comes down to the fear of failure vs. embracing failure as an opportunity to learn and find new ways to succeed.

Knowing Success Through Failure

Looking back at my life, I have two very distinct memories of catastrophic failure - the kind of failure where I was so emotionally invested in the project or goal, that the failure was truly devastating to the point where I would have a complete breakdown and be entirely lost for a while.

The first of these memories was back in College. I have an associates degree (AA) in music, from a junior college back in my hometown in Kansas. After graduating with that degree, I found another school in Denver that had a sound recording / engineering track in their music school and I signed up for it with all the passion and motivation that I now have for software development. When I moved on to campus at that school and started figuring out what classes I would be taking, etc., I found out that I had slipped through the cracks in the school of music. As it turns out, I was supposed to have interviewed for the school of music and done some performance in front of various professors, to be accepted. With that in mind, I worked with the director of the program and did my performances - and completely failed. As it turns out, I had a general skill with musical instruments and could play just about anything at a very mediocre level, but I was not terribly good at any instrument. The end is result is that I was told (in very kind, helpful terms) that I would need a few years of lessons before I could be accepted into the school of music. Needless to say, this was a very devastating experience for me. My goal and my dream, at the time, was to be a musician and work in a recording studio. Shortly after the realization that my goal was unattainable, I had various talks with various people close to me and some talks with the director of the music school. We quickly realized that I could still attain the primary goal in my dream - to work in a sound recording studio and be in the sound recording / engineering program at the school - but my specified major would not be music. I ended up in the Management Information System department, with that being my major, while still taking the sound recording / engineering classes.

The second of these memories is significantly less important in the grand scheme of my life. A few years ago, I was attempting to install a new car stereo system in my car. I had done stereo and speaker installation before, but had never done an amp and subwoofer. Over a 4 day weekend, I ended up with a car that had no working speakers, a blown amp, and a subwoofer with holes punched in it. At the time, this was another very devastating outcome for me - I had a very specific goal in mind and had spent a significant amount of time and money on the project, with no usable results. Two days later, I had my car in a professional car audio shop with professional audio installation personnel fixing the problems and installing a new amp and subwoofer. The end result was that I had a great system in my car.

Looking back at both of these experiences, I see a pattern: a project or goal, a significant personal investment, a catastrophic failure and finally, an outcome that still satisfied my criteria for success.

There's an old cliche line that I've heard many times:

You can't know true success unless you know true failure.

I believe I've been as close to true failure as I can get, without giving up on a project or goal. True failure, though, can only come from giving up.

Playing To Win vs. Playing Not To Lose

My career as a software developer has been very interesting, so far. I've had a lot of great success and a few fairly large failures. What's really interesting to me, though, is looking back at those failures and seeing the risk that I was willing take. I've jumped into some very difficult, new, demanding situations with little or no knowledge and experience in those situations. Many times, I was able to find the experience quickly and succeed, but some times I was not able to find the experience quickly enough and I failed. These successes and failures are why I believe I understand the issue of playing to win vs. playing not to lose, now. As I said before, it all comes down to the fear of failure vs. embracing failure as an opportunity to learn and find new ways to succeed. With this in mind, I have some questions that may help you understand playing to win vs. playing not to lose.

Are you willing to take risks in your project? Are you willing to put forth the effort involved in trying to create what could be a better you, or a better project, knowing that you could fail if you try? Are you willing to open yourself for failure so that you can learn, and have a greater chance of greater success?

Are you playing to win?

Or are you only willing to do the work that you are comfortable with now, and only willing to learn a little bit of something new, keeping a safety net around yourself? Are you willing to keep yourself from taking risk so that you don't have any significant chance of failure, and no significant growth? Are you afraid of change or afraid that you will fail?

Are you playing not to lose?

Good Judgement and Experience

Another tired old cliche that I've heard a thousand times:

Good judgement comes from experience. Experience comes from bad judgement.

I make a dozen bad decisions every day. I also make a dozen good decisions every day, because I am willing to honestly look at the decisions I've made and admit that they were bad decisions. By allowing myself to understand that these decisions were bad decisions, and admitting that to not only myself, but to my managers and team members as well, I set myself up for success. I'm able to look at these decisions, understand why there wrong, and correct the mistakes. And by doing this on a daily basis, if not more often, I can mitigate the failure that any one decision may cause.

Embracing Failure Without Fearing It

One of the reasons I am so in love with Test Driven Development and Behavior Driven Development is that it accelerates the failure-to-success process. I'm not unit testing to prove that I have not failed. I'm unit testing to prove that I have succeeded and created the API that I want.

I expect failure when I unit test. I expect to write horrible APIs that are unusable, ugly, stupid, and obnoxious. I WANT to realize that I am doing this, through my unit tests, because I can accelerate the process of realization and correction by using my unit tests as a design tool.

And I challenge you to do the same - to stop fearing failure and not be afraid to make mistakes. If you believe you have made a mistake, expose it for peer review. Ask for others to validate or invalidate that mistake and learn from the experience. Find the tools, techniques, coworkers and peers that will help you accelerate the realization of failure so that you can correct the failure and succeed, faster.

A Personal Rant: My Success As A Developer

I believe I am a very successful software developer and leader. I have a lot of experience under my belt and a lot of knowledge that I want to share with others.

So, why am I successful? Why was I responsible for the public face of a 300 million dollar multi-national corporation, through it's web sites, when I was 22 years old? Why was I made the lead developer in a team of 10, when I was the new guy in the office? Why am I now diving into the cutting edge of Behavior Driven Development and actively involved in the Agile community? Why am I making a name for myself not only in my office, but also in the development world outside of my office?

Because I take risk and embrace my failures. I openly admit my failures at the first possible moment, so that I can learn. I actively seek the voice of dissent and the views that I don't agree with, so that I can be proven to be wrong and learn how to be right.

Why am I successful? Because I play to win.

Wednesday, April 02, 2008 8:38:07 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: General | Management | Philosophy of Software

 Monday, March 31, 2008

A while back, I posted a stream of thoughts concerning programming in triples. The basic idea is that we have 2 developers doing pair programming and a third developer doing automated acceptance test development, on the same story at the same time.

Triples Programming Terms

I've been discussing this idea with various people since then, and I'm finding myself referring to this team organization with a specific term, now:

Pair+1 Programming

I don't know if this term has been used previously, or if there is already a term for this. However, I find this to be a good name for the organization that I am talking about.  It really is pair programming, as defined by many common sources, plus one acceptance test developer. The really fun part is that all three of the developers in this unit will switch roles throughout the day. The end result is that we have a very well cross-trained team - each member of each unit will be responsible for writing unit tests, writing production code, writing acceptance tests, and thinking ahead of the current code, throughout any given day.

An Agile Team includes more than just the developers - the customers, the test lead, the technical writers, the project manager, etc., are all part of the team. Pair+1 Programming is not into teams. A "team" implies that they the persons involved are fairly static - they don't move between teams, etc. In order to distinguish the Pair+1 organization from the Team as a whole, I am also going to refer to this group with another name:

Development Unit (Update: based on further discussion, renaming this)

WorkCell

Just as a developer will rotate rolls within the Unit, I believe Pair+1 programmers should move between WorkCells on a regular basis. This will further the cross-training that occurs and help to pollinate the knowledge of one WorkCell into the thoughts and goals of other WorkCells. The migration is likely to be less volatile than the role switching that happens within a WorkCell. For example, developers rotate positions every 2 or 3 hours, within the WorkCell, whereas a developer may only rotate between WorkCells once a day or once a week.

Development Systems

Within each Development Unit, there will be two development systems.

  1. The primary system of that Unit will be the pair programming system. This system should have a very large monitor - 30" is preferable - to allow the Pair to easy see everything on the screen.
  2. The secondary system will be used for Acceptance Tests and is likely to only need a 22" or 24" monitor, as it will be primarily used by a single developer.

Each of these systems, aside from monitor size, should be a mirror of each other - the same system specs with the same software development packages installed. Every machine used for development should be able to execute any of the tests - unit tests or acceptance tests - no matter the primary use of that development machine. This is required so that the Pair working on the Development machine can execute the Acceptance Tests being created on the Acceptance Test machine; thus ensuring that they are coding appropriately, and passing the expected tests. The Acceptance Test developer should also be able to execute the code being written by the Pair, to ensure that the Acceptance Tests are being written against the API correctly.

Following standard Agile practices, these machines should not be concerned with Email, IM, or other non-development tasks. They should be dedicated entirely to development work. If a person needs Email, IM, etc. then the office space should provide access via shared systems and/or a developer should have their own system (likely a laptop) that they can take with them wherever they go. The point is, though, to remove distraction from the Development Unit. Keep the non-development software off the Unit's systems, as much as possible, to ensure that the Unit can focus on development and not be distracted by 50 different flashing icons and windows on the machine.

Disclaimer

A lot of my thoughts are purely academic, at this point. I am hopefully going to have some actual experience with this environment, soon. As such, I am trying to organize my thoughts so that I can have some direction to start with. I reserve the right to be wrong and change my mind whenever I want, likely re-defining the terms and processes involved in Pair+1 Programming.

Monday, March 31, 2008 2:26:19 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Acceptance Testing | Agile | Behavior Driven Development | Management | Pair+1 Programming | Unit Testing

 Wednesday, March 26, 2008

In the last few months, I've heard a person say this multiple times

"business runs on de-normalized data"

The context of this statement has always been the discussion of database design and implementation... and I continue to wonder where this person's experience is coming from, to make such a statement. In my world - the business of developing software to run a business or automate a portion of a business - this is very far from the truth. My response to this statement is (and yes, you can quote me on this - please do)

Management reports on de-normalized data, but operations runs entirely on well-normalized data

I'm not going to make any ignorant or naive claims about de-normalized data having no place in business. There certainly is a lot of business value in de-normalized data. That's why we have data warehousing, OLAP cubes, and other reporting database structures (including Views, Stored Procedures, etc. that will de-normalize data for live reporting). When it comes to the day to day business, though - the people on the floor doing the low level business work - well normalized data is an absolute must.

From WikiPedia's entry on Database Normalization:

Database normalization, sometimes referred to as canonical synthesis, is a technique for designing relational database tables to minimize duplication of information and, in so doing, to safeguard the database against certain types of logical or structural problems, namely data anomalies. For example, when multiple instances of a given piece of information occur in a table, the possibility exists that these instances will not be kept consistent when the data within the table is updated, leading to a loss of data integrity. A table that is sufficiently normalized is less vulnerable to problems of this kind, because its structure reflects the basic assumptions for when multiple instances of the same information should be represented by a single instance only.

I'm certainly not a DBA and I'm not a real database guru. I do have more than 10 years experience working with various database systems (SQL Server, Access, Oracle, SQLite, MySQL, DB2/DB400, and XML & flat files , etc.) in various business scenarios (manufacturing, engineering, business process automation, e-commerce/e-business, enterprise integration, etc. etc.) and I have a pretty high opinion of my relational modeling capabilities ... and It evokes a sense of disbelief and shock when I see poorly normalized schema's or hear statements like this being made.

Please, please, PLEASE take the time to understand what well normalized database design is and why it's necessary for flexible, maintainable software.

Wednesday, March 26, 2008 12:38:04 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Data Access | Database Design | Management

Navigation
About Me
View Derick Bailey's profile on LinkedIn

Send mail to the author(s) Contact Me
Archive
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
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 2010
Derick Bailey
Sign In
Statistics
Total Posts: 115
This Year: 0
This Month: 0
This Week: 0
Comments: 44
Themes
Pick a theme:
All Content © 2010, Derick Bailey
DasBlog theme 'Business' created by Christoph De Baene (delarou)