DevPinoy.org

A Filipino Developers Community
Welcome to DevPinoy.org Sign in | Join | Help
in Search

cruizer

aspiring to free and open the mind of .NET developers

September 2007 - Posts

  • Cyclomatic complexity and its effect on my code

    Have you heard of the term cyclomatic complexity?

    I had my first encounter with it in the current project we're doing at work. One of the senior guys in our project set up our build server, with CruiseControl.NET invoking a tool called SourceMonitor and analyzing source code complexity. Basically, the tool counts the number of branches being made per method per source file.  An if statement, for example, generates an additional branch.  Having an else to that if statement adds another branch to the code.  You can imagine how many branches a massive switch statement would result in. Stick out tongue The CruiseControl.NET generates statistics which can be viewed by the PHBs (or *NHBs, ha ha) in our organization to help them feel good about the project we're doing.

    It's starting to have an effect on how I view my code. One effect is discussed in my previous blog post. My observation is that it meshes well with Test-Driven Development (TDD). With TDD, you are forced by the practice to create short methods that focus on specific tasks.  In order to keep method complexity to a minimum, it can be helpful to break the method into multiple methods.  Otherwise one can end up with a single method having a cyclomatic complexity of 54.  I've also observed that code with high complexity are those that are very procedural in nature...something I'd love to stick a (refactoring) knife to.

    Of course, cyclomatic complexity is not perfect. Like I mentioned above, it measures procedural complexity. But it doesn't measure OOP complexity due to overuse of design patterns and abstractions. I hope I don't end up feeling good about my code because the highest complexity I have is 3 in most of my code, when in fact it's shifted into a different form of complexity (OOP), one that isn't measured by the tool we're using.

    *NHB - "no-haired" boss

  • Enums are EVIL!

    Early in my C# coding life I actually liked enums. They're neater than C enums (which are glorified int constants) and they're type-safe. But lately I've grown to hate them. To me, they are a leading cause of verbosity in C# code and those who use them tend to produce procedural code. I'll show why I feel this is so, and I'll discuss an approach you can use to weed them out.

    I remember a project I worked on earlier this year in a previous employer. Some parts of the code made use of Model-View-Presenter and some don't. I guess such a thing is kinda expected when development teams change throughout the different phases of the project. But there's this particular thing in the WinForms code that stood out like a sore toe. The UI had a grid control and an array of buttons in the lower portion of the form. In this case, each button had a particular enum assigned to its Tag property. All the buttons had just one event handler, and eventually the call to the event handler gets to a massive switch-case block which calls the appropriate view/form method for the button. Massive pain!

    Enums are simply labels (or, in the example I cited above, tags). You can assign them anywhere to allow you to distinguish between different cases that are represented by the enum. For example, if you want to distinguish between days, you can use a DayOfWeek enum, which comes built into .NET anyway. If you want to distinguish between different data types you can have some enum like MyDataType.String, MyDataType.Integer, MyDataType.Decimal, and so on. But then...HOW do you actually plan to distinguish between them later in your code? More often than not, it will involve a massive if or switch block. I mean, pull out any .NET code you can find that uses enums...it's very likely that it will have that conditional block to distinguish between the different values for that enum. It is equally likely that duplication or similar code (cut-n-paste code?) can be found across the various case handlers in that particular if or switch block.

    The object-oriented way of dealing with an enum is to...throw it out! Wink I am not kidding. Instead, replace them with polymorphic behavior. The example I cited above with all form buttons having a common event handler but differing enum values assigned to each button's Tag property can be refactored into using the Command pattern. The WinForms default event handling mechanism is in fact very similar already to the Command pattern so the simpler solution might be to simply switch back to the WinForms way of doing things (having a delegate to handle each Button's Click event). On the other hand, my example above about handling different data types can be dealt with using something like the Strategy pattern.  So you can have separate classes for handling string, integer and decimal operations having the same interface or superclass. So instead of doing something like:

    HideAllFields();
    switch (dataType) {
        case MyDataType.String:
            StringTextField.Text = someValue;
            StringTextField.Visible = true;
            break;
        case MyDataType.Integer:
            IntTextField.Text = someValue.ToString();
            IntTextField.Visible = true;
            break;
        case MyDataType.Decimal:
            DecTextField.Text = someValue.ToString();
            DecTextField.Visible = true;
            break;
    }

    You can do something like:

    HideAllFields();
    myData.EnableControlAndSetValue(someValue);

    and have different classes representing string, integer and decimal deriving from the same class or interface with a virtual method named EnableControlAndSetValue. In this case the class for handling strings can look like:

    public class MyStringType : MyBaseType {
        public MyStringType(TextBox textFieldControl) : base(textFieldControl) {
        }
        public override void EnableControlAndSetValue(object someValue) {
            myPrivateTextBox.Text = someValue.ToString();
            myPrivateTextBox.Visible = true;
        }

    You might be thinking: "Hey, that means more code to type!" In a way, yes, that's true for this example. But imagine if you have twenty possible data types, and suddenly the requirement is changed and you have to support thirty possible data types. With the enum approach, you'll have to change the enum to add ten new enum entries, and you'll have to extend your switch statement to support thirty cases. In contrast, with the Strategy pattern approach here will only require you to create ten new short classes to correspond to those new data types, each differing only in their overridden EnableControlAndSetValue method. If all your classes do the same routine (setting the textbox Text property and making it Visible) then you can even move the EnableControlAndSetValue method to the base class (e.g. MyBaseType) and you won't have to override it at all in each class.

    You might think that this example is contrived and puts enums in the worst light possible and that there are pros and cons to the enum approach vs. the polymorphic approach. Yes, there definitely are trade-offs, but in my case I prefer smaller, more focused classes than an unwieldy series of if/switch statements. So these days I have shunned enums. I only work with them when I am forced to do so (i.e. legacy code I need to maintain at work -- and I certainly feel the itch to get it refactored!).

    UPDATE: The master showed me these links: Replace Conditional Logic with Strategy and Replace Conditional Dispatcher with Command. Thanks master!

Powered by Community Server (Commercial Edition), by Telligent Systems