What is a Software Unit?
By Mitch on Friday 11 January 2013, 14:08 - Standards - Permalink
IEC 62304 requires to split architecture of class C (mission critical) software into software items and software units. Software units are software items that can't be split into sub-items, according to the standard. Okay. But how to decide that an item can't be split into sub-items, and is a unit?
There had been a long and excellent discussion about that subject on elsmar cove forum a few years ago. I use some outputs of this discussion in my post. I draw different conclusions, however.
Here is the short answer that cames in mind of any developer. A software unit is:
- a set of procedures or functions, in a procedural or functional language,
- a class and its nested classes, in an object or object-oriented language.
Be it procedural or object oriented, these procedures/functions/classes are grouped in a source file.
This is certainly right in many cases. But I think that it's not always relevant in all cases. Let me argue!
Software equals modeling
Software design is modeling how data are processed. The less detailed model is the user requirements or use cases. The most refined modeling is ... the software code itself that does the job. In between we have a few levels of granularity, usually:
- Systems and subsystems,
- Main software items, that can be
- Processes or services if we think about deployment,
- Topmost packages or components if we think about development
- Software items of lower level (level 1) nested inside the main items,
- Software items of lower level (level 2) nested inside level 1 items,
- ... and so on down to software units.
Don't go too low
Delving on the details of software, one can argue that a software unit is:
- a processor instruction,
- a language instruction,
- a line of code,
- a loop,
- a branch of an if then else instruction.
We don't go that far in modeling because we all know that there is nothing to gain from such a level of scrutiny. There is a level at which the modeling ends and the programming begins.
But when does the programming begins?
Think about patterns
Software engineers and developers have the habit to think about patterns. There are lots of reusable patterns, like the very generic design patterns of the gang of four, or more specific patterns, or patterns found in software libraries like GUI.
So a set of classes/procedures/functions grouped to implement a pattern could be seen as a software unit.
Another proof in favor of patterns is when refactoring is necessary. Most of times, we don't refactor a class/procedure/function. We refactor a set of classes/procedures/functions to enhance their performance, their consistency.
Thinking about patterns brings also a dynamic view of software behavior that doesn't appear in single classes/functions. The pattern is used for a specific purpose that can be highlighted. Thanks to the pattern, we can highlight interaction between software units. We can also communicate easily on the internal classes/procedures inside a well-known pattern.
Think about interfaces
Interfaces are often a source of bugs and software failure. At which level is it necessary to go in the software items to describe the functioning of an interface?
If an interface is not well described by the software units representing it, then they probably aren't software units. They are software items that need to be refined in software items/units to describe the interface well.
Think about risks
We always have to think about risks in the medical devices industry. Risk mitigation can be a good clue to define the level of details necessary to software modeling.
Is it relevant to split a software item in one or more software units, to explain in which unit the risks resides and/or in which unit it is mitigated?
If yes, then the software item has to be modeled more in details, with items of lower levels, down to units.
Remember we do all of this (Software architecture, modeling, IEC 62034 and so on) to avoid software failures and mitigate risks.
Use programming language structure
Programming languages offer many ways to organize sets of classes/procedures/functions:
I personally like organizing software code with packages (mandatory in languages like java or .Net family) or namespaces (in C++ but optional) or modules (in procedural languages). Packages/namespaces/modules of lowest level can be a good way to name software units and group classes/procedures/functions.
The way we do software modeling, using design patterns, and the way programming languages allow to organize code, using packages or namespaces, speak in favor of software units of higher level than classes or procedures in a source file.
There are undoubtedly cases where classes or procedures are the right level of software units (like tiny embedded SW in microcontrollers).
But for most of software, modeling down to single classes/procedures doesn't bring more information about its functioning and doesn't make a better risk analysis.
Next article will be about when doing this job, given the software class (A, B, or C) according to IEC 62304.
Thanks for the articles and the information you share, its great! I think this article is very interesting.
What is not clear to me is, 62304 talks about software units and specifying interfaces. It looks here that you are describing something similar to "Component based programming". Is that right? My understanding of component based programming was that it is useful for large scale enterprise systems and implementing micro-services architectures and such. I have read about it in the Ian Somerville books and in the "UML Component" book by Cheeseman and Daniels. Is this article saying that the same approach would be useful for class C embedded medical devices? Is 62304 saying that we must use Component Based Programming and design for class C medical devices? What if the amount of software was closer to being more easily represented using plain classes and OO? Would we still be required to "componentise" the software and add interfaces?
I really appreciate the work you have put down to decipher the IEC 62304!
The definition of UNIT seems to imply that a UNIT cannot depend on another UNIT. Also in B.5.4 the standard says "UNITS can be tested separately".
Surely it is good to minimize tight dependencies between UNITS. But how am I supposed to e.g. work with general purpose libraries/modules (which are UNITS on their own)? These libraries are usually used extensively everywhere. The standard seems to categorically mandate that UNITS should be implemented in such way that they can be tested in separation even from general purpose libraries/modules.
Please tell me that there's a less restrictive way to interpret the standard.
Any comments appreciated!