Optimal Encapsulation

 

There is a very simple thing to do to rationalize a code base: making
sure that every methods, fields and types have an optimal visibility. For
example, if a method is declared internal but is not used outside its declaring
type, it should be declared private. For such method the private visibility is
its optimal one. Rationalizing a code base with optimal visibility help
protecting from potential flaw. For example having optimal visibility can avoid
improper coupling with a class that should have been declared internal as soon as it
was developed.

 

Since the early days of NDepend, the tool was able to tell which code elements
do not have optimal visibility. We now moved this feature into Code Query Language
v1.5
with the following CQL conditions:

 

CouldBeInternal, CoulBeInternalProtected,  CouldBeProtected, CouldBePrivate and ShouldBePublic.

 

The default set of CQL constraints comes with a new
Optimal Encapsulation group that contains constraints such as…

 

SELECT METHODS WHERE CouldBePrivate

 

…and that you can adapt to suit the needs of your own
code base…

 

SELECT METHODS OUT OF NAMESPACES “MyNamespace1″, “MyNamespace2″ WHERE CouldBePrivate AND !NameLike “MyMethodsThatIDontWantToBePrivate”…

 

Of course, if your code base is a framework, there are
chances that the query…

 

SELECT METHODS WHERE CouldBeInternal

 

…returns a lot of public methods that are not used by
your code base, but that should remain public anyway because some external client code
relies on it. In this case, just discard this query.

 

 

What about the condition ShouldBePublic? This condition matches types,
methods and fields that are declared as internal but that are used by code
declared in other assemblies thanks to the attribute
System.Compilers.Services.InternalsVisibleToAttribute. In general, having code
elements that are considered as
ShouldBePublic is not a problem because it is
made on purpose. However, it can be interesting to list them.

The condition CoulBeInternal can also apply to namespaces although .NET
languages (C#, VB.NET etc) don’t allow visibility modifier on namespaces. A
namespace is considered as
CoulBeInternal if it contains only types that are
used internally and if at least one of its types is declared as public.

 

SELECT NAMESPACES WHERE CouldBeInternal

 

While developing the
optimal visibility feature, we notice an interesting thing. When you declare an
internal class without  an explicit constructor, the default constructor automatically provided by the C#
compiler is public. NDepend will tell you to declare explicitly an internal
constructor but beware here: having a default internal constructor can sometime lead to serialization
issues.

 

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.EdmundKirwan.com Ed Kirwan

    Hi, Patrick,

    The may seem a little odd, but I was playing around with some mathematics a while back and derived a methematical law proving optimum encapsulation for small family of systems. You may, or may not, fancy the read here:
    http://www.edmundkirwan.com/encap/intro.html

    But if that’s too much, the second law states that the encapsulation which minimises a family of systems’ complexity is when the number of name spaces equals the square root of the number of classes divided by the number of public classes per name space.

    Ed

  • http://grabbagoft.blogspot.com/ Jimmy Bogard

    Wow this is weird, we were talking about this very thing in our M. Feathers book club today. “Gee I wish there was a tool that would tell us if our visibilities were appropriate”, then boom here it is. Now to start the 5 month purchase approval process…