Key Design Practices for Agile Development of Medical Devices
bDouglass 270001GVVD Visits (8803)
I’ve developed a number of medical devices in my career
ranging from cardiac pacemakers to integrated anesthesia systems. As many of
you know, I’m also a big proponent of agile methods, primarily as a means of
improving quality but also as a way of improving engineering efficiency. For most people, finding published
information on how to apply agile methods to regulated, safety-critical systems
is difficult. I’ve tried to fill this gap with books such as “Real-Time Agility”
In terms of design, there are a number of practices that I’ve found particularly useful:
By HFM, I refer to the creation of systems or software models, mostly in the SysML or UML, that specify structure, behavior and functionality. The key is that the models must be precise enough for verification. Models that are vague and imprecise do add some minor value – such as fostering a conversation as to what exactly you meant – but the true value of HFM comes in when you can construct design statements that can be directly verified. Oh, and source code can be automatically generated from such designs with advanced tools such as Rational Rhapsody. Note, however, that even if I wanted to write the code by hand, I would still create and verify my design.
Figure 1: Drug Delivery Design Model
The idea of TDD is to create and apply white-box test cases as you develop the implementation. This is done so as to avoid the insertion of defects in the implementation, rather than the more tradition defect insertion-removal cycle. In a HFM modeling environment, this means that you will develop and test your designs at the design level of abstraction. In the Harmony process, the nanocycle is the very short design-code-test cycle normally ranging from 20-60 minutes long. The design grows incrementally using elements of proven correctness, greatly improving the quality of the final end product and shortening the integration and system verification phases.
Figure 2: Basic TDD Flow
A design pattern is a generalized solution to a
commonly-occurring problem. Large-scale patterns, such as those in my book “Real-Time
Design Patterns: Robust Scalable Architecture for Real-Time Systems” (htt
Figure 3: Key Architectural Views
The system architecture is generally composed from one or more patterns from each of these views.
The idea of DD has been around a long time but it is not often implemented in systems for “performance reasons”. The idea is simple: all functionality as assumptions of what is true before the behavior is invoked (pre-conditional invariants), what is true after the behavior has completed (post-conditional invariants) and things that are assumed to be universally true (class invariants). DD assumes these invariants are not (invariant, that is) and puts in place means to detect when those assumptions are violated and behavior to do the right thing in those cases. I’ve seen far too many system fail catastrophically when a error code is ignored or memory isn’t available, or a race condition manifests. It’s time to do it right. As Grady Booch has said “If we build houses like we build software, the first woodpecker would have destroyed civilization.”
Figure 4: Example of Defensive Design
The last practice I’ll mention here (yes, there are more!) is CI. Most projects plan a short period of time to integrate various software components together and software and hardware, but end up spending long periods of (unplanned) work to get the pieces of the system interacting properly. This is usually because the pieces are created in silos, integration is deferred until late in the project, and a great deal of rework is required. CI avoids this mess by integrated constantly throughout the project with incomplete and immature pieces still integrating. The basic rule is that you’re not allowed to “break the build” so that it builds each and every day. Thus, any incompatibilities among the system elements are identified early, minimizing the rework necessary.
Figure 5: How Continuous Integration runs parallel with development activities
Agile methods change the emphasis from a ballistic, up-front plan to a plan that evolves based on evidence of project success. Agile methods are realized through the application of practices around analysis, design, project planning, project governance, and verification. Based on my experience, the key design practices are High Fidelity Modeling, Test-Driven Development, Pattern-oriented architectures, Defensive Design, and Continuous Integration. What design practices have you found particularly helpful?