Preface

In der Beschränkung zeigt sich erst der Meister. (In simplicity one recognizes true skill.)

J.W. von Goethe

After 15 years of consulting about software quality, we at the Software Improvement Group (SIG) have learned a thing or two about maintainability.

First, insufficient maintainability is a real problem in the practice of software development. Low maintainability means that developers spend too much time on maintaining and fixing old code. That leaves less time available for the most rewarding part of software development: writing new code. Our experience, as well as the data we have collected, shows that maintaining source code takes at least twice as long when maintainability is measured as below average, compared to when maintainability is above average. See Appendix A to learn how we measure maintainability.

Second, lack of maintainability is to a large extent caused by simple issues that occur over and over again. Consequently, the most efficient and effective way to improve maintainability is to address these simple issues. Improving maintainability does not require magic or rocket science. A combination of relatively simple skills and knowledge, plus the discipline and environment to apply them, leads to the largest improvement in maintainability.

At SIG, we have seen systems that are essentially unmaintainable. In these systems, bugs are not fixed, and functionality is not changed or extended because it is considered too time-consuming and risky. Unfortunately, this is all too common in today’s IT industry, but it does not have to be like that.

That is why we have written the 10 guidelines. We want to share the knowledge and skills that any practicing software developer should master to consistently write maintainable source code. We are confident that after reading and understanding the 10 guidelines, as a software developer you will be able to write maintainable source code. What is left, then, is the environment to apply these skills to maximum effect, including shared development practices, appropriate tooling, and more. We cover these development environment essentials in a second book, called Building Software Teams.

The Topic of This Book: Ten Guidelines for Building Maintainable Software

The guidelines in the following chapters are independent of the type of system. The guidelines are about the size and number of parameters in units of code (methods in C#), the number of decision points, and other properties of source code. They are well-known guidelines that many programmers may have heard about in their training. The chapters also provide examples, mostly in the form of refactoring patterns, of how to apply the guidelines in practice. Although the guidelines are presented in C#, they are independent of the programming language used. Eight out of 10 of them are derived from the SIG/TÜViT1 Evaluation Criteria for Trusted Product Maintainability,2 a set of metrics to systematically rate source code maintainability.

Why You Should Read This Book

Taken in isolation, the guidelines presented in this book are well known. In fact, many commonly used tools for code analysis check a number of the guidelines presented here. For instance, Checkstyle (Java), StyleCop+ (for C#), Pylint (for Python), JSHint (for JavaScript), RuboCop (for Ruby), and PMD (covers multiple languages, including C# and Java) all check compliance with the guideline presented in Chapter 2. The following three characteristics, however, set this book apart from other books on software development:

We have selected the 10 most important guidelines from experience

Style guides and static code analysis tools can be daunting. Checkstyle version 6.9 contains some 150 rules, each of which implies a guideline. They all make sense, but their effect on maintainability is not equal. We have selected the 10 guideline chapters because they have the highest impact on maintainability. The box “Why These Ten Specific Guidelines?” explains how we have chosen our guidelines.

We teach how to comply with these 10 guidelines

Stating what a programmer should or should not do is one thing (and many style guides do just that). Providing guidance on how to comply with the guidelines is another. In this book, for each guideline we provide concrete examples of how to build code that complies with it.

We present statistics and examples from real-world systems

At SIG, we have seen a lot of source code made by real-world programmers under real-world constraints. That source code contains compromises. Therefore, we are sharing data from our benchmark to show how real-world source code compares with the guidelines.

Who Should Read This Book

This book is aimed at software developers who know how to program in C#. We distinguish between two groups of such developers. The first group comprises developers who received comprehensive training in computer science or software engineering (e.g., by majoring in one of those fields in college or university). For those developers, our book should reinforce basic principles that they have been taught in introductory programming courses.

The second group comprises software developers who entered the field without any comprehensive training in computer science or software engineering. We are thinking of developers who are self-taught, or who majored in a totally different field in college or university and then made a career switch. Our experience is that this group often received very little training beyond the syntax and semantics of the programming language they are using. This is the group for whom we have specifically written.

What This Book Is Not

This book uses C# (and only C#) to illustrate and explain our guidelines. Yet it does not teach C# in itself. We assume that the reader is at least able to read C# and the API of the standard libraries that come with it. We have tried to keep the code examples simple, using basic features of the language.

This is also not a book about C# idioms—that is, about C#-specific conventions on how to express functionality in code. We do not believe that you achieve maintainability by using specific language-dependent idiom. To the contrary, the guidelines presented here are to a very large extent language-independent, and therefore also independent of language idioms.

While we introduce and explain a number of refactoring patterns, what follows is not meant to be a comprehensive catalogue of such patterns. There are already books and websites out there that are very good pattern catalogues. Our book focuses on why and how a number of selected refactoring patterns contribute to maintainability. Therefore, this book serves as a stepping stone for such catalogues.

The Follow-up Book

We know that individual developers do not control all parts of the development process. Which development tools are used, how quality control is organized, how deployment pipelines are set up, and so on are all important factors that influence software quality but are also a team responsibility. Those topics are therefore outside the scope of this book. We do discuss them in a follow-up book, Building Software Teams. That book deals with discussing best practices in that field and how to measure their implementation.

About the Software Improvement Group

Although the front cover lists one name, the real author of this book is much more than just one person. The real author is SIG, a software management consulting company. That is, the book consolidates the collective experience and knowledge of the SIG consultants that have been measuring software quality and advising about it since 2000. We run a unique, certified,3 software analysis laboratory that performs standardized inspections against the ISO 25010 international standard for software product quality.

One of the services provided by SIG is our Software Risk Monitoring service. Our clients using this service upload their source code at regular intervals (usually once a week). These uploads are then automatically inspected in our software analysis laboratory. Anything out of the ordinary detected by this automatic analysis is then assessed by SIG consultants and discussed with the client. At the time of writing, in total SIG has analyzed 7.1 billion lines of code, and 72.7 million new lines of code are uploaded to SIG weekly.

SIG was established in 2000. Its roots can be traced back to the Dutch National Research Institute for Mathematics and Computer Science (Centrum voor Wiskunde en Informatica [CWI] in Dutch). Even after 15 years, we still keep and value our links with the academic software engineering research community. SIG consultants regularly contribute to scientific publications, and several PhD theses have been based on research to develop and improve the SIG quality model.

About This Edition

This is the C# edition of the book. All code examples are in C# (and in C# only), and the text frequently refers to tools and terms that are widely used in the C# community, but not necessarily outside of it. We assume that the reader has experience in C# programming. As previously noted, the guidelines, while presented in this edition in C#, are independent of the programming language used. A Java edition is published concurrently by O’Reilly.

Conventions Used in This Book

The following typographical conventions are used in this book:

Italic

Indicates new terms, URLs, email addresses, filenames, and file extensions.

Constant width

Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types, environment variables, statements, and keywords.

Tip

This element signifies a tip or suggestion.

Note

This element signifies a general note.

Warning

This element indicates a warning or caution.

Important

This element indicates an important remark.

Generic Names for Elements of Source Code

Although in the book we use C# to illustrate maintainability guidelines, these guidelines are not specific to C#. The guidelines are inspired by the SIG maintainability model, which is technology-independent and has been applied to about a hundred programming languages and related technologies (such as JSP).

Programming languages differ in the features they provide and (of course) their syntax. For example, where Java uses the keyword final for a constant, C# uses readonly for exactly the same thing. As another example, C# provides a feature called partial classes, which Java (currently) does not provide.

In addition to differences in syntax, programming languages also differ in the terminology they use in textbooks, tutorials, and their individual specifications. For instance, the concept of a group of code lines that can be executed as a whole is known in almost every programming language. In Java and C#, this concept is called a method. In Visual Basic, it is called a subroutine. In JavaScript and C, it is known as a function. In Pascal, it is known as a procedure.

That is why a technology-independent model needs generic names for grouping concepts. Table P-1 presents the generic names that we use throughout the chapters.

Table P-1. A generic grouping of concepts and their representation in C#.
Generic name Generic definition In C#

Unit

Smallest grouping of lines that can be executed independently

Method or constructor

Module

Smallest grouping of units

Top-level class, interface, or enum

Component

Top-level division of a system as defined by its software architecture

(Not defined by the language)

System

The entire codebase under study

(Not defined by the language)

The following list further clarifies the relationship between the grouping constructs described in Table P-1 and the practice of C# programming:

From smallest to largest

The grouping concepts in Table P-1 are ordered from smallest to largest. A unit itself consists of statements, but statements are not a grouping construct.

Note

In C#, as in many other programming languages, there is a complex relationship between statements and lines in the .cs file in which they appear. A line may have more than one statement, but a statement can be spread over multiple lines. We simply look at lines of code (LoC): any line in source code that ends with an Enter/Return, and neither is empty nor contains only a comment.

Some concepts are not defined in a particular language

As Table P-1 shows, some generic concepts are not represented in C#. For instance, in C# there is no syntax to describe the boundaries of a system. This concept is introduced in the generic terminology because we do need it. It is not a problem that C# lacks the syntax: in practice we have other ways to determine these boundaries.

Some well-known generic concepts play no role

You might be surprised that Table P-1 does not define well-known terms such as subcomponent and subsystem. The reason is simple: we do not need them for the guidelines.

Not all grouping constructs of a language are represented

C# has more grouping constructs than those listed in Table P-1. C# has namespaces to group classes and interfaces. C# also has nested classes. They are not listed in Table P-1 because we do not need them for the guidelines. For example, we do not need to distinguish between classes and nested classes to formulate our guidelines about coupling.

Note

A C# namespace is not the same as a component in the generic terminology. In very small C# systems, there may be a one-to-one mapping between components and namespaces. In larger C# systems, there are usually far more namespaces than components.

Build tooling plays no role in the generic terminology

In C# development, Visual Studio provides an additional grouping concept: build targets. However, build targets play no role in the guidelines. There may be a one-to-one relation between on the one hand components and on the other hand build targets, but this is not a rule.

Components are determined by the architecture of the system

A component is not a C# concept. Components are neither namespaces nor Visual Studio build targets or solutions. In a given system, there may be a one-to-one mapping between components and Visual Studio projects of solutions, but that is not a rule. Instead, components are the highest-level building blocks as identified by the software architecture of the system. They are the blocks in a “blocks-and-arrows” diagram of the system. Chapter 7 further explains the concept of components and presents some examples.

Using Code Examples

Supplemental material (code examples, exercises, etc.) is available for download at https://github.com/oreillymedia/building_maintainable_software.

This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing storage media (e.g., CD-ROM) of examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission.

We appreciate, but do not require, attribution. An attribution usually includes the title, authors, publisher, and ISBN. For example: “Building Maintainable Software, C# Edition by Joost Visser. Copyright 2016 Software Improvement Group B.V., 978-1-4919-5452-2.”

If you feel your use of code examples falls outside fair use or the permission given above, you may contact us at permissions@oreilly.com for special permission.

Safari® Books Online

Note

Safari Books Online is an on-demand digital library that delivers expert content in both book and video form from the world’s leading authors in technology and business.

Technology professionals, software developers, web designers, and business and creative professionals use Safari Books Online as their primary resource for research, problem solving, learning, and certification training.

Safari Books Online offers a range of plans and pricing for enterprise, government, education, and individuals.

Members have access to thousands of books, training videos, and prepublication manuscripts in one fully searchable database from publishers like O’Reilly Media, Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams, Que, Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kaufmann, IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-Hill, Jones & Bartlett, Course Technology, and hundreds more. For more information about Safari Books Online, please visit us online.

How to Contact Us

Please address comments and questions concerning this book to the publisher:

  • O’Reilly Media, Inc.
  • 1005 Gravenstein Highway North
  • Sebastopol, CA 95472
  • 800-998-9938 (in the United States or Canada)
  • 707-829-0515 (international or local)
  • 707-829-0104 (fax)

We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at http://bit.ly/building_maintainable_software_csharp.

To comment or ask technical questions about this book, send email to .

For more information about our books, courses, conferences, and news, see our website at http://www.oreilly.com.

Find us on Facebook: http://facebook.com/oreilly

Follow us on Twitter: http://twitter.com/oreillymedia

Watch us on YouTube: http://www.youtube.com/oreillymedia

Acknowledgments

We would like to thank the following people for writing this book:

  • Yiannis Kanellopoulos (SIG) as our project manager, overseeing everything.

  • Tobias Kuipers (SIG) as initiator of this project.

  • Lodewijk Bergmans (SIG) for helping to develop the book structure.

  • Zeeger Lubsen (SIG) for his thorough review.

  • Ed Louwers (SIG) for his help with the visuals in this book.

  • All SIG (former) employees that are working and have worked on perfecting models for measuring, benchmarking, and interpreting software quality.

From our publisher, O’Reilly:

  • Nan Barber as our text reviewer.

  • Jay Hilyard as our technical reviewer.

And Arie van Deursen for granting permission to use the JPacman code base.

1 TÜViT is part of TÜV, a worldwide organization of German origin for technical quality management. It specializes in certification and consulting for IT in general and security in particular.

2 See Maintainability Evaluation Criteria.

3 That is, ISO/IEC 17025 certified.

Get Building Maintainable Software, C# Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.