Vague Software Development Terms

Perplexing terms I wish I understood sooner

9/19/2022•5 min read
Pine trees during a snow storm

As a software engineer, I've come across several words or terms that I've either heard someone else say, read somewhere, or said myself that I didn't fully understand. It wasn't until almost a decade into my career that I started to question if I actually knew what some of the words actually meant. I realized that I didn't know what the words meant like I thought I did and I also found that many of my colleagues didn't know what they meant either even though they would actively use them.

The following are terms that I have found to be very vague and used in ways that can be unclear. The context of these words will be focused on their use in software development.

#1: Paradigm#

The term "Paradigm" sounds un-worldly like it's referring to some impossible objective regarding software development. When I first heard it used in relation to programming languages like C# and Java, I found the term to be vague and a little intimidating. I eventually came to realize that the term "Paradigm" simply refers to a style of programming.

Simply put, there are several styles (paradigms) of programming that have been created and refined over the years. The following are a few of the most popular:

  • Object-oriented
  • Functional
  • Event-driven
  • Procedural
  • Declarative
  • Imperative

Most programming languages support multiple paradigms (styles) and ultimately the paradigm ends up being more of a preference for the engineer of the application. I have found that most applications employ a mix of multiple paradigms that end up being used throughout the development cycle.

#2: Service#

When utilizing the object-oriented programming paradigm, we tend to prefer to tie operations we perform to some type of domain object. Sometimes those operations don't necessarily fit an object very well. To avoid forcing operations into an object class that doesn't really make sense, services usually end up being the answer.

The best definition that I have found for a service is a stateless operation that relates to a domain concept that is not a natural part of an entity. This definition is paraphrased from the best source on what a service is that I have found in "Domain-Driven Design" by Eric Evans.

Services can also sometimes be referred to as "Managers" or similar suffixes. They can be dressed up as domain objects without actually providing anything other than one or more operations. I find that a clear indication that operations in a file should be considered just a service is when there is no state being maintained by the file. This is a smell that tells me that we're dealing with operations that don't reflect actual objects in the domain. An example of this would be a "LoggingService".

#3: Unit#

When I was first introduced to Test-Driven Development (TDD) as a practice, the term "unit" perplexed me when used in the context of unit testing. I would question whether a unit was a method, a class, a behavior, or something else.

When I first learned about unit testing, I would be told that a class is a unit and we should be unit testing our classes. I started there, but as soon as I utilized some more advanced refactorings for smells I was seeing, the notion of a unit being one class would fall apart really quickly. I would then come to realize that a unit can be one class or multiple related classes.

This is a similar sentiment that Martin Fowler describes in his article called "UnitTest" where the definition of a unit is actually less important than what style of TDD you personally would subscribe to.

For example, a classical TDD style would focus on sociable tests that test a unit of behavior that might rely on other units to fulfill its behavior. A mockist TDD style, in contrast, uses solitary tests that isolate the tested unit.

I have not found that a unit can be easily defined and I am suspicious of anybody claiming to have a specific definition as to what a unit actually is. Ultimately, the term "unit" will be defined by the engineer actually writing the code and tests where they will take into consideration what behaviors they are looking to achieve, how those behaviors are related to each other, what style of TDD they prefer, and how fast the tests actually run.

Laptop showing computer code

#4: Declarative#

Declarative is a term that I have found to be used to describe code and I would always glance over the term or pass it by without really appreciating what it was telling me. I find that the easiest way of describing what "declarative" means is when you compare it to the term "imperative".

Imperative describes HOW code should work; not WHAT code should do. At a quick glance, imperative code is not easy at all to tell what is happening. You have to read each line by line to determine what is actually happening.

An example of imperative code is below:

int values[4] = { 8, 23, 2, 4 };

int sum = 0;
for (int i = 0; i < 4; ++i)
    sum += values[i];

int temp = values[0];
for (int i = 0; i < 3; ++i)
    values[i] = values[i + 1];

values[3] = temp;

Declarative describes WHAT code should do; not HOW code should work. Two ways of utilizing declarative code are to either add comments above imperative code or to extract imperative code into methods that describe the imperative code.

An example of the same code above written declaratively is below:

int values[4] = { 8, 23, 2, 4 };
int sum = SumArray(values);
RotateArrayIndices(values, -1);

I find that the best code is written declaratively as it makes reading the code easier to understand at a glance.