Click here to Skip to main content
15,896,444 members
Articles / All Topics

Staying DRY with Atomiq

Rate me:
Please Sign up or sign in to vote.
4.67/5 (2 votes)
16 Jul 2015CPOL3 min read 5.5K   2  
Staying DRY with Atomiq

Don’t Repeat Yourself, or DRY, is a key principle of software engineering. Various sites on the web and various courses state this principle as:

“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

One of the things this means, practically, is that the abstractions that you use in your code should provide for reuse such that there is never a need to copy code.

Reuse of code can be accomplished by properly designing your objects (abstractions) such that they have a single responsibility. For example, if you have several objects that communicate with a data layer, you should abstract the data layer away into a data access class that is then injected into the constructor of objects that need to converse with the data layer. This provides for better data encapsulation and allows for better unit testing as you can create a fake for the data access object. Another example of how you can reuse code is through the use of base classes that provide functionality that is common to a set of potentially derived classes.

I recently presented a course on best practices for Object Oriented Design at my company and ran across a very cool tool that was mentioned in a Pluralsight course by Steve Smith. The tool is Atomiq by goldfinch. It is a completely free tool that they make available (self-admitedly) to drum up business for their static analysis tool, Nitriq. Atomiq searches your code and finds code duplication and similarities. It provides statistics and easy way to navigate to duplications within the code. It provides a very nifty graphic to show where duplicates are and it even has a command line EXE for which a threshold can be set for use with a continuous integration builder (very cool!).

I decided to test drive Atomiq using some old code to which I had access. I knew this code would give Atomiq a run for its money as this code has been around for a decade and has been touched and tweaked and, well, defiled by many developers. After letting Atomiq analyze the entire project, this is the wheel graphic that was generated by Atomiq:

Wheel Output From Atomiq For Solution with Lots of Repetition

Wheel Output From Atomiq For Solution with Lots of Repetition – (Class Names Removed to Protect the Innocent)

As I suspected, Atomiq found many sources of repetition in this solution. Each line crossing this Spirograph looking picture represents an opportunity to refactor this code such that the repetition goes down and the maintainability goes up.

I had another project where I was playing around prototyping a couple ICommand objects for use in ESRI’s ArcMap. In this project, the two commands were generated using the ArcMap ICommand generation tool in Microsoft Visual Studio. Because the classes were auto-generated, the same base code was added to each. For example, this code (along with a few other lines) was auto-generated into both classes:

C#
#region COM Registration Function(s)
[ComRegisterFunction]
[ComVisible(false)]
static void RegisterFunction(Type registerType)
{
    // Required for ArcGIS Component Category Registrar support
    ArcGisCategoryRegistration(registerType);
}

[ComUnregisterFunction]
[ComVisible(false)]
static void UnregisterFunction(Type registerType)
{
    // Required for ArcGIS Component Category Registrar support
    ArcGisCategoryUnregistration(registerType);
}
#endregion

This duplicated code caused Atomiq to (rightly) generate this graph:

Atomiq Output Because of Duplicate Auto-Generated ICommand Template Code

Atomiq Output Because of Duplicate Auto-Generated ICommand Template Code

For this particular duplication, Atomiq found 65 lines that were similar. Also, Atomiq showed this similarity view, that showed the same code side-by-side:

Atomiq Similarity View Showing ESRI ICommand Boilerplate

Atomiq Similarity View Showing ESRI ICommand Boilerplate

This is one example where Atomiq shows a great place to do some refactoring. By pulling all of the ESRI ArcMap boilerplate code into a base class, we can move all of this duplicate code to one place and then create derived classes from this base class. For this example, I just started by refactoring out a part of the similar code, as shown here:

C#
using ESRI.ArcGIS.ADF.BaseClasses

// Base class from which all other ESRI ICommands should be derived for code reuse

[ComVisible(true)]
public abstract class MyBaseCommand : BaseCommand
{
    [ComRegisterFunction]
    [ComVisible(false)]
    static void RegisterFunction(Type registerType)
    {
        // Required for ArcGIS Component Category Registrar support
        ArcGisCategoryRegistration(registerType);
    }

    [ComUnregisterFunction]
    [ComVisible(false)]
    static void UnregisterFunction(Type registerType)
    {
        // Required for ArcGIS Component Category Registrar support
        ArcGisCategoryUnregistration(registerType);
    }

    // Move other common ICommand code here

}

After reanalyzing the code, the 65 similar lines dropped to 55:

After refactoring - Duplicate Lines Dropped from 65 to 55

After refactoring – Duplicate Lines Dropped from 65 to 55

By iterating in this same fashion, Atomiq can help to eliminate duplications and make this code more maintainable.

While there is no silver bullet, Atomiq is a very good (and very free) tool to use in making sure that you write code that complies with the DRY principle. When coupled with the command line version for a continuous integration builder, this is a great way to improve code quality.

 

This article was originally posted at http://www.keithholloway.net/blog/staying-dry-with-atomiq

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
United States United States
I'm a learner/coder/leader who is curious about how technologies and people work together to solve interesting problems. I have a passion for software and doing what I can to improve the lives of the people who create and use it.

Comments and Discussions

 
-- There are no messages in this forum --