NDepend

Improve your .NET code quality with NDepend

Announcing the Singleton Challenge

Announcing the Singleton Challenge

About a month ago, I made a post about what the singleton pattern costs you.  Although I stated my case in terms of trade-offs rather than prescriptive advice, I still didn’t paint the singleton pattern in a flattering light.  Instead, I talked about the problems that singletons tend to create in codebases.

Whenever I’ve talked about the singleton pattern, anywhere I’m blogging, the general response follows a typical signature.  It attracts a relatively large amount of shares (usually indicating support) and traffic (often indicating support) while generating comments (these often contain objections).  Generally, the response follows this pattern from Stack Overflow.  At the time of writing:

  • 1,018 net upvotes for an answer explaining why they’re bad.
  • 377 net upvotes for an answer explaining why they’re usually a mistake.
  • 280 net upvotes for them getting a bad wrap only because people misuse them (with a disproportionate number of mitigating downvotes).
  • 185 net upvotes for an answer explaining why they’re terrible.

It seems as though something like 80 percent of the active developer population has come around to thinking, “Yeah, let’s not do this anymore.”  But a vocal 20 percent minority resents that, thinking the rest are throwing the baby out with the bathwater.

Perusing some of the comments on the blog and discussion sites where it was shared, I found two themes of objection to the post.

  1. If singleton is so bad, why do DI frameworks provide singleton object instances?
  2. Your singleton examples are bad, ergo the problem is that you misuse singletons.

Today, I’d like to address those threads of criticism.  But not ultimately in the way you might think.

Continue reading Announcing the Singleton Challenge

Understanding Cyclomatic Complexity

Wander the halls of an enterprise software outfit looking to improve, and you’ll hear certain things.  First and foremost, you’ll probably hear about unit test coverage.  But, beyond that, you’ll hear discussion of a smattering of other metrics, including cyclomatic complexity.

It’s actually sort of funny.  I mean, I understand why this happens, but hearing middle managers say “test coverage” and “cyclomatic complexity” has the same jarring effect as hearing developers spout business-meeting-speak.  It’s just not what you’d naturally expect.

And you wouldn’t expect it for good reason.  As I’ve argued in the past, code coverage shouldn’t be a management concern.  Nor should cyclomatic complexity.  These are shop-heavy specifics about particular code properties.  If management needs to micromanage at this level of granularity, you have a systemic problem.  You should worry about these properties of your code so that no one else has to.

With that in mind, I’d like to focus specifically on cyclomatic complexity today.  You’ve probably heard this term before.  You may even be able to rattle off a definition.  But let’s take a look in great detail to avoid misconceptions and clear up any hazy areas.

Defining Cyclomatic Complexity

First of all, let’s get a specific working definition.  This is actually surprisingly difficult because not all sources agree on the exact method for computing it.

How can that be?  Well, the term was dreamed up by a man named Thomas McCabe back in 1976.  He wanted a way to measure “the number of linearly independent paths through a program’s source code.”  But beyond that, he didn’t specify the mechanics exactly, leaving that instead to implementers of the metric.

He did, however, give it an intimidating-sounding name.  I mean, complexity makes sense, but what does “cyclomatic” mean, exactly?  Well, “cyclomatic number” serves as an alias for something more commonly called circuit rank.  Circuit rank measures the number of independent cycles within a cyclic graph.  So I suppose he coined the neologism “cyclomatic complexity” by borrowing a relatively obscure discrete math concept for path independence and applying it to code complexity.

Well then.  Now we have cyclomatic complexity, demystified as a term.  Let’s get our hands dirty with examples and implications.

Continue reading Understanding Cyclomatic Complexity

Marker Interface Isn't a Pattern or a Good Idea

Marker Interface Isn’t a Pattern or a Good Idea

Today, I have the unique opportunity to show you the shortest, easiest code sample of all time.  I’m talking about the so-called marker interface.  Want to see it?  Here you go.

I told you it was simple.  It’s dead simple for a code sample, so that makes it mind-blowingly simple for a design pattern.  And that’s how people classify it — as a design pattern.

How Is This “Marker Interface” Even a Pattern?

As you’ve inferred from the title, I’m going to go on to make the claim that this is not, in fact, a “design pattern” (or even a good idea).  But before I do that, I should explain what this is and why anyone would do it.  After all, if you’ve never seen this before, I can forgive you for thinking it’s pretty, well, useless.  But it’s actually clever, after a fashion.

The interface itself does nothing, as advertised.  Instead, it serves as metadata for types that “implement” it.  For example, consider this class.

The customer class doesn’t implement the interface.  It has no behavior, so the idea of implementing it is nonsense.  Instead, the customer class uses the interface to signify something to the client code using it.  It marks itself as containing sensitive information, using the interface as a sort of metadata.  Users of the class and marker interface then consume it with code resembling the following:

Using this scheme, you can opt your classes into special external processing.

Marker Interface Backstory

I’m posting code examples in C#, which makes sense.  After all, NDepend is a .NET ecosystem tool.  But the marker interface actually goes back a long way.  In fact, it goes back to the earlier days of Java, which baked it in as a first class concept, kind of how C# contains a first class implementation of the iterator design pattern.

In Java, concepts like serialize and clone came via marker interfaces.  If you wanted serialization in Java, for instance, you’d tag your class by “implementing” the marker interface Serializable.  Then, third party processing code, such as ORMs, IoC containers, and others would make decisions about how to process it.  This became common enough practice that a wide ecosystem of tools and frameworks agreed on the practice by convention.

C# did not really follow suit.  But an awful lot of people have played in both sandboxes over the years, carrying this practice into the .NET world.  In C#, you’ll see two flavors of this.  First, you have the classic marker interface, wherein people use it the way that I showed above.  Secondly, you have situations where people get clever with complex interface inheritance schemes and generics in order to force certain constraints on clients.  I won’t directly address that second, more complex use case, but note that all of my forthcoming arguments apply to it as well.

Now, speaking of arguments, let’s get to why I submit that this is neither a “pattern” nor a good idea in modern OOP.  NDepend tells you to avoid this, and I wholeheartedly agree.

Continue reading Marker Interface Isn’t a Pattern or a Good Idea

Understanding the Different Between Static And Dynamic Code Analysis

Understanding the Difference Between Static And Dynamic Code Analysis

I’m going to cover some relative basics today.  At least, they’re basics when it comes to differentiating between static and dynamic code analysis.  If you’re new to the software development world, you may have no idea what I’m talking about.  Of course, you might be a software development veteran and still not have a great idea.

So I’ll start from basic principles and not assume you’re familiar with the distinction.  But don’t worry if you already know a bit.  I’ll do my best to keep things lively for all reading.

Static and Dynamic Code Analysis: an Allegory

So as not to bore anyone, bear with me as I plant my tongue in cheek a bit and offer an “allegory” that neither personifies intangible ideas nor has any real literary value.  Really, I’m just trying to make the subject of static and dynamic code analysis the slightest bit fun on its face.

So pull your fingers off the keyboard and let’s head down to the kitchen.  We’re going to do some cooking.  And in order to that, we’re going to need a recipe for, say, chili.

We all know how recipes work in the general life sense.  But let’s break the cooking activity into two basic components.  First, you have the part where you read and synthesize the recipe, prepping your materials and understanding how things will work.  And then you have the execution portion of the activity, wherein you do the actual cooking — and then, if all goes well, the eating.

Static and Dynamic Recipe Analysis

Having conceived of preparing the recipe in two lights, think in a bit more detail about each activity.  What defines them?

First, the recipe synthesis.  Sure, you read through it to get an overview from a procedural perspective, rehearsing what you might do.  But you also make inferences about the eventual results.  If you’ve never actually had chili as a dish, you might contemplate the ingredients and what they’d taste like together.  Beef, tomato sauce, beans, spicy additives…an idea of the flavor forms in your head.

You can also recognize the potential for trouble.  The recipe calls for cilantro, but you have a dinner guest allergic to cilantro.  Yikes!  Reading through the recipe, you anticipate that following it verbatim will create a disastrous result, so you tweak it a little.  You omit the cilantro and double check against other allergies and dining preferences.

But then you have the actual execution portion of preparing a recipe.  However imaginative you might be, picturing the flavor makes a poor substitute for experiencing it.  As you prepare the food, you sample it for yourself so that you can make adjustments as you go.  You observe the meat to make sure it really does brown after a few minutes on high heat, and then you check on the onions to make sure they caramelize.  You observe, inspect, and adapt based on what’s happening around you.

Then you celebrate success by throwing cheese on the result and eating until you’re uncomfortably full.

Continue reading Understanding the Difference Between Static And Dynamic Code Analysis

Using NDepend to Get Going Quickly on C# Projects

Using NDepend To Get Going Quickly on C# Projects

Assuming you’ve had at least one job working on one or more C# projects, let me paint a familiar picture for you.  I’m talking about your onboarding time with a new group.  It’s always an exciting and awkward experience as you feel out teammates and new codebases.

On day one, you arrive.  But rarely does anyone expect you to contribute meaningfully on that day.  In fact, you probably won’t even contribute meaningfully that first week.  Instead, you hear plenty of talk about “learning curves” and how this environment is uniquely challenging.  Ironically, every shop I visit as a consultant claims to be uniquely challenging.

C# Projects: the Onboarding Phase

What, then, does onboarding usually look like?  I’ll build you a composite picture, based on my travels.  I’ll leave out the HR component, with new team member lunches and paperwork; here, we’ll consider only about the technical aspects.

On the first day, you show up and a developer on the team works with you on the basics.  You get access to the mundane necessities: network shares, the internal SharePoint, version control, etc.  If you get lucky, all of that goes smoothly, and you actually get source code on your machine.  But this could also drag out a day or two.

During this time, everyone on the team is pretty busy.  You have chunks of time left to your own devices, instructed to study the architecture and design documents and also to look around the codebase.  These documents paint impressive architectural pictures of layer cakes, distributed clusters, tiers, and CQRS paradigms.  You secretly wonder if they’re accurate.  (Spoiler: they aren’t.)

You’d get going on real work sooner, but the architect needs to walk you through the relevant design patterns.  This is necessary so you’ll know what goes where without making a serious blunder. Of course, the architect is really busy since all problems bubble up to her.  So you wait.

Continue reading Using NDepend To Get Going Quickly on C# Projects

What the Singleton Pattern Costs You

What the Singleton Pattern Costs You

Do you use the singleton pattern?  If not, I’m assuming that you either don’t know what it is or that you deliberately avoid it.  If you do use it, you’re probably sick of people judging you for it.  The pattern is something of a lightning rod in the world of object-oriented programming.

You can always use Stack Overflow as a litmus test for programming controversy.  Someone asked “what was so bad” about singletons, and voting, responding, and commenting went off the charts.  Most of those responses fell into the negative category.  Outside of Stack Overflow, people call singletons evil, pathological liars, and anti-patterns.  People really seem to hate this design pattern — at least some of them do, anyway.

NDepend takes a stance on the singleton pattern as well, both in its rules and on the blog.  Specifically, it encourages you to avoid it.

But I’m not going to take a stance today, exactly.  I understand the cathartic temptation to call something evil in the world of programming.  If some (anti) pattern, framework, or language approach has caused you monumental pain in the past, you come to view it as the tool of the devil.  I’ve experienced this and turned it into a blog post, myself.

Instead of going that route here, however, I’m going to speak instead about what it can cost you when you decide to use the singleton pattern — what it can cost the future you, that is.  I have a consulting practice assessing third-party codebases, so I’ve learned to view patterns and practices through a dispassionate lens.  Everything is just trade-offs.

Continue reading What the Singleton Pattern Costs You

The Role of Static Analysis in Testing

The Role of Static Analysis in Testing

“What do you do?”

In the United States, people ask this almost immediately upon meeting one another for the first time.  These days, I answer the question by saying that I do IT management consulting.  That always feels kind of weird rolling off the tongue, but it accurately describes how I’ve earned a living.

If you’re wondering what this means, basically I advise leadership in IT organizations.  I help managers, directors, and executives better understand how to manage and relate to the software developers in their groups.  So you might (but hopefully won’t) hear me say things like, “You should stop giving out pay raises on the basis of who commits the most lines of code.”

In this line of work, I get some interesting questions.  Often, these questions orient around how to do more with less.  “How can we keep the business happy when we’re understaffed?”  “What do we do to get away from this tech debt?”  “How should we prioritize our work?”  That sort of thing.

Sometimes, they get specific.  And weird.  “If we do this dependency injection thing, do we really need to deploy as often?”  Or “If we implement static analysis, do we still need to do QA?”

I’d like to focus on the latter question today — but not because it’s a particularly good or thought-provoking one.  People want to do more with less, which I get. But while that particular question is a bit of a non sequitur, it does raise an interesting discussion topic: what is the role of static analysis in testing?

Static Analysis in Testing: An Improbable (But Real) Relationship

If you examine it on the surface, you won’t notice much overlap between testing and static analysis.  Static analysis involves analyzing code without executing it, whereas QA involves executing the code without analyzing it (among other things).

A more generous interpretation, however, starts to show a relationship.  For instance, one could argue that both activities relate deeply to code quality.  Static analysis speaks to properties of the code and can give you early warnings about potential problems.  QA takes a black box approach to examining the code’s behavior, but it can confirm the problems about which you’ve received warnings.

But let’s dive even a bit deeper than that.  The fact that they have some purview overlap doesn’t speak to strategy.  I’d like to talk about how you can leverage static analysis as part of your testing strategy — directly using static analysis in testing.

Continue reading The Role of Static Analysis in Testing

How Has Static Code Analysis Changed Through the Years?

Years ago, I found myself staring at about 10 lines of source code.  This code had me stymied, and I could feel the onset of a headache as I read and re-read it.  What did this brain-bending code do, you might wonder?  It sorted elements in an array.

Now you probably assume that I was learning to code at the time.  Interestingly, no.  I had worked gainfully as a software developer for years and was also completing a master’s degree in computer science.  In fact, the pursuit of this degree had brought me to this moment of frustration, rubbing my temples and staring tiredly at a simple bubble sort in C.

Neither inexperience nor the difficulty of the code had brought me to that point.  Rather, I struggled to formally prove the correctness of this tiny program, in the mathematical sense.  I had enrolled in a class called “Formal Methods of Software Development” that taught the math underpinning our lives as programmers.

This innocuous, simple bubble sort had seven execution paths.  Here was number five, from a piece of homework I kept in my digital files.

Code analysis ranges from the academic to the pragmatic.

Hopefully I now seem less like an incompetent programmer and more like a student grappling with some weighty concepts.  But why should a simple bubble sort prove so difficult?  Well, the short answer is that actually proving things about programs with any complexity is really, surprisingly hard.  The longer answer lies in the history of static code analysis, so let’s take a look at that.

Continue reading How Has Static Code Analysis Changed Through the Years?

Code Coverage Should Not Be a Management Concern

Code Coverage Should Not Be a Management Concern

You could easily find yourself mired in programmer debates over code coverage.  Here’s one, for instance.  It raged on for hundreds of votes, dozens of comments, many answers, and eight years before someone put it out to pasture as “opinion-based” and closed it.

Discussion participants debated a “reasonable” percentage of code coverage.  I imagine you can arrive at the right answer by taking the mean of all of the responses. (I’m just kidding.)

Some of the folks in that thread, however, declined to give a simple percentage.  Instead, they gave the obligatory consultant’s response of “it depends” or, in the case of the accepted answer, a parable.  I found it refreshing that not everybody picked some number between 50 and 100 and blurted it out.

But I found it interesting that certain questions went unasked.  What is the goal of this code coverage?  What problem does it solve?  And as for the reasonability of the number, reasonable to whom?

What is Code Coverage? (Briefly)

Before going any further, I’ll quickly explain the concept of code coverage for those not familiar, without belaboring the point.  Code coverage measures the percentage of code that your automated unit test suite executes when it runs.

So let’s say that you had a tiny codebase consisting of two methods with one line of code each.  If your unit test suite executed one method but not the other, you would have 50% code coverage.  In the real world, this becomes significantly more complicated.  In order to achieve total coverage, for instance, you must traverse all paths through control flow statements, such as if conditions, switch statements, and loops.

When people debate how much code coverage to have, they aren’t debating how “correct” the code should be.  Nor do they debate anything about the tests themselves, such as quantity or quality.  They’re simply asking how many lines of code per one hundred your test suite should cause to execute.

You can get tools that calculate this for you.  And you can also get tools that factor it into an overall code quality dashboard.

Continue reading Code Coverage Should Not Be a Management Concern

Is Your Team Wrong About Your Codebase? Prove It. Visually.

I don’t think I’ll shock anyone by pointing out that you can find plenty of disagreements among software developers.  Are singletons evil?  Is TDD a good idea (or dead)?  What’s the best IDE?  You can see this dynamic writ large across the internet.

But you can also see it writ small among teammates in software groups.  You’ve seen this before.  Individuals or small camps form around certain competing ideas, like how best to lay out the unit test suite or whether or not to use a certain design pattern. In healthy groups, these disagreements take the form of friendly banter or good-natured ribbing.  In less healthy groups, they create an us vs. them kind of dynamic and actual resentment.

I’ve experienced both flavors of this dynamic in my career.  Having to make concessions about how you do things is never fun, but group work requires it.  And so you live with the give-and-take of this in healthy groups.  But in an unhealthy group, frustration mounts with no benefit of positive collaboration to mitigate it.  This holds doubly true when one of the two sides has the decision-making authority or perhaps just writes a lot of the code and claims a form of squatter’s rights.

Status Quo Preservation

Division into camps can, of course, take many forms.  But I think the one you see most commonly happens when you have a group of developers or architects who have laid the ground rules for the codebase and then a disparate group of relative newcomers that want to change the status quo.

I once coined a term for a certain archetype in the world of software development: the expert beginner.  Expert beginners wind up in decision-making positions by default and then refuse to be swayed in the face of mounting evidence, third party opinions, or, well, really anything.  They dig in and convince themselves that they’re right about all matters relating to the codebase, and they express no interest in hearing dissenting opinions.  This commonly creates the toxic, adversarial dynamic here, and it leaves the rest of the group feeling helpless and frustrated.

Of course, this cuts the other way as well.  Sometimes the longest tenured decision makers of the group earned their position for good reason and acquit themselves well in defense of their positions.  Perhaps you shouldn’t adopt every passing fad and trend that comes along.  And these folks might find it tiresome to relitigate past architectural decisions ad nauseum every time a new developer hires on.  It probably doesn’t help when newbies throw around pejorative terms like “legacy code” and “the old way,” either.

Continue reading Is Your Team Wrong About Your Codebase? Prove It. Visually.