Data Model: Aren’t Global Variables Bad?

The Data Model architecture pattern consists of all the model point instances in the application, and it is the canonical authority for the data. The model point instances – when statically allocated – are from the compiler’s perspective global variables. So if model point instances are global variables, and global variables are bad – doesn’t that make the Data Model a bad pattern?

Note: This article assumes that the reader is already familiar with the Data Model architecture pattern. It is recommended that you read (if you have already): Data Model: Introduction to the Data Model Architecture before proceeding.

Why are global variables bad?

I have always been told that global variables are bad, but to be honest I couldn’t articulate why they are bad. So after some Google searching, here is my list (in no particular order) of why global variables are a bad practice.

  • Non-CONST global variables are dangerous because their values can be changed at any time and there is no easy way for the developer to know when, how, or if this will happen.
  • Global variables are not inherently thread safe.
  • Clients have to spend time searching for all the places a global variable is referenced.
  • Global variables can bring in hidden dependencies and make testing code in any predictable fashion extremely difficult.
  • No module that depends upon a global variable can be closed against any other module that might write to that variable.
  • Global variables pollute the standard namespace.

Not Really Global Variables

Model points, are technically global variables, but I claim that they have sufficiently different semantics to exempt them from the don’t-use-global-variables best practice. In some ways, it’s similar to why if-else or switch constructs are okay to use even though they are technically just gussied up goto statements (and everyone knows goto statements are bad). The reason if-else and switch constructs are okay to use is that they provide syntactic cues that bound the goto actions. The same is true with model points: it may be “global data,” but there are syntactic cues that their usage semantics are not that of traditional global variables.

Usage Semantics

This list below enumerates the model point syntactic cues and usage semantics that differentiate them traditional C/C++ global variables.

  • The semantics of a model point instance is that it can be changed at any time, and there is never an assumption that its value has not been changed by some external entity.
  • Model point types are required to be thread safe.
  • While a developer may spend time searching for where a particular model point is used, this activity is done to understand how the application works. However, knowing every place a model point is used is not required (and arguable not desired) to construct a module that will consume the model point instance.
  • Model points only have a dependency on the data model framework, nothing more. That is, there are no hidden dependencies.
  • Using model points makes testing easier because the individual tests can control exactly when, and what, values are written to the model points.
  • There are advantages to using hard-coded model points in modules; it greatly simplifies creating classes and modules because you don’t have to propagate a bunch of model point references through initialization or constructor calls. Also, when using hard-coded model point names in modules that are application or project specific, there is little downside because these modules only need to be closed within the context of the application. And they are.
  • For non-application-specific modules (e.g., a temperature driver), using hard-coded model point names is a bad thing. You should instead pass the necessary model point reference into the initialization or constructor call.
  • The namespace issue can be resolved either by putting the model instances into their own namespace or by using a naming convention for model point names that avoids namespace collisions.

Summary

While model point instances quack like a duck (i.e. technically global variables), model points are sufficiently different as to not be a duck. Or said another, model point instances do not ‘fall under’ or ‘violate’ the don’t-use-global-variables best practice.