NDepend

Improve your .NET code quality with NDepend

prioritize-bugs

How to Prioritize Bugs on Your To-Do List

People frequently ask me questions about code quality.  People also frequently ask me questions about efficiency and productivity.  But it seems we rarely wind up talking about the two together.  How can you most efficiently improve quality via the fixing of bugs?  Or, more specifically, how should you prioritize bugs?

Let me be clear about something up front.  I’m not going to offer you some kind of grand unified scheme of bug prioritization.  If I tried, the attempt would come off as utterly quixotic.  Because software shops, roles, and offerings vary so widely, I cannot address every possible situation.

Instead, I will offer a few different philosophies of prioritization, leaving the execution mechanics up to you.  These should cover most common scenarios that software developers and project managers will encounter.
Continue reading How to Prioritize Bugs on Your To-Do List

static analysis for the build machine

Static Analysis for the Build Machine?

I remember my earliest experiences with static analysis.  Probably a decade ago, I started to read about it during grad school and poke around with it at work.  Immediately, I knew I had discovered a powerful advantage for programmers.  These tools automated knowledge.

While I felt happy to share the knowledge with coworkers, their lack of interest didn’t disappoint me.  After all, it felt as though I had some sort of trade secret.  If those around me chose not to take advantage, I would shine by comparison.  (I have since, I’d like to think, matured a bit.)  Static analysis became my private competitive advantage — Sabermetrics for programmers.

So as you can imagine, running it on the build machine would not have occurred to me.  And that assumes a sophisticated enough setup that doing so made sense (not really the case back then).  Static analysis was my ace in the hole for writing good code — a personal choice and technique.

Fast forward a decade.  I have now grown up, worked with many more teams, and played many more roles.  And, of course, the technological landscape has changed.  All of that combined to cause a complete reversal of my opinion.  Static analysis and its advantages matter far too much not to use it on the build machine.  Today, I’d like to expand on that a bit.
Continue reading Static Analysis for the Build Machine?

static analysis continuous testing relationship

The Relationship between Static Analysis and Continuous Testing

As an adult, I have learned that I have an introvert type personality.  I do alright socially, don’t mind public speaking, and do not (I don’t think) present as an awkward person.  So, learning about this characterization surprised me somewhat, but only until I fully understood.

I won’t delve into the finer points of human psychology here, but suffice it to say that introverts prefer to process and grok questions before responding.  This describes me to a tee.  However, working as a consultant and giving frequent advice clashes with this and has forced me to develop somewhat of a knack for answering extemporaneously.  Still, you might ask me just the right question to cause me to cock my head, blink at you, and frown.

I received just such a question the other day.  The question, more or less, was, “if we have continuous testing, do we really need static analysis?”  And, just like that, I was stumped.  This didn’t square, and I wanted time to think on that.  Luckily, I’ve had a bit of time.  (This is why I love blogging.) Continue reading The Relationship between Static Analysis and Continuous Testing

effective team code reviews

How to Perform Effective Team Code Reviews

I’ve heard people say (paraphrased) that teams succeed uniformly, but fail each in its own unique way.  While I might argue the veracity of this statement, it evokes an interesting image.  Many roads, lined with many decisions, lead to many different sorts of failures. Team code reviews present no exception.  Teams can fail at code review in myriad, unique ways.  And, on top of that, many paths to broader failure can involve poor code reviews (doubtless among other things).

How can I assign such importance to the code review?  After all, many would consider this an ancillary team activity and one with only upside.  Done poorly, code review catches no defects.  Done well, it catches some defects.  Right? Continue reading How to Perform Effective Team Code Reviews

Rewrite or Refactor?

I’ve trod this path before in various incarnations and I’ll do it again today.  After all, I can think of few topics in software development that draw as much debate as this one.  “We’ve got this app, and we want to know if we should refactor it or rewrite it.”

For what it’s worth, I answer this question for a living.  And I don’t mean that in the general sense that anyone in software must ponder the question.  I mean that CIOs, dev managers and boards of directors literally pay me to help them figure out whether to rewrite, retire, refactor, or rework an application.  I go in, gather evidence, mine the data and state my case about the recommended fate for the app.

Because of this vocation and because of my writing, people often ask my opinion on this topic.  Today, I yet again answer such a question.  “How do I know when to rewrite an app instead of just refactoring it?”  I’ll answer.  Sort of.  But, before I do, let’s briefly revisit some of my past opinions. Continue reading Rewrite or Refactor?

Secrets of Maintainable Codebases

You should write maintainable code.  I assume people have told you this at some point.  The admonishment is as obligatory as it is vague.  So, I’m sure, when you heard this, you didn’t react effusively with, “oh, good idea — thanks!”

If you take to the Internet, you won’t need to venture far to find essays, lists, and stack exchange questions on the subject.  As you can see, software developers frequently offer opinions on this particular topic.  And I present no exception; I have little doubt that you could find posts about this on my own blog.

So today, I’d like to take a different tack in talking about maintainable code.  Rather than discuss the code per se, I want to discuss the codebase as a whole.  What are the secrets to maintainable codebases?  What properties do they have, and what can you do to create these properties?

In my travels as a consultant, I have seen so many codebases that it sometimes seems I’m watching a flip book show of code.  On top of that, I frequently find myself explaining concepts like the cost of code ownership, and regarding code as, for lack of a better term, inventory.  From the perspective of those paying the bills, maintainable code doesn’t mean “code developers like to work with” but rather “code that minimizes spend for future changes.”

Yes, that money includes developer labor.  But it also includes concerns like deployment effort, defect cycle time, the universality of skills required, and plenty more.  Maintainable codebases mean easy, fast, risk-free, and cheap change.  Here are some characteristics in the field that I use when assessing this property.  Some of them may seem a bit off the beaten path.

Continue reading Secrets of Maintainable Codebases

what to do when your colleague creates spaghetti code

What to do when Your Colleague Creates Spaghetti Code

I write for a number of different outfits and earn my living consulting around software and IT.  Because of the intersection of these three concerns — writing, offering advice professionally, and software — I field a lot of requests for advice on how to do the right technical thing without everyone around you shooting holes in it.  Consider an example.

“How can we get started with unit testing?”

Considered as a technical question alone, this invites a fairly obtuse response.  “First, write a unit test.  Second, run the unit test.”  Obviously, that’s not really what anyone is asking when they ask this question.

Instead, they want to know something orders of magnitude more complex.  “How can we overcome years of inertia, a nasty legacy codebase, Bill, who has been around for 40 years and hates everything new, and the fact that management doesn’t want to pay us to write ‘extra’ code… and then start unit testing?”  Oh, yeah, that.  Well, that’s complicated.

I frequently hear such apparently-innocuous-but-actually-complex questions about code quality.  “This idiot on my team is writing mountains of the most unmaintainable garbage imaginable — what should I do?”

Usually, this sort of question comes to me from people at client sites.  And, accordingly, I have to balance the answer that makes the most sense for the individual with the one that keeps the client’s best interests in mind.  The client pays my bill, and I have a charter to lower the cost of ownership and development of their code.

But when I’m in writer mode, and only the asker’s interests matter, I’l give a subtly different answer.  Today, I’d like to offer advice on what you should do in this situation.

Continue reading What to do when Your Colleague Creates Spaghetti Code

Considering a Port to .NET Core? Use NDepend

An American colloquialism holds, “only two things are certain: death and taxes.”  If I had to appropriate that for the software industry, I might say that the two certainties are death and legacy code.  Inevitably, you have code that you have had for a while, and you want to do things with it.

Software architects typically find themselves tasked with such considerations.  Oh, sure, sometimes they get to pick techs and frameworks for greenfield development.  Sometimes they get to draw fancy diagrams and lay out plans.  But frequently, life charges them with the more mundane task of “figuring out how to make that creaky old application run on an iPhone.”  Okay, maybe it’s not quite that silly, but you get the idea.

If you earn a living as an architect in the .NET world, you have, no doubt, contemplated the impact of .NET Core on your application portfolio.  Even if you have no active plans to migrate, this evolution of .NET should inform your strategic decisions going forward.  But if you have use for deploying the framework along with your application or if you want to run on different operating systems, you’re going to need to port that legacy code.

I am, by no means, an expert in .NET Core.  Instead, my areas of specialty lie in code analysis, developer training, and IT management and strategy consulting.  I help dev teams create solutions economically.  And because of this, I can recognize the value of NDepend to a port from what I do know about .NET core.

Continue reading Considering a Port to .NET Core? Use NDepend

plugging leaky abstractions

Plugging Leaky Abstractions

In 2002, Joel Spolsky coined something he called “The Law of Leaky Abstractions.”  In software, an “abstraction” hides complexity of an underlying system from those using the abstraction.  Examples abound, but for a quick understanding, think of an ORM hiding from you the details of database interaction.

The Law of Leaky Abstractions states that “all non-trivial abstractions, to some degree, are leaky.”  “Leaky” indicates that the abstraction fails to adequately hide its internal details.  Imagine, for instance, that while modifying the objects generated by your ORM, you suddenly needed to manage the particulars of some SQL query.  The abstraction leaked, forcing you to understand the details that it was supposed to hide.

Spolsky’s point may inspire a fatalistic feeling.  After all, if the things are doomed to leak, why bother with them in the first place?  But I like to consider it a caution against chasing perfection rather than a lament.

Abstractions in software help us the same way figurative language helps our prose.  Metaphors and analogies offer ease of understanding, but at the accepted price of lost precision.  If you press a metaphor enough, it will inevitably break down.  But that doesn’t render metaphors useless — far from it.

Thus, if you have a leaky abstraction, you can take steps to “plug” it, so to speak.  Spolsky says it himself, right in the law he coined: “all non-trivial abstractions are, to some degree, leaky.”  We have the ability to lessen that degree.

Continue reading Plugging Leaky Abstractions

Measure Your Code to Get Back on Track

When I’m called in for strategy advice on a codebase, I never arrive to find a situation where all parties want to tell me how wonderfully things are going.  As I’ve mentioned before here, one of the main things I offer with my consulting practice is codebase assessments and subsequent strategic recommendations.

Companies pay for such a service when they have problems, and those problems drive questions.  “Should we scrap this code and start over, or can we factor toward a better state?”  “Can we move away from framework X, or are we hopelessly tied to it?”  “How can we evolve without doing a forklift upgrade?”

To answer these questions, I assess their code (often using NDepend as the centerpiece for querying the codebase) and synthesize the resultant statistics and data.  I then present a write-up with my answer to their questions.  This also generally includes a buffet of options/tactics to help them toward their goals.  And invariably, I (prominently) offer the option: “instrument your code/build with static analysis to raise the bar and prevent backslides.”

I find it surprising and a bit dismaying how frequently clients want to gloss over this option in favor of others. Continue reading Measure Your Code to Get Back on Track