Skip to content

Commit bc7f8f0

Browse files
committed
Merging changes synced from https://github.com/MicrosoftDocs/visualstudio-docs-pr (branch live)
2 parents 020d3c2 + b1f7e7d commit bc7f8f0

13 files changed

+142
-12
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
title: Code metrics - Class coupling
3+
ms.date: 1/8/2021
4+
description: Learn about the class coupling metric for code metrics in Visual Studio.
5+
ms.topic: conceptual
6+
author: mikejo5000
7+
ms.author: mikejo
8+
manager: jillfra
9+
ms.workload:
10+
- multiple
11+
---
12+
13+
# Code metrics - Class coupling
14+
15+
Class coupling also goes by the name Coupling Between Objects (CBO) as originally defined by [CK94](#ck94). Basically, class coupling is a measure of how many classes a single class uses. A high number is bad and a low number is usually good with this metric. Class coupling has been shown to be an accurate predictor of software failure and recent studies have shown that an upper-limit value of 9 is the most efficient [S2010](#s2010).
16+
17+
According to the Microsoft documentation, class coupling “measures the coupling to unique classes through parameters, local variables, return types, method calls, generic or template instantiations, base classes, interface implementations, fields defined on external types, and attribute decoration. Good software design dictates that types and methods should have high cohesion and low coupling. High coupling indicates a design that is difficult to reuse and maintain because of its many interdependencies on other types.”
18+
19+
The concepts of coupling and cohesion are clearly related. To keep this discussion on topic, we will not get into depth with cohesion other than to give a brief definition from [KKLS2000](#kkls2000):
20+
21+
“Module cohesion was introduced by Yourdon and Constantine as ‘how tightly bound or related the internal elements of a module are to one another’ [YC79](#yc79). A module has a strong cohesion if it represents exactly one task [], and all its elements contribute to this single task. They describe cohesion as an attribute of design, rather than code, and an attribute that can be used to predict reusability, maintainability, and changeability.”
22+
23+
## Class Coupling Example
24+
25+
Let’s look at class coupling in action. First, create a new console application and create a new class called Person with some properties in it then immediately calculate the code metrics:
26+
27+
![Class coupling example 1](media/class-coupling-example-1.png)
28+
29+
Notice the class coupling is 0 since this class doesn’t use any other classes. Now create another class called PersonStuff with a method that creates an instance of Person and sets the property values. Calculate the code metrics again:
30+
31+
![Class coupling example 2](media/class-coupling-example-2.png)
32+
33+
See how the class coupling value goes up? Also notice that, no matter how many properties you set, the class coupling value just goes up by 1 and not by some other value. Class coupling measures each class only once for this metric no matter how much it is used. In addition, can you see that `DoSomething()` has a 1 but the constructor, `PersonStuff()`, has a 0 for its value? Currently there is no code in the constructor that is using another class.
34+
35+
What if you put code in the constructor that used another class? Here is what you get:
36+
37+
![Class coupling example 3](media/class-coupling-example-3.png)
38+
39+
Now the constructor clearly has code that uses another class and the class coupling metric shows this fact. Again, you can see the overall class coupling for `PersonStuff()` is 1 and `DoSomething()` is also 1 to show that only one external class is being used no matter how much internal code you have that uses it.
40+
41+
Next, create another new class. Give this class some name and create some properties inside it:
42+
43+
![Class coupling example - add new class](media/class-coupling-example-add-new-class.png)
44+
45+
Now consume the class in our `DoSomething()` method within the `PersonStuff` class and calculate code metrics again:
46+
47+
![Class coupling example 4](media/class-coupling-example-4.png)
48+
49+
As you can see, the class coupling for the PersonStuff class goes up to 2 and, if you drill into the class, you can see that the `DoSomething()` method has the most coupling in it but the constructor still only consumes 1 class. Using these metrics, you can see the overall max number for a given class and drill down into the details on a per-member basis.
50+
51+
## The Magic Number
52+
53+
As with cyclomatic complexity, there is no limit that fits all organizations. However, [S2010](#s2010) does indicate that a limit of 9 is optimal:
54+
55+
“Therefore, we consider the threshold values [] as the most effective. These threshold values (for a single member) are CBO = 9[].” (emphasis added)
56+
57+
## Code Analysis
58+
59+
Code analysis includes a category of Maintainability rules. For more information, see [Maintainability rules](/dotnet/fundamentals/code-analysis/quality-rules/maintainability-warnings). When using legacy code analysis, the Extended Design Guideline rule set contains a maintainability area:
60+
61+
![Class coupling Extended Design Guideline rules](media/class-coupling-extended-design-guideline-rules.png)
62+
63+
Inside the maintainability area is a rule for class coupling:
64+
65+
![Class coupling rule](media/class-coupling-maintainability-area-rules.png)
66+
67+
This rule issues a warning when the class coupling is excessive. For more information, see [CA1506: Avoid excessive class coupling](/dotnet/fundamentals/code-analysis/quality-rules/ca1506).
68+
69+
For a description of this rule, see the archived Code Analysis blog post: [Code Metrics as Check-in Policy](/archive/blogs/codeanalysis/code-metrics-as-check-in-policy) and the threshold description *Warning at above 80 for class and above 30 for a method*. These values seem abnormally high, but at least provide an extreme upper limit. If you hit this warning, then something is almost certainly wrong.
70+
71+
## Citations
72+
73+
### CK94
74+
75+
Chidamber, S. R. & Kemerer, C. F. (1994). A Metrics Suite for Object Oriented Design (IEEE Transactions on Software Engineering, Vol. 20, No. 6). Retrieved May 14, 2011, from the University of Pittsburgh web site: [http://www.pitt.edu/~ckemerer/CK%20research%20papers/MetricForOOD_ChidamberKemerer94.pdf](http://www.pitt.edu/~ckemerer/CK%20research%20papers/MetricForOOD_ChidamberKemerer94.pdf)
76+
77+
### KKLS2000
78+
79+
Kabaili, H., Keller, R., Lustman, F., and Saint-Denis, G. (2000). Class Cohesion Revisited: An Empirical Study on Industrial Systems (Proceedings of the Workshop on Quantitative Approaches in Object-Oriented Software Engineering). Retrieved May 20, 2011, from Université de Montréal web site [http://www.iro.umontreal.ca/~sahraouh/qaoose/papers/Kabaili.pdf](http://www.iro.umontreal.ca/~sahraouh/qaoose/papers/Kabaili.pdf)
80+
81+
### SK2003
82+
83+
Subramanyam, R. & Krishnan, M. S. (2003). Empirical Analysis of CK Metrics for Object-Oriented Design Complexity: Implications for Software Defects (IEEE Transactions on Software Engineering, Vol. 29, No. 4). Retrieved May 14, 2011, from University of Massachusetts Dartmouth web site [http://moosehead.cis.umassd.edu/cis580/readings/OO_Design_Complexity_Metrics.pdf](http://moosehead.cis.umassd.edu/cis580/readings/OO_Design_Complexity_Metrics.pdf)
84+
85+
### S2010
86+
87+
Shatnawi, R. (2010). A Quantitative Investigation of the Acceptable Risk Levels of Object-Oriented Metrics in Open-Source Systems (IEEE Transactions on Software Engineering, Vol. 36, No. 2).
88+
89+
### YC79
90+
91+
Edward Yourdon and Larry L. Constantine. Structured Design. Prentice Hall, Englewood Cliffs, N.J., 1979.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
title: Code metrics - Maintainability index range and meaning
3+
ms.date: 1/8/2021
4+
description: Learn about the maintainability index range metric for code metrics in Visual Studio.
5+
ms.topic: conceptual
6+
author: mikejo5000
7+
ms.author: mikejo
8+
manager: jillfra
9+
ms.workload:
10+
- multiple
11+
---
12+
# Code metrics - Maintainability index range and meaning
13+
14+
Question: The maintainability index has been reset to lie between 0 and 100. How and why was this done?
15+
16+
The metric originally was calculated as follows: `Maintainability Index = 171 - 5.2 * ln(Halstead Volume) - 0.23 * (Cyclomatic Complexity) - 16.2 * ln(Lines of Code)`
17+
18+
The use of this formula meant that it ranged from 171 to an unbounded negative number. As code tended toward 0, it was clearly hard to maintain code and the difference between code at 0 and some negative value was not useful. As a result of the decreasing usefulness of the negative numbers and a desire to keep the metric as clear as possible, we decided to treat all 0 or less indexes as 0 and then rebase the 171 or less range to be from 0 to 100. For this reason, the formula we use is:
19+
20+
`Maintainability Index = MAX(0,(171 - 5.2 * ln(Halstead Volume) - 0.23 * (Cyclomatic Complexity) - 16.2 * ln(Lines of Code))*100 / 171)`
21+
22+
In addition to that, we decided to be conservative with the thresholds. The desire was that if the index showed red then we would be saying with a high degree of confidence that there was an issue with the code. This gave us the following thresholds:
23+
24+
For the thresholds, we decided to break down this 0-100 range 80-20 to keep the noise level low and we only flagged code that was suspicious. We've used the following thresholds:
25+
26+
- 0-9 = Red
27+
- 10-19 = Yellow
28+
- 20-100 = Green

docs/code-quality/code-metrics-values.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ For information about how to generate code metrics data in Visual Studio, see [H
3030

3131
The following list shows the code metrics results that Visual Studio calculates:
3232

33-
- **Maintainability Index** - Calculates an index value between 0 and 100 that represents the relative ease of maintaining the code. A high value means better maintainability. Color coded ratings can be used to quickly identify trouble spots in your code. A green rating is between 20 and 100 and indicates that the code has good maintainability. A yellow rating is between 10 and 19 and indicates that the code is moderately maintainable. A red rating is a rating between 0 and 9 and indicates low maintainability. For more information, see the [Maintainability index range and meaning](/archive/blogs/codeanalysis/maintainability-index-range-and-meaning) blog post.
33+
- **Maintainability Index** - Calculates an index value between 0 and 100 that represents the relative ease of maintaining the code. A high value means better maintainability. Color coded ratings can be used to quickly identify trouble spots in your code. A green rating is between 20 and 100 and indicates that the code has good maintainability. A yellow rating is between 10 and 19 and indicates that the code is moderately maintainable. A red rating is a rating between 0 and 9 and indicates low maintainability. For more information, see [Maintainability index range and meaning](code-metrics-maintainability-index-range-and-meaning.md).
3434

3535
- **Cyclomatic Complexity** - Measures the structural complexity of the code. It is created by calculating the number of different code paths in the flow of the program. A program that has complex control flow requires more tests to achieve good code coverage and is less maintainable. For more information, see the [Uncyclopedia entry for cyclomatic complexity](https://wikipedia.org/wiki/Cyclomatic_complexity).
3636

3737
- **Depth of Inheritance** - Indicates the number of different classes that inherit from one another, all the way back to the base class. Depth of Inheritance is similar to class coupling in that a change in a base class can affect any of its inherited classes. The higher this number, the deeper the inheritance and the higher the potential for base class modifications to result in a breaking change. For Depth of Inheritance, a low value is good and a high value is bad.
3838

39-
- **Class Coupling** - Measures the coupling to unique classes through parameters, local variables, return types, method calls, generic or template instantiations, base classes, interface implementations, fields defined on external types, and attribute decoration. Good software design dictates that types and methods should have high cohesion and low coupling. High coupling indicates a design that is difficult to reuse and maintain because of its many interdependencies on other types. For more information, see the [Class coupling](/archive/blogs/zainnab/code-metrics-class-coupling) blog post.
39+
- **Class Coupling** - Measures the coupling to unique classes through parameters, local variables, return types, method calls, generic or template instantiations, base classes, interface implementations, fields defined on external types, and attribute decoration. Good software design dictates that types and methods should have high cohesion and low coupling. High coupling indicates a design that is difficult to reuse and maintain because of its many interdependencies on other types. For more information, see [Class coupling](code-metrics-class-coupling.md).
4040

4141
::: moniker range=">=vs-2019"
4242

docs/code-quality/how-to-generate-code-metrics-data.md

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,10 @@ The .NET code-quality analyzers include several code metrics [analyzer](roslyn-a
3333
- [CA1505](/dotnet/fundamentals/code-analysis/quality-rules/ca1505)
3434
- [CA1506](/dotnet/fundamentals/code-analysis/quality-rules/ca1506)
3535

36-
These rules are disabled by default but you can enable them from [**Solution Explorer**](use-roslyn-analyzers.md#set-rule-severity-from-solution-explorer) or in a [rule set](using-rule-sets-to-group-code-analysis-rules.md) file. For example, to enable rule CA1502 as a warning, your .ruleset file would contain the following entry:
36+
These rules are disabled by default but you can enable them from [**Solution Explorer**](use-roslyn-analyzers.md#set-rule-severity-from-solution-explorer) or in an [EditorConfig](use-roslyn-analyzers.md#set-rule-severity-in-an-editorconfig-file) file. For example, to enable rule CA1502 as a warning, your EditorConfig file would contain the following entry:
3737

38-
```xml
39-
<?xml version="1.0" encoding="utf-8"?>
40-
<RuleSet Name="Rules" Description="Rules" ToolsVersion="16.0">
41-
<Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
42-
<Rule Id="CA1502" Action="Warning" />
43-
</Rules>
44-
</RuleSet>
38+
```cs
39+
dotnet_diagnostic.CA1502.severity = warning
4540
```
4641

4742
### Configuration
Loading
Loading
Loading
Loading
Loading
Loading
Loading

docs/code-quality/toc.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,11 +453,17 @@
453453
href: how-to-generate-code-metrics-data.md
454454
- name: Work with code metrics data
455455
href: working-with-code-metrics-data.md
456+
- name: Resources
457+
items:
458+
- name: Maintainability index range and meaning
459+
href: code-metrics-maintainability-index-range-and-meaning.md
460+
- name: Class coupling
461+
href: code-metrics-class-coupling.md
456462
- name: C++ code analysis
457463
items:
458464
- name: Analyze C and C++ code
459465
href: /cpp/code-quality/code-analysis-for-c-cpp-overview
460466
- name: EditorConfig formatting conventions
461467
href: ../ide/cpp-editorconfig-properties.md
462468
- name: C++ code analysis warnings
463-
href: /cpp/code-quality/code-analysis-for-c-cpp-warnings
469+
href: /cpp/code-quality/code-analysis-for-c-cpp-warnings

docs/deployment/installchecks-element-bootstrapper.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,20 @@ The `InstallChecks` element supports starting a variety of tests against the loc
171171
For example, to block installation on a computer running Windows 95, use code such as the following:
172172

173173
```xml
174-
<!-- Block install on Windows 95 -->
174+
<!-- Block install on Windows 95 -->
175175
<FailIf Property="Version9X" Compare="VersionLessThan" Value="4.10" String="InvalidPlatform"/>
176176
```
177177

178+
To skip running install checks if a FailIf or BypassIf condition is met, use the BeforeInstallChecks attribute. For example:
179+
180+
```xml
181+
<!-- Block install and do not evaluate install checks if user does not have admin privileges -->
182+
<FailIf Property="AdminUser" Compare="ValueEqualTo" Value="false" String="AdminRequired" BeforeInstallChecks="true"/>
183+
```
184+
185+
>[!NOTE]
186+
>The `BeforeInstallChecks` attribute is supported starting with the Visual Studio 2019 Update 9 release.
187+
178188
## See also
179189
- [\<Commands> element](../deployment/commands-element-bootstrapper.md)
180190
- [Product and package schema reference](../deployment/product-and-package-schema-reference.md)

0 commit comments

Comments
 (0)