Annyce Davis

Davis Technology Consulting

  • Home
  • About Me
  • Blog
  • Courses
  • Newsletter

Frustration-Free Code Reviews

September 5, 2018 by Annyce Davis

#wocintechchat

Hopefully, code reviews are already a part of your software development process. They should be a collaborative, non-judgemental tool for improving code quality and decreasing knowledge silos. Yet instead, they often serve as a source of frustration and fear. But why?

Well, if this was a play we’d have the following parts:

  • The code
  • The Author
  • The Author’s Ego
  • The Reviewer
  • The Reviewer’s Ego

As you can imagine bringing this cast of characters together can be a challenge! Especially since we want to do so in a way that results in high-quality software. Thus we need a plan, just like any good play has a well-written script.

Let’s look at the following areas and how they contribute to a frustration-free code review:

  • Goals
  • Pull Requests
  • CI Integration
  • Giving Comments
  • Responding to Comments

Continue Reading

Talk: Developing Maintainable Apps

August 28, 2015 by Annyce Davis

Great Android apps only include what’s needed to achieve the goals of the product, not enhance the resume of the developer. What’s more, the more maintainable an application is, the more likely it will have increased user satisfaction and decreased time to market.


So how can you do it?  Keep these four factors in mind:

  1. Choose your 3rd Party Components Wisely
  2. Keep your Code Simple
  3. Use Static Code Analysis Tools
  4. Write Unit Tests

Resources:

  • Clean Code – http://amzn.to/1DJybxH
  • Effective Java –http://amzn.to/1Ku8Xel
  • Working Effectively with Legacy Code – http://amzn.to/1Jqe1PA
  • Unit Testing Idioms – http://goo.gl/Bx1WbL
  • Google Code Style – http://goo.gl/8Pf6J3
  • Architecting Android – http://goo.gl/UKvmbq
  • Conquering Cyclomatic Complexity – http://goo.gl/lRoPXN

Conquering Cyclomatic Complexity

July 7, 2015 by Annyce Davis

Have you ever received a warning about Cyclomatic Complexity while working with a class in Android Studio? Would you like to know how to fix it?  If yes, keep reading…

What is cyclomatic complexity?


Here is a definition from Wikipedia:

“The cyclomatic complexity of a section of source code is the number of linearly independent paths within it. For instance, if the source code contained no control flow statements (conditionals or decision points), such as IF statements, the complexity would be 1, since there is only a single path through the code.” — Wikipedia

Ok, so that particular definition is a tad verbose, but it’s essentially saying that the more control structures (if, else, switch, etc.)  you have in your code the more you introduce complexity into your program.

Why is high cyclomatic complexity bad?


Short answer, it can make it more difficult to write unit tests that cover all possible branches of a given function as well as hinder debugging efforts. Others argue that it affects the readability of your code, making it more challenging for another developer to understand the intent of your functions and/or classes.

How do you fix it?


You start by reducing the number of paths through any given function.  Let’s take a look at a very contrived example.

public void overlyComplexMethod(Video video) {
    if (video != null && video.getStreamUrl() != null) {
        switch (video.getCategory()) {
            case "CAT1" :
                playVideo(video);
                if (video.getLargeImageUrl() == null) {
                    video.setLargeImageUrl("http://www.largeImage.png");
                }
                updateMetadata(video);
                break;
            case "CAT2" :
                if (video.getLargeImageUrl() == null) {
                    video.setLargeImageUrl("http://www.smallImage.png");
                }
                updateMetadata(video);
                break;
            case "CAT3" :
                if (video.getLargeImageUrl() == null) {
                    video.setLargeImageUrl("http://www.mediumImage.png");
                }
                updateMetadata(video);
                break;
            default:
                break;
        }
    }
}


This function has several different paths through it, notice the use of a switch statement with several cases and within the cases more if statements. The cyclomatic complexity of this method is 9, ideally you would want to have most functions with a value of 8 or less.  So let’s clean it up!

First we’re going to move the switch statement into its own method.

public void overlyComplexMethod(Video video) {
    if (video != null && video.getStreamUrl() != null) {
        updateVideoBasedOnCategory(video);
    }
}

private void updateVideoBasedOnCategory(Video video) {
    switch (video.getCategory()) {
        case "CAT1" :
            playVideo(video);
            if (video.getLargeImageUrl() == null) {
                video.setLargeImageUrl("http://www.largeImage.png");
            }
            updateMetadata(video);
            break;
         case "CAT2" :
            if (video.getLargeImageUrl() == null) {
                video.setLargeImageUrl("http://www.smallImage.png");
            }
            updateMetadata(video);
            break;
         case "CAT3" :
            if (video.getLargeImageUrl() == null) {
                video.setLargeImageUrl("http://www.mediumImage.png");
            }
            updateMetadata(video);
            break;
          default:
            break;
    }
}


By making this simple change we’ve already reduced the complexity down to a value of 7. The next step would be to look for code duplication among the case statements and then create one method that they can all share.  Let’s see how that might look…

public void overlyComplexMethod(Video video) {
    if (video != null && video.getStreamUrl() != null) {
        updateVideoBasedOnCategory(video);
    }
}

private void updateVideoBasedOnCategory(Video video) {
    switch (video.getCategory()) {
        case "CAT1" :
            playVideo(video);
            updateVideoMetaDataAndUrl(video, "http://www.largeImage.png");
            break;
        case "CAT2" :
            updateVideoMetaDataAndUrl(video, "http://www.smallImage.png");
            break;
        case "CAT3" :
            updateVideoMetaDataAndUrl(video, "http://www.mediumImage.png");
            break;
        default:
            break;
    }
}

private void updateVideoMetaDataAndUrl(Video video, String url) {
    video.setLargeImageUrl(url);
    updateMetadata(video);
}

Now by extracting out this common method, updateVideoMetaDataAndUrl, we have reduced the cyclomatic complexity to 4. We could reduce this further by eliminating the need for a switch statement with polymorphism.  I leave that to you as an exercise.

Conclusion


As we can see it’s a simple refactoring effort to reduce the cyclomatic complexity of methods and by extension classes.  I would however like to mention that having unit tests in place before you begin the refactoring is ideal to ensure you don’t make any breaking changes.

If you want to learn more about writing clean code, I highly recommend the book Clean Code by Robert Martin. 

Follow Me

  • Bluesky

Categories

  • Android (60)
  • Career (5)
  • Communication (4)
  • Flutter (1)
  • Git (4)
  • Gradle (4)
  • Grails (23)
  • iOS (1)
  • Java (8)
  • JavaScript (6)
  • Kotlin (17)
  • Life (5)
  • Public Speaking (26)
  • Revenue (2)
  • RxJava (1)
  • Software Development (13)
  • Twitter (3)
  • Uncategorized (11)
  • Video Course (5)

Follow Me

  • Bluesky

Copyright © 2025 · All Rights Reserved · Log in

 

Loading Comments...