Clean Code for Embedded Systems

Clean Code is important, clean well crafted code is easy to read, easy to maintain and easy to reuse. Clean Code is important, code that is not clean slows down development, it becomes hard to read, difficult to understand and at times becomes so bad that it is just plain dangerous to change. Code that is not clean sucks the life out of development teams, it kills productivity and at its worst has killed companies.

The term Clean Code originates from Robert C Martins book, Clean Code - A Handbook of Agile Software Craftsmanship, it and other books from the software craftsmanship movement go in to great detail on what Clean Code looks like and how to write it. However the book and most of the Clean Code material does not consider the special requirements of embedded systems.

This training course helps you to build knowledge and understanding of all aspects of Clean Code as adapted to embedded systems development in C or C++. You will learn what clean code looks like in fine detail. You will learn how to write clean code (by refactoring).

Course Structure

Four two hour training sessions, each looking at three aspects of clean code.

One half day hands on training exercise in refactoring

Training can be delivered remotely or on site

Audience

  • Embedded Software Developers
  • Software Developers
  • Technical team leaders
  • Managers that want to know more about the technology they manage

Course Outline

The first three modules are about code style, those aspects of the software that have no impact on the compiled code, only on readability. Then we have an interactive hands on session where we look in detail at Refactoring and the process of writing clean code. The remaining nine sessions look at aspects of clean code that impact the compiled code as well as the readability. These later sections are more specific to embedded systems.

Clean Code and Software Craftsmanship for Embedded Systems

Module objective: Software developers write code that works, all too often we stop once code works and is performant enough for the job in hand. Failure to take the extra step of ensuring that the code is clean, readable and maintainable causes code to rot. As code rots it becomes slower and slower to add value leading to huge costs further down the line. In this section we explore:

  • The Origins of Clean Code
  • The need for Clean Code
  • What is good code and what is bad code
  • The cost of bad code
  • Responsibility
  • Overview of clean code topics

Comments

Module Objective: Commented code is good - or is it? In many old code bases there was a requirement to comment every function, every parameter, every file... did that actually lead to better more maintainable code?

  • Explain yourself in code
  • Legal comments
  • Informative comments
  • Explaining intent
  • Commenting standards and tools
  • Comments as noise
  • Comments as a code smell
  • Comments and LeBlanc's law
  • Commented out code

Meaningful Names

Module Objective: Consider carefully what makes a good name for an identifier. Look at examples to understand the impact that good names have. Determine some guidelines that help with generating meaningful names. Specifically we consider:

  • Intention revealing names
  • Avoiding Disinformation
  • Distinctions
  • Pronounceability
  • Hungarian Notation
  • Naming classes
  • Naming Functions & Methods
  • Consistency
  • Vocabulary
  • Context

"You should name a variable using the same care with which you name a first-born child.”― Robert C Martin – Clean Code

Formatting

Module Objective: Understand the importance of formatting code. Look at numerous examples of different styles of formatting. Consider what formatting rules the team believe are most readable. Consider tools to assist with formatting. Specifically we consider:

  • Team rules
  • Vertical formatting
  • Horizontal formatting
  • Line length
  • Openness and density
  • Alignment
  • Indentation and parenthesis
  • Dummy Scopes
  • Naming Style

Refactoring

Module Objective: Understand what refactoring is (its not rewriting), different types of refactoring and why refactoring is critical to maintaining a clean code base.

  • What is refactoring
  • Types of refactoring
  • Why do we need to refactor
  • Sample refactoring steps
  • Demonstration of refactoring
  • Exercise
  • Debrief

During the debrief we discuss how the team found the refactoring. The benefits of separating refactoring from adding new functionality. The impact of having full test coverage when refactoring.

Functions

Module Objective: Functions or methods are the core building blocks of software. This module looks at many aspects of function design that impact their readability and maintainability.

  • Function Size
  • Do one thing/One level of Abstraction
  • Naming
  • Arguments
  • Side Effects
  • Command or Query

Having looked at these aspects we reconsider how to actually write clean functions.

Objects and Data Structures

Module Objective: Objects hide their data behind abstraction, whereas data structures expose their data. This module looks in depth at the differences between the two, looks at what makes a good object and when to choose to use objects and when to use data structures.

NOTE: For C programmers this applies to you too!

  • Data Abstraction
  • Data Object Anti-symmetry
  • The law of Demeter
  • Data Transfer Objects (DTO)
  • Organization considerations

Classes

Module Objective: Consider what differentiates a clean class from one that isn't. What design principles can help with producing a clean class?

  • Object oriented guidance and C
  • Class organization
  • Size
  • SOLID principles
  • YAGNI

Error Handling

Module Objective: Error handling is an essential part of software design. The book clean code is clear that using exceptions is the clean way of handling errors and this module covers this. However in embedded systems we are often prevented from using exceptions for many reasons, this module covers clean code approaches when exceptions cannot be used.

  • Exceptions vs Error Codes
  • Write try-catch first
  • Unchecked exceptions
  • Context
  • Scope
  • Special Case Pattern
  • NULL
  • Clean Error codes

The module concludes with a discussion on the merits of the various approaches within the teams code base.

Boundaries

Module Objective: Boundaries in software are key to being able to make changes easily. This module considers multiple types of boundaries and considers clean strategies to decouple software across boundaries. As well as architectural boundaries source code organization into appropriate components allows us to design for changes in processor, board revisions, operating systems and tool vendors

  • Third party software
    • Learning tests
  • Non existent code
  • Architectural layers
    • Clean Architecture
  • Source code organization
  • Vendor branches

Unit Tests

Module Objective: Unit testing is essential to ensure the multiple units that make up our software all work independently as the developer intended. But how do we generate unit tests? What needs to be tested? How do we write good clean maintainable tests? In this module we consider:

  • Test driven development
  • What makes a clean test
  • Domain specific languages in tests
  • Dual standards for production code and tests
  • Tests should do one thing - but what is one thing?
  • FIRST

We recommend Test Driven development training from Wingman Software

Systems

Module Objective: This module considers strategies for system issues such as startup/shutdown, scaling and architecture. The objective is to uncover strategies for separating these concerns from the operation of the components of our system. Specifically we consider

  • Separate construction from use
  • Separate construction from initialization
  • Scaling up
  • Test driving architecture
  • Decide as late as possible

Emergence

Module Objective: What if there were four rules that if followed ensured that clean code was produced? What if there were four simple rules, would you follow them? This module takes the form of a discussion around four such rules.

Concurrency

Module Objective: In embedded systems concurrency is a given. In this module we look at strategies for maintaining clean concurrent code. The specific topics covered are:

  • Abstract the operating system
  • Separate Tasks and Runnables
  • Mutex
  • Interrupts
  • Design in shutdown
  • Defense principles
  • Maintain a temporal design
  • Know your tools/Monitor your system
  • Testing multi threaded code