The opinions expressed in these materials are my own and are not necessarily those of Microsoft.
Copyright © Microsoft Corporation. All rights reserved. Unless otherwise indicated, all source code provided is licensed under the Microsoft Public License (Ms-PL).
SKU: Premium, Ultimate
Versions: 2008, 2010
As we continue looking at code metrics in Visual Studio (see vstipTool0129, “Calculating Metrics”), it’s time to look at class coupling. Class coupling also goes by the name Coupling Between Objects (CBO) as originally defined by [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 generally 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].
According to the MSDN documentation, class coupling “[m]easures 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.”
The concepts of coupling and cohesion are clearly related. To keep this discussion on topic, I will not get into depth with cohesion other than to give a brief definition from [KKLS2000]:
“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]. 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.”
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:
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:
See how the class coupling value goes up? Also notice that, no matter how many properties we 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.
What if we put code in the constructor that used another class? Here is what you get:
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 we have that uses it.
Next, let’s create another new class. I’ll call my class Blah and create some properties inside it:
Now consume the class in our DoSomething() method within the PersonStuff class and calculate code metrics again:
As you can see, the class coupling for the PersonStuff class goes up to 2 and, if we drill into the class, we can see that the DoSomething() method has the most coupling in it but the constructor still only consumes 1 class. Using these metrics we can see the overall max number for a given class and drill down into the details on a per-member basis.
As I mentioned with cyclomatic complexity (see vstipTool0131, “Code Metrics - Cyclomatic Complexity”), there is no limit that fits all organizations. However, [S2010] does indicate that a limit of 9 is optimal:
“Therefore, we consider the threshold values […] as the most effective. These threshold values [for a single member] are CBO = 9[…].” (emphasis added)
When using code analysis, the Extended Design Guideline rule set contains a maintainability area:
Inside the maintainability area is a rule for class coupling:
This rule issues a warning when the class coupling is excessive. You can learn more about the rule here:
Unfortunately, the documentation doesn’t talk about the thresholds set for this rule but I did find a description on the Code Analysis Team Blog (http://blogs.msdn.com/b/codeanalysis/archive/2007/11/15/code-metrics-as-check-in-policy.aspx): “Warning at above 80 for class and above 30 for a method”. These seem abnormally high but at least provide an extreme upper limit. If you hit this warning then something is almost certainly wrong.
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
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
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
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).
Edward Yourdon and Larry L. Constantine. Structured Design. Prentice Hall, Englewood Cliffs, N.J., 1979.
Windows: ALT + W, N (new window); ALT + W, V (new vertical tab group)
Menu: Window | New Window; Window | New Vertical Tab Group
Command: Window.NewWindow; Window.NewVerticalTabGroup
Versions: 2005, 2008, 2010
For quite some time you have been able to split your code windows horizontally (see http://blogs.msdn.com/b/zainnab/archive/2010/03/05/split-your-windows-vstipenv0004.aspx) but did you know there is a technique you can use to split your code windows vertically?
These techniques do not work on .ASPX files see http://blogs.msdn.com/b/zainnab/archive/2010/12/05/vertical-split-view-vstipedit0081.aspx
Also, these techniques will not work for .XAML files. To split them vertically click the Vertical Split button in the designer:
First, locate the tab for the file you want to split vertically:
Next, make a copy of the window by going to Window | New Window on your Menu Bar:
Finally, go to Window | New Vertical Tab Group to split the copies:
Now you have the code window split vertically in the IDE. Of course you could always rip one of the copies outside the IDE and vertically arrange them as well (http://blogs.msdn.com/b/zainnab/archive/2010/01/15/free-your-document-windows.aspx).
Keyboard: F5; CTRL + F5Menu: Debug -> Start Debugging; Debug -> Start Without DebuggingCommand: Debug.Start; Debug.StartWithoutDebuggingVersions: 2008,2010Published: 11/1/2010Code: vstipDebug0037
While researching this one I came across a LOT of misinformation concerning what is actually happening here. There seems to be a great deal of confusion as to what is actually happening when you use Start Debugging (F5) versus Start Without Debugging (CTRL + F5):
Starting With Debugging
Let's start with the basics: When you press F5 (Start Debugging) in Visual Studio it launches your application, attaches the Debugger, and let's you do all the "normal" things you would expect:
According to the documentation (http://msdn.microsoft.com/en-us/library/k0k771bt(v=VS.100).aspx) here is what the Debugger does:
"The Visual Studio debugger is a powerful tool that allows you to observe the run-time behavior of your program and locate logic errors. The debugger works with all Visual Studio programming languages and their associated libraries. With the debugger, you can break, or suspend, execution of your program to examine your code, evaluate and edit variables in your program, view registers, see the instructions created from your source code, and view the memory space used by your application."
The Debugger: Release Builds
One popular misconception is the Debugger doesn't come into play for Release builds. This isn't true. Set a Breakpoint in some code for a Release build and then press F5 to see if is stops there:
Of course it does! The Debugger is attached! That is what is happening. Now, there are some things that aren't happening as well. For example, you can't use the System.Diagnostics.Debug class methods to send messages to the Output window since the compiler strips them out for Release builds:
Start Without Debugging
This is exactly what it sounds like. It starts the application WITHOUT THE DEBUGGER ATTACHED. That's it! Nothing else. It just doesn't attach the Debugger. Otherwise everything else is the same. So, the practical implications of this are obvious: Without the Debugger attached when the application runs it will not hit Breakpoints, emit Debug messages, etc. So now let's deal with the biggest myth about Start Without Debugging.
Myth: Start Without Debugging Creates a Release Build
Nope. It uses the build you are currently on. So if you are using a Debug build and you press CTRL + F5 then it will run that Debug build. The easiest way to test this is to use conditional compilation to see if you are using a Debug build:
In this example, the Console statement will run but the Debug statement will NOT run because the Debugger is not attached. So I will get this output:
And, if I attach the debugger after pressing CTRL + F5, to this process:
Then this is what I get:
The Debug messages haven't been stripped out because I'm using a Debug build of the application.
Okay, so the obvious question is "Why?". I mean, why would they give us this option? Well the most obvious answer is so we can run the application without having to hassle with disabling breakpoints, etc. to do a quick "Smoke Test" and see if it runs. There may be other reasons you have for wanting to run without the Debugger attached as well. So now you have a better idea of the difference between Start With and Start Without Debugging. Go forth and debug away!
Keyboard: CTRL + G Menu: Edit -> Go ToCommand: Edit.GoToVersions: 2008,2010Published: 3/8/2010Code: vstipEdit0026
You can go to any line number in your code by simply pressing CTRL + G. You will get this dialog:
Just type in your desired line number and click OK. The Cursor will move to the line number you typed.
Menu: Project -> Add New Solution Folder; [Right-Click Solution] -> Add -> New Solution Folder Command: Project.AddNewSolutionFolderVersions: 2008,2010Published: 3/27/2010 Code: vstipProj0009
Did you know there are special folders to help you organize large solutions? There is! They are called, appropriately enough, Solution Folders. To create one just Right-Click on your solution (or go to Project -> Add New Solution Folder) and you will see this in Solution Explorer:
Simply give the folder a name and you are good to go. But so what? I mean, what can you actually DO with these things? Here is a list of stuff you can do:
Move or add projects to them. Solution Folders can be nested to create greater organizational structure.
Add, delete, or rename Solution Folders at any time, if the organizational requirements of the solution change.
Unload all projects in a Solution Folder to make them temporarily unavailable for building.
Collapse or hide entire Solution Folders so that you can work more easily in Solution Explorer. Hidden projects are built when you build the solution.
Build or rebuild all the projects. The projects are built in the order specified by the project dependencies.
Solution Folders are an organizational tool in Solution Explorer; corresponding Windows folders are not created. Microsoft recommends that you organize your projects on disk in the same way that you organize them in the solution. But that is your call :)
I LOVE statistics and was recently asked about calculating the mean, median, and mode using SQL Server. I found this great article by George Mastros that shows you how:
There is an update to Visual Studio 11 that came out in early April that is available. You can find the details here:
If you haven’t been playing with Visual Studio 11 yet, I strongly encourage you to get it today. You can download it from here:
When you DO have it one of the first things you should do is turn on automatic checking for updates to extensions found at Tools | Options | Environment | Extension Manager:
Not only will this make sure you are notified about the latest and greatest version of your favorite extensions but it will also enable notification of updates to Visual Studio! We are now pushing updates to the IDE as extension-like elements. When you enable this feature, every time you start Visual Studio you will see a message whenever there is an update to Visual Studio that looks like this:
You can click on the bubble or, to get to updates manually, go to Tools | Options | Extension Manager | Updates | Product Updates:
You will see the update(s) available and can then click on the Update button for the items you want. In this case, when I clicked on update for the April 2012 fix for VS11, I received the download dialog:
Selecting Run began the installation process:
It finished smoothly and Visual Studio was updated easily.
Go out there and update your version of Visual Studio 11 if you haven’t done it already so you can get the most up-to-date goodies!
Keyboard: CTRL + M, CTRL + M Menu: Edit -> Outlining -> Toggle Outlining Expansion Command: Edit.ToggleOutliningExpansion Versions: 2008,2010Published: 3/15/2010Code: vstipEdit0029
By default, Outlining is enabled in Visual Studio. It's the line you see with the boxes to indicate the status of the area (collapsed or expanded):
You can collapse areas of code to get them out of your way so you can focus on other areas. There are four ways to do it:
Once collapsed, the code area will look like this:
In my travels across the country, with my fellow Evangelist, Clint Edmonson, talking about Visual Studio we often come across great stories to tell. One of our favorite true stories is of a customer that had a web application running very slow. We ran code metrics against it and, sure enough, the Page_Load event had 9,000 lines of code in it.
Naturally we were curious so we opened it up to see that it was basically the same if statement copied over and over. Apparently they needed to find out who was coming into the website in order to show customized content and the solution they came up with was this massive set of statements.
For better or worse we have all had code that gets copied throughout our solutions. Until now there was no tool to tell us there were copies and, instead, we had to rely on other metrics to hopefully reveal any code smells that lead us to duplicates. Now, however, we have the new Code Clone Detection (aka Code Clone Analysis) feature.
According to the documentation:
“Code clones are separate fragments of code that are very similar. They are a common phenomenon in an application that has been under development for some time. Clones make it hard to change your application because you have to find and update more than one fragment. Visual Studio can help you find code clones so that you can refactor them.”
You can find clones of specific code by selecting the segment you are interested then right click on the selection to choose Find Matching Clones in Solution from the context menu:
Visual Studio will search for code clones and produce the result in the new Code Clone Search Results window:
The original line of code is put in a group on its own and then all the matches are put into a different group. You can expand the groups to see the specific locations of the matches:
Also, you can double click on any entry in the list to go to the selection in your code file:
Besides looking for specific clones you can also look for code clones for the entire solution. To use this feature go to Analyze | Analyze Solution for Code Clones:
This creates a result set for the entire solution:
By default it groups and sorts the results by the strength of the match. Exact matches come first then those matches that may be close but not exact come next and so on. The terms you may see are Exact, Strong, Medium, and Weak.
Once you have the result set, there are a couple of ways you can compare them against each other.
If you have a comparison tool configured you can Right-click on any item and select Compare from the shortcut menu:
You would know if you have this feature available by going to Tools | Options | Source Control | Team Foundation Server and click on Configure User Tools.
If you don’t have a comparison tool you can do manual comparisons between two entries in the list. If the clones are in different files then you can just double-click each entry and it will open the file as well as highlight the entry that is duplicated as mentioned earlier.
You are probably curious as to what is found by this tool. The heuristics for finding clones will find duplicates even if the following changes have happened:
· Renamed identifiers
· Insert and delete statements added
· Rearranged statements
There are some rules for what is not found as well. I have taken this list from the documentation pretty much verbatim.
· Type declarations are not compared. For example, if you have two classes with very similar sets of field declarations, they will not be reported as clones. Only statements in methods and property definitions are compared.
· Analyze Solution for Code Clones will not find clones that are less than 10 statements long. However, you can apply Find matching clones in solution to shorter fragments.
· Fragments with more than 40% changed tokens.
· If a project contains a .codeclonesettings file, code elements that are defined in that project will not be searched if they are named in the Exclusions section of the .codeclonesettings file.
· Some kinds of generated code are excluded:
· *.designer.cs, *.designer.vb
· InitializeComponent methods
A settings file is available to configure this feature at the project level. Currently we have only announced the ability to do exclusions in the file but there will most likely be other elements that are added later on. The file is just XML with a .CODECLONESETTINGS extension. The only requirement for use is that the file exists in the top level directory of the project.
The base elements consist of a CodeCloneSettings element with an Exclusions child:
Within the Exclusions element you can have the following children:
This element is used to indicate files that should be excluded from analysis. Path names can be absolute or relative and you can use wildcards as well. So, for example, to ignore all the C# text template files that have been put in their own directory (called MyTextTemplates) you might have the following:
You can also exclude namespaces, types, and functions. Just like files these items can use absolute names or names with wildcards in them. Here is an example of what it might look like:
In the Tailspin Toys sample there is some generated code in the TailSpin.SimpleSqlRepository project that is the bulk of the duplications:
When I run code analysis, this is the result:
Code clone analysis doesn’t automatically know to ignore text templates so I would create an XML file called TailSpinRepository.codeclonesettings and insert an entry like this:
Now if I run clone analysis again here is what I get:
As you can see the results are significantly less than the first time the analysis ran. It’s common to create several exclusions in different projects to weed out noise in the analysis results.
Code Clone Detection is a great new tool to add to your arsenal for improving code quality. Combined with Code Analysis and Code Metrics, this will help quickly find potential issues.
Keyboard: CTRL + SHIFT + U (upper); CTRL + U (lower)Menu: Edit -> Advanced -> Make Uppercase; Edit -> Advanced -> Make LowercaseCommand: Edit.MakeUppercase; Edit.MakeLowercaseVersions: 2008,2010Published: 4/10/2010Code: vstipEdit0044
Download the seriously cool Tip of the Day Extension to get the daily tips delivered to your Start Page!
Okay, so let's say you have some text (a variable, maybe?)
and you need to do some case-changing action on it. Plus, there is a crazy guy holding several people hostage and threatening to dip them in boiling chocolate unless you do it fast. What do you do? No Problem! You just select the word and press CTRL + SHIFT + U to make it uppercase
or if the evil guy isn't satisfied you can always make it lowercase by pressing CTRL + U
And now you have saved the day!