Chapter 9. Standardize the Development Environment

To accomplish anything whatsoever one must have standards. None have yet accomplished anything without them.

Mozi

Best Practice:

  • Define and agree on standards in the development process.

  • Ensure that developers adhere to standards and that standards reflect the goals of the team.

  • This improves the development process because standards help enforce best practices and standards simplify both the development process and code.

This chapter deals with standardization in the development process. Standards make the results of development work more predictable. This predictability leads to a “hygienic development environment,” in which developers work in a consistent manner. By this standardization, we mean four things:

Standardized tooling and technologies

Agreeing on default tools and technologies, and not using a complex technology stack for solving a simple problem.

Process standards

Agreeing on steps that developers need to perform during development.

Standardized coding style

Defining a coding style (e.g., conventions for naming or indentation) and enforcing it.

Code quality control

Defining and continuously measuring code quality in terms of complexity, readability, and testability of code.

Arriving at standards that are the best fit for your development team or organization is not trivial: if you put three developers in a room, they will usually offer three different ways to solve a certain problem, all three according to best practice. The team should ultimately agree on what is “best.” Settling the issue is up to a quality champion, which typically is a team lead or (software) architect.

The following section explains the benefits of having these standards defined.

Motivation

Development standards make software more predictable, which eases maintenance. Standards also help in enforcing best practices, simplifying development and avoiding discussion overhead.

As a result, standards also ease comparison of metrics. Comparison allows for trend analysis and may be about comparing developers, teams, systems, or other factors. When the development process is consistent, there is less “noise” in observations that would otherwise make metrics hard to compare.

Development Standards Lead to Predictable Software Development

Standards lead to consistency and consistency is good for predictability. Therefore, agreeing on standards is a useful way to achieve predictable behavior and products (the software). The most important advantages for maintenance are:

  • It lowers the effort to understand how other developers have made decisions about design and implementation.

  • It makes it more likely that code and tests can be reused by others. Not by copying and pasting, of course!

Development Standards Help Enforce Best Practices

Standards should reflect best practices. With the exclusion of externally set standards (e.g., legal requirements), standards appear when a user community apparently prefers to do things a certain way. Therefore, standards reflect what commonly works well in practice.

Thus indirectly, standards help to enforce development best practices. For example, with consistent naming conventions, the relationships between different pieces of code (be it methods, classes, components) are clear. This helps dividing code into the right abstractions and allows, for example, for proper code encapsulation.1

A naming convention is a common type of standard. Identifiers that are very long or hard to understand are confusing for other developers, such as (a real example) AddPaymentOrderToPayOrderPaymentGroupTaskHelper. If those identifiers are named in a consistent manner, it serves as a system’s documentation of itself, because they show how functionality is organized technically.

This consistency is important. Standards are only effective when they are applied consistently. And tooling can help you with that (by facilitating or enforcing). A common example is to have a CI server automatically check code commits for certain characteristics (such as an issue identifier) and based on the result, allow or deny the commit.

Development Standards Simplify Both the Development Process and Code

Standardization decreases the number of specific decisions that developers need to make. Variations in implementations complicate maintenance, such as using different technologies to solve a similar problem. Using a single technology per domain ensures that developers can understand each other’s code, and learn from each other. This improves code reusability.

For large software development efforts it is common to have separate development teams working rather isolated from each other. Without standards, different teams may use a different development process and implement “custom solutions” that cannot be reused or they may duplicate functionality already present elsewhere.

Development Standards Decrease Discussion Overhead

Using standards limits discussion in development teams to the exceptions outside the standard. This is because with good standards, their context and application are understood. This eases understanding and communicating what is going on in source code. This also means that code is easier to transfer to new developers or other development teams.

How to Apply the Best Practice

Without standards, questions arise such as “What technology should I use?” or “How should I deal with version control?” With development process standards, these are defined and agreed upon. The following best practices are in place to obtain clear standards.

Standardize Tooling and Technologies—and Document It

Standardization of tooling and technologies should include a summary description of their context. Context information should list a few simple situations with their solution. That leaves less room for developers to misunderstand in which situation (and how) they should use which technology.

Agreeing on standards verbally may not be enough to have a lasting effect. Therefore, centralize documentation of these standards (e.g., in a wiki or document). This allows for access from different teams that may be physically separated.

A clear standard for tooling and technologies includes the following:

  • Prescribing a simple technology stack—for example, agreeing to use only one back-end programming language for implementing business logic.

  • Scoping of technologies and frameworks—for example, using multiple specialized tools instead of using all features of one framework whose features might not be mature yet. Typically, areas such as testing, security, and performance warrant specialized tooling. This tends to require some deliberation, especially given cost trade-offs (licensing/open source). See Chapter 10 for elaboration.

  • Default configurations of technologies or tooling (e.g., IDE, test suite, plug-ins). To achieve consistency, it is beneficial if default technologies and configurations are pushed over the internal network.

Chapter 11 elaborates on documentation efforts.

Considerations for Combinations of Technologies

Standards should be applicable and suitable to your organization and development team. The following are typical considerations for choosing combinations of programming languages and frameworks:

Assimilation

Is it likely that one of the technologies will evolve quickly with advanced capabilities? Such that it integrates (assimilates) qualities from the other technology?

Compatibility

How compatible are the different technologies? Do they require custom code to work together?

Time frame

Are the technology’s benefits really needed right now, or are you anticipating future demands?

Maturity

How long has the technology been around? How viable is usage of the technology?

Independence

Can different technologies be maintained independently or are they dependent on each other?

Specialized skills

Do the different technologies require essentially different technical skills? Is it likely that one developer can work with the complete stack or is specific training needed (or even different staff)?

Testability

Will the usage of different technologies significantly complicate testing?

Nonfunctionals

Are there foreseeable effects on non-functionals, such as performance or security, when using multiple technologies? This is likely to be the case when you foresee that testability is negatively influenced when using certain combinations.

Defining Process Standards

Process standards describe the steps that should be followed during the development process. Think of standards such as:

  • “Every commit should include an issue identifier.”

  • “Code should have a sufficient unit test coverage before it is committed.”

  • “Every implemented feature should be peer reviewed on code quality by a senior developer.”

These examples could be enforced with pre-commit hooks that perform a check on the code commit before pushing it to the CI server. Peer review could be enforced by requiring authorization from a developer other than the one doing the commit. The aim of the peer review should be to check for adherence with standards, understandability, and general feel of code quality (is the code well tested, simple enough, isolated, etc?).

Though these are only a few examples, any of the best practices in this book can be standardized. When they are actions that developers must perform, you could also put them in your Definition of Done (see Chapter 3).

Coding Style

Most IDEs already have default style checking features that give warnings or even errors when your code formatting is not compliant with the predefined style configuration in the IDE. It is a good idea to use such a style checker, if only to be consistent in your code formatting. Do make sure that your style guidelines are not being suppressed. You would rather have an overview of violations than assuming that all code is according to standards. Commonly we see CHECKSTYLE tags such as the following:

// CHECKSTYLE:OFF
piece of code that violates coding style standards
// CHECKSTYLE:ON

Here, the style checker is bypassed by enclosing the violating code in between suppressing tags. This is something you should definitely avoid! There are several ways to facilitate this technically. For instance, pre-commit hooks can be configured to check for these tags or to ignore suppress messages.

Another good way to standardize coding style is to adhere to conventions and defaults rather than specific configurations. So, instead of writing lengthy mapping tables to relate the objects in your data access layer to the corresponding database table, you assume the convention that an object like “Book” will be mapped to a “book” table by default. This principle is known as convention over configuration, because you typically adhere to the convention and only violate it when exceptions occur. In general that leads to less configuration and less code. Using the conventions of the technology you use also improves transferability of the software, for example when hiring new developers. Conventions can be understood by newcomers to the team even when they originate from a completely different environment. Tooling and technologies help you in adhering to conventions with default presets.

Code Quality Control

What makes high-quality code? With maintainability as a quality aspect, some basic measurements for quality are system size in lines of code, lines of code per unit, the amount of duplication, and complexity of decision paths within units.

There are numerous static code analysis tools available for determining and enforcing code quality. Most of them can measure a few simple metrics such as size, duplication, and complexity of code, but do require some level of configuration. Combined with an IDE that includes built-in style checks, developers will get quick feedback on their code, which speeds up code improvement. Usually, style checks are performed immediately while coding, and code quality control measurements are executed in the CI server. Quality control checks can also be checked before a release, but by adding preconditions on a build in the CI server, you can do quality checks automatically. You can even ensure that all code has passed quality control before it is built for integration testing. This is rather strict, but practice shows that this is the best way to obtain high-quality code because it cannot be ignored.

Important

Perform code quality checks before a build is performed. In the most strict form of control you can choose not to build when the code is not up to code quality standards.

Controlling Standards Using GQM

Suppose that you have agreed upon standards for tooling and technologies and that now you want to put those into practice. The IDEs that developers use support code style checks such as duplication, unit test coverage, and complexity of units/methods. You know why it is useful to measure those software characteristics. But if standards for complexity and test coverage are enforced (e.g., checked by the CI server before a commit triggers a new build), you may want to know whether the standards are in fact appropriate. Therefore, consider the following GQM model:

  • Goal A: To understand the effect of our development standards by monitoring adherence to those standards.

    • Question 1: Do developers adhere to process and coding standards?

      • Metric 1a: Number of process standard violations as a percentage of the number of commits. A violation here could be the omission of a peer review before committing code. You would expect this percentage to be low, such as 5%, but not 0%. If there are never any violations, then the standard may be too conservative. When there are many violations you will hear complaints soon enough, about the standards breaking the flow of work or being unreasonably strict. Both cases are worth investigating. The standard itself may be unfeasible, or the developers may lack certain skills necessary to comply with the standard.

      • Metric 1b: Number of coding style violations as a percentage of the number of commits. Expect a downward trend as developers learn the standard. If the standard is enforced by tooling, this can be near zero, because coding style can be corrected in real time.

      • Metric 1c: Number of code quality violations as a percentage of the number of commits. Expect this percentage to gradually decrease as the code quality increases.

The reason to normalize the number of code quality violations is that the number of violations alone may not be meaningful enough to the team: imagine a productivity peak in which the team produces much more code than usual. In that case the number of code quality violations will surely rise, even though the relative number of violations might decrease. We capture this in Figures 9-1 and 9-2. Although the absolute number of violations did not decrease dramatically, compared to the increasing number of commits we see that the relative number of violations decreases more quickly.

bmso 0901
Figure 9-1. Absolute number of violations versus the number of commits
bmso 0902
Figure 9-2. Normalized number of violations (as percentage of the number of commits)

In other words, it has become easier to adhere to code quality standards. This GQM model could be enforced automatically, if you wish to. In practice we see that this works mainly when the team understands and agrees with the standards. Clearly, standards should not be too lenient, otherwise they do not lead to improvement. There should be a middle way to achieve this. You can measure perceptions manually with the following GQM model:

  • Goal B: To understand the quality of our development standards by taking inventory of developers’ opinions of them.

    • Question 2: Do developers think that the standards are fair?

      • Metric 2: Opinion per developer about the fairness of the standards, on a scale (say, from 1 to 10). The outcome of this measurement should be discussed with the team. When developers have widely different opinions, this may be caused by difference in experience. When the measurement shows that everyone agrees that the standards are unreasonable, you should distinguish between the parts that are unreasonable and the parts that you can keep. Then you can focus on tackling the standards that are unfair.

    • Question 3: Do developers find it easy or hard to adhere to the standards?

      • Metric 3: Opinion per developer about the effort to adhere to standards, on a scale (say, from 1 to 10). Again, different opinions may reflect difference in experience. The important observations come from the trend line. Maybe some developers do not find it easier to adhere to standards over time. Then consider pairing up more experienced developers with less experienced ones, which is a good practice anyway. For instance, you could define in your process standards that the commits of junior developers with less than 2 years of experience should be peer reviewed by a developer with at least 5 years of development experience. Or you could organize regular plenary sessions in which the top violations are discussed in terms of their causes and solutions. Then, everyone can learn from each other and code quality will increase.

It is important to monitor your standards periodically (say, quarterly), because standards should change (however slightly) over time to reflect new gains in experience and technology.

Common Objections to Standardization

Typical objections to standardization are that certain standards do not apply. You may choose to accept certain violations, as long as they are not being covered up. Keep in mind that standards are a reflection of how the team should work or wants to work. That means that the objections of single developers will not always make sense toward team goals.

Objection: We Cannot Work Like This!

“Our code keeps violating our standards. We cannot work like this!”

We do not expect that standards are a perfect fit right away, or that they should forever be held on to. Developers should understand the reasoning behind and the need for standards and what they intend to achieve. Resistance to standards may invite developers to circumvent them in clever ways. Hiding or not knowing violations is a bigger problem than knowing where violations occur. This may mean going back to the goals of the standards and possibly loosening them. Be careful when doing so, because having certain standards may serve a particular purpose. For instance, the standards you introduce may be high, but they reflect a quality level you want to have in the future. Then you should be explicit about this fact and have the team agree that they do not have to do it right first, as long as they understand this is something the team should work toward.

Objection: Can You Standardize on Multiple Technologies?

“Can we standardize on multiple technologies, such as using two programming languages for frontend code?”

Try to stick with one technology stack that is consistent, ideally with a single programming language. Simplicity is an important determinant notably for maintainability and security. Complex relations between technologies require a lot of testing and are at risk of breaking. There may be good reasons to use multiple technologies, to benefit from the specialties and strengths of each technology. For common considerations, see “Considerations for Combinations of Technologies”.

Objection: Organization Unfit for Standardization

“Our organization/project is not fit for standardization. We cannot get it through.”

This is essentially a management issue. If formal standardization is not possible, an intermediate solution is to verbally agree on standards; for example, agreeing within your team to apply a standard within (part of) a system. If a “bad” standard applies consistently to a whole organization, it is generally better to adhere to it consistently than to ignore it with custom solutions. Deviating from an organization-wide standard tends to lead to problems in maintenance and failing interfaces, in addition to a lot of miscommunication and trouble with other departments.

Metrics Overview

As a recap, Table 9-1 shows an overview of the metrics discussed in this chapter, with their corresponding goals.

Table 9-1. Summary of metrics and goals in this chapter
Metric # in text Metric description Corresponding goal

ST 1a

Number of process standard violations

Adherence to standards

ST 1b

Number of coding style violations

Adherence to standards

ST 1c

Number of code quality violations

Adherence to standards

ST 2

Developer opinion about fairness of standards

Quality of standards

ST 3

Developer opinion about effort to adhere to standards

Quality of standards

In the next two chapters, we will further refine the hygiene of the development process by looking at two other kinds of standards: the usage of third-party code (Chapter 10) and documentation (Chapter 11).

1 Encapsulation here has a general meaning: being able to control access to a piece of code (e.g., an object) in order to isolate effects (e.g., for maintenance).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.191.134