Fat Classes

SonarQube Rule Name

Classes should not be Fat.

SonarQube Rule Description

A class is Fat if it contains too many internal dependencies (default 120). These are the dependencies between the methods, fields and inner classes contained by the class.

A Fat class is a structural problem for a number of reasons:

To repair a Fat class you need to move some of its contained methods, fields and/or inner classes into (usually new) other classes. It is helpful to view both the internal dependency graph, and how the internal elements are used by client classes. Are there any “cohesive clusters” - groups of methods, fields and/or inner classes that are highly cohesive, but loosely coupled with the rest of the code in the Fat class? Are there any separately identifiable responsibilities? Do the external/incoming dependencies indicate multiple usage patterns?

Tip: “Spotlight” and expand the Fat class in Structure101 Workspace to see both its internal and external dependencies. For more advanced analysis, use the “Group tangles and cohesive clusters” in Structure101 Studio, and tag/filter the incoming dependencies. Once you have identified a set of elements for extraction, use the “extract delegate” refactoring in your IDE.

SonarQube Issue Message

Move some of the class contents to new classes.

 

Fat methods

SonarQube Rule Name

Methods should not be Fat.

SonarQube Rule Description

A method is Fat if it contains too many execution paths (default limit 15). This is also known as McCabe’s metric, or Cyclomatic Complexity (CC). This measure recognises that it is the complexity of control flow that makes a function hard to understand and maintain, rather than the number of sequential lines.

A Fat method is a structural problem for a number of reasons:

To repair a Fat method you need to extract some of its code into (usually new) other methods, which are given expressive names, and called from the original location of the extracted code. A Fat method will have a number of control blocks (if/else, for, while), often nested. The usual way to reduce complexity is to extract blocks of code until the number of paths is reduced below threshold.

Tip: Select a suitable block of code within the Fat method and use the “Extract Method” refactoring in your IDE. Repeat this until below threshold. Refresh the Structure101 Workspace “Structural Issues/Fat Methods” list to get changed value.

SonarQube Issue Message

Extract some blocks of code from this method into new methods.

 

Fat packages

SonarQube Rule Name

Packages should not be Fat

SonarQube Rule Description

A package is Fat if it contains too many internal dependencies (default 120). These are the dependencies between the classes and sub-packages contained by the package.

A Fat package is a structural problem for a number of reasons:

To repair a Fat package you need to move some of its contained classes and/or sub-packages into (usually new) other packages. It is helpful to view both the internal dependency graph, and how the internals are used by client code. Are there any “cohesive clusters” - groups of classes and/or sub-packages that are highly cohesive, but loosely coupled with the rest of the code in the Fat package? Are there any separately identifiable groups of classes/responsibilities that make for a cogent new package? Do the external/incoming dependencies indicate different usages? Is there a mix of sub-packages and classes under the Fat package - if so, you could push the classes down into new sub-packages.

Tip: “Spotlight” and expand the Fat package in Structure101 Workspace to see both its internal and external dependencies. For more advanced analysis, use the “Group tangles and cohesive clusters” in Structure101 Studio, and tag/filter dependencies. You can use the “tidy” command (Studio/Structure tab/context menu) to group any classes into sub-packages. Make sure you do not introduce cyclic package dependencies (tangles) as you break up the package. Once you have identified a set of classes/sub-packages for extraction, use the “move” refactoring in your IDE.

SonarQube Issue Message

Move some of the package contents to new packages.

 

Spec Dependency Violations

SonarQube Rule Name

Dependencies should comply with the Structure Spec.

SonarQube Rule Description

A Spec Dependency Violation breaks the layering and/or visibility rules expressed in the applicable Structure Spec.

A Structure Spec is an arrangement of modules and packages into groups and layers, that serves to:

To repair a Spec Dependency Violation, find the source of the violating dependency, and refactor the code so that the specified layering and/or visibility constraints are respected. Sometimes a change to the spec may be required.

Tip: Create and edit a Structure Spec using the “Overlays/Structure Spec” tab in Structure101 Studio. This lets you arrange existing and/or planned modules and packages into coloured groups to help understanding, adjust the layering to define allowable dependencies (dependencies should flow only downward), and to define modules and packages to be “private” to their parent scope. Use the Structure Map in Structure101 Workspace to see how local source code dependencies roll up through the spec, to drill down on the cause of violations, decide on suitable repair strategies, and navigate to the relevant code.

SonarQube Issue Message

Refactor so that dependencies comply with the Structure Spec.

Remove dependency on <…>

 

Spec Item Violations

SonarQube Rule Name

Items should not exist in a specified scope unless they are included in the Structure Spec for that scope.

SonarQube Rule Description

A Spec Item Violation occurs when a scope in a project is included in the Structure Spec, and an item exists in the actual code at that scope, but is not included in the Spec. The count of the number of classes contained by the violating container is used to measure the severity of the violation.

A Structure Spec usually grows from the top (or root) scope. So for example all the modules might be first specified to define groups of modules, the dependency layers, and visibility constraints. Then the internal package structure for one or modules may be added. Then sub-packages, etc. When a scope is added, it not only defines the dependencies, but also the items allowed at that scope. So if a new module is to be created, it needs to be added to the spec at the root level. Or if the sub-packages of package “a” have been included in the spec (e.g. a.x and a.y) and a new package (a.z) is created, then that new package is illegal until it is added to the spec.

Spec Item Violation checking serves 2 purposes:

To repair a Spec Item Violation, either add that items to the Structure Spec, or remove it from the code by moving its contents to other items that are in the spec.

Tip: Create and edit a Structure Spec using the “Overlays/Structure Spec” tab in Structure101 Studio. To add the new item to the spec, right-click “Add to spec”, and then move to the desired layer/group. To remove the violating item, use the Structure Map in Structure101 Workspace to discover the unspecified item, and navigate to the relevant code. Use the “move” refactoring in the IDE to move it to the desired specified container.

SonarQube Issue Message

Move the contents of this item into an item that is included in the Structure Spec.

This item contains <xx> classes.

 

Cyclic Package Dependencies

SonarQube Rule Name

Packages should not contain tangled sub-packages.

SonarQube Rule Description

A “tangle” is group of cyclically-dependent packages (and possibly classes) under the same parent. The parent is then considered tangled.

If the sub-packages and classes contained by a parent package are acyclically-dependent, then they can be arranged into layers so that all the dependencies flow downward. If some of the packages/classes are cyclically-dependent, then they cannot be levelized in this way. If they are arranged so that the minimum number of (weighted) dependencies flow upward, then these upward dependencies are called “feedback” dependencies. The weighted number of feedback dependencies (i.e. the number of code-level references that flow upward) is a good measure of the severity of the tangle.

Package tangles are a serious structural problem because:

To repair tangled sub-packages, look first at each end of the feedback dependencies, and observe the contingent dependencies (the dependencies in/on/from the dependent items). Look for misplaced sets of classes that can be moved to other packages so as to resolve the feedback dependencies. The feedback dependencies are a good guide, but don’t assume they are the “bad” dependencies - in some situations it makes sense to resolve tangles by focusing on non-feedback dependencies. If there are any Fat packages or classes involved in the cyclic dependencies, breaking up the Fat items may make it easier to resolve the tangles.

Tip: Always try to move classes (restructure) before changing code logic (refactor) since this is lower impact and risk - and the assignment of classes to packages may be accidental, and not worth a lot of effort to preserve. Using Structure101 Workspace, navigate to the tangled package. Expand each end of the feedback dependencies until the relevant classes and/or methods are exposed. Use the layering and specific dependencies to determine a resolution. Use the “move” refactoring in the IDE to move classes between packages. For more complex tangles that require many (sometimes dozens or hundreds) class moves to resolve, use the “Structure” tab in Structure101 Studio to simulate the moves and verify the result, before pushing the “action list” to Workspace for implementation.

SonarQube Issue Message

Move classes between sub-packages to remove the cyclic package dependencies.

There are <…> feedback dependencies in the tangle.

 

Architecture Diagram Violations

SonarQube Rule Name

Dependencies should comply with all enforced Architecture Diagrams.

SonarQube Rule Description

An Architecture Diagram Violation is a dependency that breaks the layering and/or visibility rules expressed in any Architecture Diagrams that have been tagged as “enforce”.

An Architecture Diagram is similar in some ways to a Structure Spec. Unlike a Structure Spec however, the structure of an Architecture Diagram is not locked to the actual structure of your project - the entities (“cells”) in the diagram map to classes in an arbitrary way (e.g. using pattern-matching). (Architecture Diagrams can be used to define actual structure too, but a Structure Spec is recommended for this).

Architecture Diagrams serve to:

To repair an Architecture Diagram Violation, find the source of the violating dependency, and refactor the code so that the specified layering and/or visibility constraints are respected. Sometimes a change to the Architecture Diagram may be required.

Tip: Create and edit Architecture Diagrams using the “Overlays/Architecture Diagrams” tab in Structure101 Studio. This lets you map classes to “cells”, and arrange the cells so that the layering defines allowable dependencies (dependencies should flow only downward), and to define cells to be “private” to their parent scope. Use the list of Architecture Diagram Violations in Structure101 Workspace to see any local source code dependencies that violate the Diagrams, and navigate to the relevant code.

SonarQube Issue Message

Refactor so that dependencies comply with Architecture Diagram(s).

Remove dependency on <…> which violates <diagram name>