Tag: refactoring

Refactoring For Interfaces: An Adventure From The Trenches

puzzle

Refactoring: Some Background

If you’re a seasoned programmer you know all about refactoring. If you’re relatively new to programming, you probably have heard of refactoring but don’t have that much experience actually doing it. After all, it’s easier to just rewrite things from scratch instead of trying to make a huge design change part way through, right? In any mature software project, it’s often the case where you’ll get to a point where your code base in its current state cannot properly sustain large changes going forward. It’s not really anyone’s fault–it’s totally natural. It’s impossible to plan absolutely everything that comes up, so it’s probable that at some point at least part of your software project will face refactoring.

In my real life example, I was tasked with refactoring a software project that has a single owner. I’m close with the owner and they’re a very technical person, but they’re also not a programmer. Because I’m not physically near the owner (and I have a full-time job, among other things I’m doing) it’s often difficult to debug any problems that come up. The owner can’t simply open an editor and get down to the code to fix things up.

So there was an obvious solution which I avoided in the first place… Unit tests. Duh. I need unit tests. So that’s an easy solution right? I’ll bust out my favourite testing framework (I’m a fan of xUnit) and start getting some solid code coverage. Well… in an ideal world, like every programming article is ever written, this would have been the case. But that wasn’t the case. My software project does a lot of direct HTTP/FTP requests and interacts with particular hardware on the machine. How awesome is writing a unit test that contacts an HTTP server? Not very awesome.

What was I to do? I need to be able to write unit tests so that I can validate my software before putting it in my customer’s hands, but I can’t test it with unit tests because I don’t have the hardware!

Refactoring for Interfaces

Okay, so the first step in my master plan is to refactor for interfaces. What do I mean by that? Well, I have a lot of code that will call out and make HTTP requests and it has a specific dependency on System.Net.WebRequest. The same thing holds true for my FTP requests I want to make. Because I have that dependency within my classes, it means I have no choice but to call out to the network and go do these things.

I could design it a different way though. What if I abstracted the web requests away so that I didn’t actually have to call that class directly? What if I could have a reference to some instance that met some API that would just do that stuff for me? I mean, my class knows all about it’s on particular job, but it truthfully doesn’t know the first thing about calling out to the Internet to go post some HTTP requests. This means if someone else is responsible for providing me with a mechanism for giving me the ability to post HTTP requests, this other entity could also fool me and not actually send out HTTP requests at all! That sounds like exactly what my test framework would want to do.

My first step was to look at the properties and methods I was using on the WebRequest class. What was shared between the HTTP and FTP requests that I was creating? The few things I had to consider were:

  • Some sort of Send() method to actually send the request
  • A URI to identify where the request is being sent
  • A timeout property

I then created an interface for a web request that had these properties/methods accessible and created some wrapper classes that implemented this interface but encapsulated the functionality of the underlying web requests. The next step was creating a class and interface for a “factory” that could create these requests. This is because my code that needs to make HTTP/FTP requests only knows it needs to make those requests–It doesn’t have any knowledge on how to actually create one.

With my interfaces for my requests and my factory that creates them, I was able to move onto the next step.

Create Mocks for the Interfaces

Now that I had my classes leveraging interfaces instead of concrete classes internally, I could mock the inner-workings of my classes. This would provide two major benefits:

  • I could create tests that wouldn’t have to actually go out to the Internet/network.
  • I could create instrumented mocks that would let me test whether certain web requests were being made.

I started off my writing up some unit tests. I tried to get as much code coverage as I could by doing simple tests (i.e. create an object, check default values, call a method and check a result, etc…). Once I had exhausted a lot of the simple stuff, I targeted the other areas that I wasn’t hitting. I mean, how was my coded test supposed to test my method that does an HTTP request and an FTP of a file under the hood? Mocks.

So this is where you probably draw the line between your integration tests or unit tests and get all pedantic about it. But I don’t care how you want to separate it: I need coded tests that cover a section of my class so that I can ensure it behaves as I expect. But if I’m mocking my dependencies, how do I know my class is actually doing what I expect?

Instrument your mocks! This was totally cool for me to play around with for the first time. I had to create dummy FTP/HTTP requests that met the interface my class under test expected. Pretty easy. But I could actually assert what requests my class under test was actually trying to send out! This meant that if my method was supposed to try and hit a certain URL, I could assert that easily by instrumenting my mocked instance to check just that. Was it supposed to FTP a certain set of bytes? No problem. Use my mocked instance to assert those bytes are actually the ones my class under test is trying to send.

Wrap Up

This was just a general post, and I didn’t put up any code to go along with it. Sorry. I really just wanted to cover my experience with refactoring, interfaces, mocking, and code coverage because it was a great learning for me.

To recap on what I said in this post:

  • Identify the parts you want to mock. These are the things your class or method probably isn’t responsible for creating directly. Going out to the network? Accessing the disk? Accessing the environment your test is running under? Creating complex concrete classes because they hook into some other system for you? Great candidates for this.
  • Create interfaces by looking at the API you’re accessing. You know what classes you want to mock, so look how you’re using the API. If you need to access a few properties and methods, then make that part of your interface. If you see commonality between a few similar things, you might be able to create a single interface to handle all of the scenarios.
  • Inject factories that can create instances for you. These factories know how to create the concrete classes that meet your interfaces. In a real situation, they can create the classes you expect. In a test environment, they can create your mocks.
  • Write coded tests with your mocks! The last part is the most fun. You can finally inject some mocked classes into your classes/methods under test and then instrument them to ensure your code under test is accessing them in the way you expect. Run some code coverage tools after to prove you’re doing a good job.

I hope my experiences down this path are able to help you out!


Be a Better Programmer – Weekly Article Dump

Be a Better Programmer - Weekly Article Dump (Image by http://www.sxc.hu/)

Be a Better Programmer

It’s a new year and that means it’s all about resolutions, right? Well, I’m not a huge fan of keeping around a resolution that needs to wait for a new year, but I am a fan of reflecting on your goals and your skills. If you’re a programmer like me, then maybe this will be a great starting point. In my weekly article dumps I usually would just provide a couple of comments on a link like this, but I felt I should dive in a little bit more. You can find the original article by Amy Jollymore over here. Please have a look! I shared it with the whole dev team at Magnet Forensics because I felt there was a little bit of something for everyone.

Number one on this list, and perhaps the one I’d personally like to focus on more out of this list, is checking your code before blaming others. Blaming other people–in general, not just programming–is an easy way out. When a problem occurs, it’s simple to assume that all of your work is right and that it must be someone else’s fault. But if everyone starts thinking like this, it turns into a nasty blame war. So next time the build breaks or your shiny new feature stops working as expected, don’t go blaming other people. Investigate what the problem is. See what your most recent changes were and if they could have caused the problem. As you start to gain confidence that your changes aren’t responsible for the issue, try sitting down with one or two other people you think might have been around the problem area recently–But don’t go accusing them! Putting your heads together to figure out the problem can speed up the process and might even shed some light on some miscommunication over a design or some assumptions in the code that don’t actually hold true. It’s a lot more embarrassing to blame someone when it’s actually your fault compared to putting in the effort and admitting you might have goofed up. Try it out!

Number two is also a great item. You should never put an end to your learning… especially as an individual in a technology space. There are so many great suggestions listed for this point that there’s no point in me repeating them. Just go read them! An interesting point worth mentioning is using podcasts for learning. This is a great option if you find you’re brain is still spinning when you lay down in bed or if you have a long commute to work (or something else you’re involved in). The author also mentions that you don’t need to be learning programming… What about domain expertise? If you’re writing code for banks, lawyers, or digital forensics… Why  not learn about that too?!

The last point I’ll touch on from the article is number three: don’t be afraid to break things. I love this point. If you’re working on a big piece of software, there are almost certainly areas that seem brittle, scary, or just plain incomprehensible. If your project is still small, it very well get to this point. It doesn’t mean that the code is bad or that you’re working with the worst programmers… It’s just something that happens when you’re continuously trying to build on your software. The real problem occurs when nobody is willing to take the time to go change things. If you have big scary brittle parts of code, then set aside some time, take a deep breath, and go refactor it! It might seem like hell at first, but once you get into it (and especially after it’s done) you’ll feel a million times better. Plus, now your code can continue to be built upon without people running in fear when you mention that section of code. Code can get nasty, but consider using a “tech debt” system or regularly set aside time for refactoring parts of your code base.

Again, the original article is located at: 7 Ways to be a Better Programmer in 2014. Check it out!

Articles

  • How to Manage Dynamic Tensions — and Master the Balancing Act: This was an interesting article on some parts of leadership that often oppose each other. Author Chris Cancialosi does an excellent job in discussing balance between internal and external influences as well as leading and managing. A good take away from this article is at least acknowledging that there are certainly some things to balance. You may want to have the most flexible team, but have you considered if there’s a “too flexible”? Just a bit of perspective that this article might bring to light.
  • A Crash Course In Leadership For 20-Something CEOs: Barry Salzberg‘s article is geared toward young CEOs, but I think that means we can apply the lessons to anyone looking to lead! A few of the points I’d like to mention include being tough on problems and not on people. Your people are the one’s who are going to solve problems and bring great ideas to the table. They’ll invest their time into your organization in order to accomplish great things–so don’t be hard on them. Instead, acknowledge that your problems and challenges are the things you want to crush, and work with your team to make sure you conquer every challenge that gets in the way of your goal. Another point is on taking risks. Never taking risks is a great way to stagnate. You need to learn from your failures, but keep pushing the boundaries. Finally, be ready to adapt. As your organization grows or as the market you’re working within evolves, you need to be ready to adapt and change. You might get lucky and things don’t change all that much over a long period of time, but the odds of that are pretty low. Be ready to adapt so when the time comes, you don’t need to worry about everything falling apart.
  • Leading at Scale with Agility: Brad Smith has a few great points on what leading a team should encompass. First, a team should have a goal that it is trying to achieve. If that team is part of a larger organization, the team’s goal should align with the goal of the entire organization. Secondly, decisions for the team should involve those on the team. It’s easy to sit back and speculate what might be best, but why not involve the people directly affected? Of course, this is more difficult for large teams but maybe that’s an indication your teams would be more effective if they were smaller. Next, empower teams to arrive at solutions on their own. If a plan worked out well, try communicating it to others to try out. Conversely, if the plan had some problems, let others on the team (or other teams) know about the hurdles. Finally, Brad has a point on trust. Trust is arguably one of the most important parts of leading a team. Each team member needs to be able to trust the others. There should be an easy assumption that everyone is operating with best intentions.
  • For Leaders, Today is History: In this article by Steven Thompson, he gives a high-level overview of his focus. Specifically, he focuses on the future and not right now. Steven says the teams he is in charge of are often looking at the problems of “right now” and perhaps a little bit in the future. It would be counter productive for him to try and butt-in to try helping with those problems because he’s so far removed from them. Instead, those individuals have been empowered to focus on those problems. Instead, Steven focuses on the future–the direction of the teams. As a leader, it’s important to try and be thinking at least one step ahead.
  • What If You Had to Write a “User Manual” About Your Leadership Style?: After I read Adam Bryant‘s article, I thought the idea of a leadership “user manual” would be pretty cool. Even if there isn’t a single other individual who would benefit from it, at least it would help reveal to myself some of my leadership quirks. That’s useful on it’s own! I’ll be sure to post up my leadership “user manual” when I have it complete… and I imagine I’ll have to keep updating it over time as my style evolves. It’ll be really interesting to see the evolution of my leadership style! Why not consider doing one for yourself?
  • What Bosses Should Never Ask Employees to Do: Jeff Haden‘s article was a little bit controversial in my opinion–and in the opinion of some of the commenters. I think I get the underlying message behind a lot of what Jeff is saying for each of his points, but as one commenter said, it sounds like a bit of a personal complaint the whole way through. Consider the topic of donating to charities at work. The feel I get after reading that segment is that your organization should not attempt to do fundraising through employees. While I don’t actually think that’s what Jeff is saying, that’s how I feel after reading it. I know that we’ve been able to do several charity events at Magnet, and we’ve always said that they are completely voluntary. I think that’s the crucial part. It’s the holiday season and your budget is a bit tight? How could anyone get mad at you for backing out of a completely optional charity donation? Busy with some personal matters or want to focus on finishing up something at work the day we’re doing a charity event? No big deal, it’s optional. Anyway, the point is that perhaps based on the wording in the article, I felt like some of the messaging will be misinterpreted. I think there are some good points buried in there. Check it out and let me know if you agree or not!

Follow Dev Leader on social media outlets to get these updates through the week. Thanks!


Charity Water – Weekly Article Dump

My 24th Birthday Wish - Charity: Water

Charity Water

We have a lot of pretty awesome people at Magnet Forensics, and every day I’m reminded just how awesome. A colleague of mine, Danielle Braun, had what I thought was an incredible idea for her birthday. For Danielle’s birthday, she’s not asking for more new clothes, for her parents to get her a car, for help with paying off tuition, or for some new fancy tech gadgets. But she’s not asking for nothing. Danielle is asking for your support with Charity: Water this year.

Charity: Water is a non-profit organization with the goal of bringing clean water to people in developing nations that don’t have access to it. Reading their mission page probably opens your eyes a fair bit about the lack of access to drinking water in other countries. They’re not about some complex and elaborate plan to revolutionize access to clean drinking water. However, they do have a simple and straight forward approach. Donate a little bit of money and they can install wells, rain catchments, and filters in areas without access to clean water. Your small contribution can make a huge impact on other peoples’ lives.

Please consider helping Danielle out with her goal of raising money for clean drinking water. A little bit goes a long way with Charity: Water.

Articles

  • Guest Post: 7 Deadly Sins: How to Successfully “Cross The Chasm” By Avoiding These Mistakes: In Geoffrey Moore’s article, we get to revisit some of the great learnings in Crossing the Chasm. If you haven’t read the book, although it’s a bit old now, it’s still a solid read. This post was a great reminder of a lot of the things the book talks about. It’s important to know where your business sits in the chasm model so that you know what you should be focusing on. Too many companies focus on the right things at the wrong times and have terrible missteps. Check it out (and the original book too)!
  • Holiday Gifts EVERY Employee Secretly Wants: Dharmesh Shah is a guy who always seems to have an awesome perspective to share. There are a few things that despite someone’s level of performance, length of employment, or amount of skill should be deserved.  Often these are overlooked either by grumpy managers or because perhaps the person may not have been a top performer. In Dharmesh’s opinion, that shouldn’t be a factor. The holidays are a perfect time to remind ourselves to recognize all of our employees’ accomplishments and treat them with respect. If you aren’t already, maybe this article is the little wake-up call you need.
  • 6 Things Really Thoughtful Leaders Do: Nothing groundbreaking here, but like the article says, this time of year is great for reflecting. Do you consider yourself a thoughtful leader? Do you observe the people around you, how they interact, and how things are flowing at work? Do you take the time to reflect on things you’ve done, how you’ve acted, or even how employees may have improved in areas you’ve discussed with them? There’s a handful of great reminders in this article that I would suggest you check out!
  • 14 Code Refactoring smells you can easily sense and What you can do about it?:  This week’s first programming article! Except… Well… This one is about the management side of programming. How do you know if your software team’s code is in a real stinky spot? This doesn’t necessarily mean your developers write bad code. It could just mean that you need to hit the brakes a bit and go revisit some problem areas in the code. This article talks about some of the warning signs.
  • What Makes A Good Manager? 7 Things To Ask Before You Promote: Does it make sense to give anyone you’re promoting a management position? Probably not. Seems obvious when you ask it like that, right? The unfortunate truth is that a lot of companies take the simple path and for anyone they want to promote, they throw a management position their way. Some people just don’t make great managers. This article talks about the qualities you want to look for in managers. Maybe the person you’re looking to promote won’t make a good manager *now*, but if it’s something they can put time and effort into building the skills and experience towards, it could still happen.
  • 10 Major Causes for Failure in Leadership: While lists of things to do are always nice, having a list of things to definitely not do is also helpful. Here’s one of them. Some of the leadership-don’ts I liked on this list were being too good to serve your followers, using your “authority”, and fear of competition. I think those are a few that are easy for people to forget, and there at the top of my list of leadership-don’ts. Read some more great points in the article!

Please take some time to help Danielle out with her goal. Any contribution helps. Remember to follow Dev Leader on social media outlets to get these updates through the week. Thanks!

Nick Cosentino – LinkedIn
Nick Cosentino – Twitter
Dev Leader – Facebook
Dev Leader – Google+
Nick’s CodeProject Articles


How and Why to Avoid Excessive Nesting

Background

This probably sounds really nit-picky or OCD, but I think it’s an issue worth addressing. Excessive nesting of logic within code can make things nightmarish to read. Even a few of years ago I never thought anything of this. I mean, how much could it really affect someone reading it? He/she must be a complete newb to not be able to read my logic. Fast forward to a co-op placement where this was more closely moderated by my managers, and I began to pay more attention to it…

Why?

Alright, so all that you know so far about my opinion on this is that excessive nesting bothers me. So far, my mission is accomplished. Everything else is just extra. The first issue with excessive nesting is that it actually makes logic hard to follow. If you’re doing code reviews or revisiting your old code, large methods that have lots of nested if statements and loops actually become a tangled mess of logical workflows. You don’t need to believe me yet, but I’m hoping by the end of this you might change your mind.

The next thing, and it’s related, is that it makes refactoring code quite tricky. If you have lot’s of deeply nested if statements, switching up the behaviour of a function even a little bit could have your mind warping with how to tackle all the logical branches. Have fun. Remember that one monolithic function that nobody wanted to go back and refactor? Well, it turns out you need to pass in another parameter now and handle it in all of your separate logical paths. Hold back the tears when you’re trying to recall the logic once you’re 10+ levels deep into nested if statements.

Another key point I’d like to mention is that, in my opinion, the larger the vertical separation between a conditional check and it’s bodies (i.e. the if block and the else block) the more difficult it becomes to read the code. Of course, this may not be a law or an all-the-time thing, but it’s certainly a decent guideline. Think about it though. If you have an enormous block of code for your if statement body, by the time you finish understanding that, you have to go back up to the if statement condition and invert the whole thing to beign to understand what your else block does.

The Offender

Let’s have a look at some real offensive code. Who knows what it does really… Well, nobody does. Why? Because it’s completely contrived to illustrate my point. And that’s that. Behold the horror!

        private void DoStuff()
        {
            foreach (thing in thisList)
            {
                if (condition1)
                {
                    if (condition2)
                    {
                        DoThis(thing);
                    }
                    else
                    {
                        if (condition3)
                        {
                            continue;
                        }
                        else
                        {
                            if (condition4)
                            {
                                continue;
                            }
                            else
                            {
                                if (condition5)
                                {
                                    if (condition6)
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        if (condition7)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            if (condition8)
                                            {
                                                DoThis(thing);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    DoThis(thing);
                }
            }
        }

Pretty filthy, right? In all honesty, anyone who has worked in production code is guaranteed to have seen code that nests much much deeper… veering right off the developer’s window (and some of us code with multiple monitors). It’s a scary world out there, and this example doesn’t even begin to illustrate how bad it can get. I mean, this particular example actually fit on my narrow blog window.

 

A Better Way?

Well, fixing this type of thing is nice and easy:

        private void DoStuff()
        {
            foreach (thing in thisList)
            {
                if (!condition1)
                {
                    DoThis(thing);
                    continue;
                }

                if (condition2)
                {
                    DoThis(thing);
                    continue;
                }
                
                if (condition3 || condition4 || !condition5 || condition6 || condition7)
                {
                    continue;
                }
                
                if (condition8)
                {
                    DoThis(thing);
                }
            }
        }

That’s so much prettier. So what’d I do there? A handful of techniques:

  • Invert logical blocks if they can reduce your nesting. For condition1, I had an if/else block where DoThis(thing) resided in the bottom else block… farrrrr farrrr away from the check itself. I simply inverted this check and moved the else block up. Of course, I then had to put a continue statement there to go back up to the next iteration.
  • For condition2, by simply placing a continue right after the method call in the body, I was able to completely eliminate the else block and reduce nesting by a whole level. This works well with if/else blocks with returns too.
  • Next up was a whole pile of combinations for checking when I’m not going to be calling DoThis(thing). That reduced nesting by a bajillion levels, approximately.
  • The final block there for condition8 was still necessary. Of course, it could have be written to be the inverse check (so, if NOT condition8) with a continue inside the block, followed by DoThis(thing) outside of the if block. To me this would have been a bit overkill.

 

Did You Catch That?

Something extremely important to remember when changing logical flows like this is that the order you check your conditions is EXTREMELY important. Notice how in my refactored version the condition checks are still in the same order that they originally appeared? This is on purpose.
Consider if I move condition8 up to the if statement that tests condition1 and say if NOT condition1, OR condition8. Now this is technically not equivalent to the initial implementation. Why? Because the initial implementation says that for one of the logical paths that call DoThis(thing) the following must be met:
  • condition1 = true
  • conditon2 = false
  • conditon3 = false
  • condition4 = false
  • condition5 = true
  • conditon6 = false
  • condition7 = false
  • condition8 = true

Thus, by combining the condition8 check with the condition1 check, how have I guaranteed all those other conditions?  Additionally, how do I know that skipping those condition checks (i.e. pretend they are method calls) has not altered state elsewhere in the class? This optimization actually may not make the code incorrect in certain situations (because it really depends what those conditions are), but it’s important to note that the checks would not be equivalent to the original. It’s just something to pay attention to, but who knows, you may even find that you can optimize some of those checks away depending on your situation!

 

Summary

Don’t excessively nest your code because it makes me cry at night.

  • Nick Cosentino

    Nick Cosentino

    I work as a team lead of software engineering at Magnet Forensics (http://www.magnetforensics.com). I'm into powerlifting, bodybuilding, and blogging about leadership/development topics over at http://www.devleader.ca.

    Verified Services

    View Full Profile →

  • Copyright © 1996-2010 Dev Leader. All rights reserved.
    Jarrah theme by Templates Next | Powered by WordPress