One of the foundation stones of software architecture is the idea of modularity, or modular design. The only problem is that while the concepts of modular design are well-known, the term “module” seems to get used at times in rather inexact ways. So what is a module? Depending on who’s speaking it sometimes appears to refer to a VI, sometimes to a library or collection of VIs, and sometimes even a whole program or executable can be called a module. The thing is, all those are legitimate usages of the word — and they are just the beginning.
So how is one to keep straight what is meant? The only way that I have found is to stay alert, and keep straight in your head the conversation’s context. Well-designed software is always modular, but it is also hierarchical. Consequently, the modularity will also be hierarchical. For example, a VI can encapsulate some functionality that you wish to use through out a project (or across multiple projects) and so can be considered a module. But that VI can also be used as part of a higher-level more-abstract module that uses it to implement some broader system-level functionality.
To see this structure in action, all you have to do is consider any modern software package — including LabVIEW itself. Much of the user experience we think of as “LabVIEW” is actually the result of cooperation between dozens of independent modules. There are modules that form the user interface, modules that implement the compiler and other modules that manage system resources like licenses, network connections and DAQ IO. Regardless of level at which the modularity occurs, the benefits are much the same — reduced development costs, improved maintainability, lower coupling and enhanced cohesion. In short, modularity is a Very Good Thing.
However, you may have noticed that this description (like so many others) concentrates on modularization as a part of the implementation process. Consequently, I want to introduce another idea about modules: The use of modularization during the design process. In particular, I want to provide you with a link to a paper by D.L. Parnas that was published the year I graduated high-school, that I first read in 1989, and that every software engineer should read at least once a year because it is as relevant today as it was 43 years ago. The paper bears the rather daunting title: On the Criteria To Be Used in Decomposing Systems into Modules.
As the title suggests, the point is to not make the case for modularization — even then it was assumed that modularity was the way to go. The question was how do you go about breaking up a system into modules so as to derive the greatest benefit. To this end, Dr Parnas takes a simple application and compares two different ways that it could be broken down into modules, comparing and contrasting the results.
In a section titled What is Modularization? Dr Parnas sets the context for the following discussion:
In this context “module” is considered to be a responsibility assignment rather than a subprogram. The modularizations include the design decisions which must be made before the work on independent modules can begin.
In other words, this discussion is primarily about designing, not implementing. Just as the first step in designing a database is generating a data model, so the first step in designing a program is to identify where the functional responsibilities lie. And just as the data model for a database doesn’t translate directly into table structures, so this design modularization will not always translate directly into code. However, when done properly this initial design work serves a far greater good than simply providing you with a blueprint of the code you need, it also teaches you how to think about the problem you are trying to solve.
It can be easy to get tied-up in the buzzwords of the work we do and think that they (the buzzwords) will protect us from creating bad code like talismans or magical words of power. But there is no magic to be found in words like “object-oriented”, “hierarchical structure” or “modular design”. As Parnas shows, it is possible to create very bad code that is modular, hierarchical and object oriented.
Until next time…