Exploring Solution Spaces © Copyright 2003-2006, by C. Keith Ray
   


About
Exploring Solution Spaces, Keith Ray's blog on Software development and other topics.

Send comments to:
keithray@mac.com

For Agile Training, eLearning, or Coaching contact:
Industrial Logic, Inc.
866-540-8336 (toll free)
510-540-8336 (Berkeley, California)

Links
xpminifaq
Résumé
“Adopting XP” Article 2002 (pdf)
“ Refactoring” Article 2006
AYE Conference
Lucien W. Dupont
Elisabeth Hendrickson
Johanna Rothman's Managing Product Development
Brian Marick's Exploration Through Example
Esther Derby's Insights You Can Use
Laurent Bossavit's Incipient(thoughts)
Dale Emery's Conversations with Dale
Martin Fowler's Bliki
Creating Passionate Users

Archives

  • 2003
  • 2004
  • 2005
  • 2006
  • 2007
  • 2008
  • Subscribe
    RSS Exploring Solution Spaces XML


           
    2003.Nov.15 Sat

    More Software Pokayoke

    One difference between Pokayoke in manufacturing compared to software, is that software is always unique and fresh (if it isn't, some re-use is lacking). To "manufacture" a software product, simply copy the CD-ROM or post the installer on a web-site. However, pokayoke is always about quality assurance in either domain; either detecting problems as soon as possible, or preventing problems from happening.

    Harry Robinson has an article about a Pokayoke software tool here: http://www.campbell.berry.edu/faculty/jgrout/pokasoft.html, along with some background material about Pokayoke. Quotes:

    Shigeo Shingo was a leading proponent of statistical process control in Japanese manufacturing in the 1950s, but became frustrated with the statistical approach as he realized that it would never reduce product defects to zero....

    While visiting the Yamada Electric plant in 1961, Shingo was told of a problem that the factory had with one of its products. Part of the product was a small switch with two push-buttons supported by two springs. Occasionally, the worker assembling the switch would forget to insert a spring under each push-button.... This problem of the missing spring was both costly and embarrassing. Management at the factory would warn the employees to pay more attention to their work, but despite everyone's best intentions, the missing spring problem would eventually re-appear.

    Shingo suggested a solution that became the first poka-yoke device:

    In the old method, a worker began by taking two springs out of a large parts box and then assembled a switch.

    In the new approach, a small dish is placed in front of the parts box and the worker's first task is to take two springs out of the box and place them on the dish. Then the worker assembles the switch. If any spring remains on the dish, then the worker knows that he or she has forgotten to insert it.

    The new procedure completely eliminated the problem of the missing springs.

    Shingo went on to develop this mistake-proofing concept for the next three decades. One crucial distinction he made was between a mistake and a defect. Mistakes are inevitable; people are human and cannot be expected to concentrate all the time on the work in front of them or to understand completely the instructions they are given. Defects result from allowing a mistake to reach the customer, and defects are entirely avoidable. The goal of poka-yoke is to engineer the process so that mistakes can be prevented or immediately detected and corrected. Poka-yoke devices proliferated in Japanese plants over the next three decades, causing one observer to note:

    It is not one device, but the application of hundreds and thousands of these very simple "fail-safing" mechanisms that day after day has brought the quality miracle to Japan. Each one is relatively simple -- something you easily could do on your own. It is the totality, the hundreds of devices, that is almost frightening to behold.

    Let me rant about bit a the Standard C Library. This library represents not the best or most appropriate set of functions that C programmers need to use, just the the ones that were most commonly implemented by C compiler vendors when the standardization process was begun. The string functions provided by the library are dangerous. For example, the string-copy function "strcpy(destBuffer,srcBuffer)" doesn't check the size of the destination buffer, so copying a too-large string can overwrite the stack or memory, provided us with countless bugs and security holes. Also countless lines of duplicate code where the programmer checked the size of the source string against the destination buffer-size before doing the copy.

    The Standard C Library contains what might be considered a safer string-copy function "strncpy(destBuffer,srcBuffer,destBufferSize)" that will not copy characters beyond last byte of the destination buffer. But it will not terminate the string with a null-byte in the destination buffer if the source string is longer than the destination buffer. This lack of string termination means that functions expecting a well-formed string in that destination buffer will misbehave: accessing memory beyond the end of the buffer. A programmer who does not know this "gotcha" will have created another bug and/or security defect. Once again we will have countless amounts of duplicated code as the some programmers either write a "safe strncpy" function, or add a line of code to insure the destination buffer has a terminating null-byte every time they use strncpy.

    And guess what? There's another problem with strncpy (and most "safe strncpy" implementations). It doesn't copy characters, it copies bytes. In multiple-byte encodings like SJIS and UTF8, half of a multiple-byte character could be left at the end of the buffer, if the buffer just happens to be one byte too short.

    I avoid most of the problems with strcpy/strncpy, etc., by using the C++ std::string class. It dynamically allocates memory for strings, so I never have to consider buffer-sizes. This helps mistake-proof string coding. One frustration I have with this class, is that it is possible to pass a null-pointer into the constructor. The standard says that a character-pointer passed into the constructor must not be a null-pointer, but the implementations I use will not detect this situation. Generally, if this happens, there will be a crash sooner or later, and some debugging will be required to find out how a null-pointer got passed into a std::string. If the implementation of std::string had a simple line of code -- "assert(ptr != NULL);" -- the debugging time would be reduced.

    C and C++ have a problem where its static type-checking falls down: integers are freely (and silently) convertible to pointers and bools, and vice-versa. In this domain, the language is "loosely-typed". The bool value 'false' can be passed into a std::string constructor because the compiler changes it character-pointer (whose value is the null-pointer). A character-pointer can be assigned to a bool variable - if the character-pointer is the null-pointer, then the bool variable takes on the value 'false', otherwise it takes on the value 'true'. Microsoft's CString class used in MFC has a "type-cast" operator method that returns a character-pointer to the CString's internal buffer. I recently found some code that "assigned" a CStdString (a cross-platform class with an API similar to CString) to a bool variable -- this silently called the character-pointer type-cast operator and assigned 'true' to that variable, since CStdString allocates its own non-null buffer. Not at all what I wanted.

    Fortunately, I can avoid std::string and CString and use (and customize) CStdString. My version of CStdString has an assertion to detect being passed a null-pointer. My version of CStdString does not define a character-pointer type-cast operator. These two changes help mistake-proof my code.

    [/docs] permanent link