Tag: Software Development

What Makes Good Code? – Patterns and Practices Series

What Makes Good Code?

It’s been a while since I’ve had a programming oriented post, and I figured this would be a great topic to write about. It’s been a topic I’ve been thinking about more and more over the last year and I’ve been experimenting with certain patterns and practices to see if certain things actually make code “better”. A lot of the information presented in this series will be completely based on my opinion, but I’ll try to back up my opinion with as many concrete examples as I can. If you have a differing opinion, I’d love to hear it in the comments.

I’d also like to call out that much of what I’ll be discussing is in the context of object oriented programming. To be specific, there may be mostly C# examples used. If this isn’t something you’re actively doing, then don’t worry! It would be great to hear if you see parallels in the work you’re doing.

What Is “Good”?

So let’s start by defining what “good” or “better” means (and I’ll leave this high level and we can dive in afterwards)…

  • Extensible: Re-writing of code is minimized when adding more functionality. It feels straight forward to extend the code. Developers won’t do “the wrong thing” when trying to extend the code.
  • Maintainable: Many of the same qualities that go with extensible. Fixing bugs or making tweaks involves touching few places in the code base.
  • Testable: It’s straight forward to write coded tests that can exercise functionality of the code under test.
  • Readable**:  Developers should be able to read code and understand what it’s doing. The flow of execution within and between different modules of code shouldn’t cause anyone a headache,

All of these describe qualities of the code. I could argue that you could write very maintainable, extensible, and testable code and it would be awful if it didn’t actually solve the customers’ needs. I’d like to try and leave this aspect out of the discussion, and focus on the actual patterns/practices that we can implement in code. I’d love to write something separate about writing code that actually solves a problem versus code that may potentially solve some possible problem at some potential point in the future (and yes, all of the uncertainty in that sentence was on purpose).

Why Should We Care?

It’s kind of a funny question, I guess, but I think it’s a fair one to ask. Why should we care what good code is? If we agree on the definition of good code, so what? Maybe those criteria for good code are obvious to some people. Maybe they weren’t so obvious to some people, but they still don’t really care. So why the fuss about what good code is?

If you’ve read other posts on DevLeader or you know me personally, you may know that I started work at a digital forensics startup a few years back in Waterloo Ontario. What you may not know is that that startup has grown significantly, and based on the accolades we’ve received as an entire organization, we’re actually one of the fastest growing software companies in North America in terms of revenue. I’m not trying to do the horn tooting without a reason though… I think one of the reasons we’ve been able to have such great success on the development side of things is because we’re always trying to improve.

We didn’t always write “good” code, and we certainly don’t always write “good” code right now. However, we’re always trying to figure out how we can get better. So why might WE care as developers at our office? I think it comes down to trade-offs.

In the real world of software development, you’re often faced with trade-offs. You can get a product out faster if you don’t test it. Or you can get a product out and test it, but maybe you had to take a lot of shortcuts in the code. Or maybe you can get all the features in the product and tested, but you can’t hit the deadline. There’s countless more combinations of trade-offs that we make in real software development every day. I think that by understanding what “good” code means allows a team to recognize just what kinds of corners they’re cutting sometimes. When teams talk about introducing “tech debt”, there’s a better grasp around what type of debt you’re introducing. If you need to get some extra features and bug fixes in but they’re getting added with some tech debt, what could that end up meaning?

Even if you don’t agree with what my criteria are for good code, I think it’s important that you establish this within your team. If everyone can agree on what good code is, it makes constructive conversations about different implementations much easier. Just because some new code is different doesn’t instantaneously make it scary and/or wrong… Maybe it’s a new way that emphasizes one of the criteria for good code a bit more than another implementation might emphasize. Perhaps it doesn’t… You can at least refer back to a reference point for what “good” is.

It’s also important to recognize that the criteria for “good” may change over time. Revisiting the definition periodically might allow you to recognize when your team is redefining what “good” means to them.

Enough Rambling! Where’s This Going?

Right. Okay. I want to write some follow up posts that will focus on a few of the following items:

  • Does every class need an interface?
  • Does every class need a factory that can create it?
  • Unit tests versus functional tests
  • Is there a benefit to only passing interfaces to objects around?
  • Is there a way to enforce that interfaces HAVE to be passed around?
  • Is the single responsibility principle even helpful?
  • Mutability and immutability
  • Is it always good to follow patterns and practices in all scenarios?

And after I feel that I’ve covered enough on these topics, I’d like to circle back and revisit what “good” code is. It’ll be cool to see if the definition changes at all!

**Readability was an after thought and I’m not sure how… I started writing the first example post for this series and QUICKLY realized I had omitted this.


Should My Method Do This? Should My Class?

Whose Job Is It?

I wanted to share my experience that I had working on a recent project. If you’ve been programming for a while, you’ve definitely heard of the single responsibility principle. If you’re new to programming, maybe this is news. The principle states:

That every class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class

You could extend this concept to apply to not only classes, but methods as well. Should you have that one method that is entirely responsible for creating a database connection, connecting to a web service, downloading data, updating the database, uploading some data, and then doing some user interface rendering? What would you even call that?!

The idea is really this: break down your code into separate pieces of functionality.

Easier Said Than Done… Or Is It?

The idea seems easy, right? Then why is it that people keep writing code that doesn’t follow this guideline? I’m guessing it’s because even though it’s an easy rule, it’s even easier to just… code what works.

The recent experience I wanted to share was my work on a project that has a pretty short time frame to prove it was feasible. It was starting something from scratch, so I had all the flexibility in the world to design code however I wanted to. I really made an effort to keep asking myself this one question: Whose job is it?

Every time I asked that question and found that it was not my current method’s responsibility, I would ask “Is this class really responsible for that”? I’d either go make myself a new method in my class or I’d just go immediately make a new class with a single method on it. It seemed like a bit of extra overhead each time I had to do it, but was it worth it in the end?

Absolutely. After the project had proven itself and development continued on, I was easily able to refactor code (where necessary) and mock out functionality in my coded tests. Instead of trying to write test setup code that required a whack of classes I needed to initialize, I could mock out a couple of interfaces and test with ease. It was also really obvious which pieces were responsible for what functionality.

Final Thoughts

If you want to get better at following the single responsibility principle, I think it starts with one question: Whose job is it? Try it out!


Leadership: What Does It Mean? – Weekly Article Dump

Leadership: What Does It Mean? - Weekly Article Dump

Leadership

Everyone has their own variation of what leadership means. For me, leadership means empowering others to accomplish their goals and providing assistance when they need it. There were a few articles that came up on LinkedIn this week that I wanted to share with everyone and discuss how they fit into my perspective on leadership.

Articles

  • Does Your Team Work With You Or For You?Kwame Manu-Antwi opens up the article in an interesting fashion. When I read the title of the article, I figured this was going to be the typical leadership vs management debate. However, Kwame goes into describing a scenario where he had a humbling experience from one of his team that made some sacrifices for him. This was truly an example of working for him.

    The entire second half of the article shares a bunch of leadership traits that I think are really beneficial.  For example, being transparent and encouraging growth in your team members. I think the point that is being made in this article, although I don’t personally feel like it was made as obvious as it could have been, is that as a leader, if you want to feel like your team is willing to make sacrifices (for you, or for the team) then practicing being an excellent leader is the way to get there. Thus, the tips he provides to do so!I’d say there’s a lot of takeaway in his bulleted leadership points.

    If you’re an experienced leader then it’s probably mostly stuff you’ve heard before. However, it never hurts to be reminded of great leadership responsibilities!

  • How Do I Hire A Good Employee: Insights on Leadership Traits: In this article Kendall Matthews talks about the specific things he looks for when interviewing. It’s not about how picking the smartest person in the world or the most skilled person according to Kendall. It’s all about finding people that have that curious drive that can think on their feet. Have you given into the status quo?

    When it comes to leadership and hiring, your responsible for building out a well rounded team. In my opinion sometimes this will require hiring the smartest or most skilled person, but more often than not, you’re just looking for go getters. People that are curious by nature and always looking to push the boundaries make great candidates for your team because they’re adaptable. This means you don’t need to go finding someone with the perfect skill set because you can hire the person that’s willing to evolve into that person.

    Again, it’s not a blanket rule in my perspective. Sometimes your team will require that super-skilled person to be up and running from day one. Being a good leader in charge of hiring requires you to understand your teams needs though.

  • Can Skipping a Meeting Make You a Better Leader?: I find that Ilya Pozin always has some interesting articles up on LinkedIn. If you don’t follow him yet, I suggest you do! This article is all about shaking things up to align them to your leadership strategy (and not just accepting meeting invites and then not showing up).The first part of the article is really about taking charge of your daily routine. If you get into work and your ready to make a big dent in your todo list, then moving meetings until later in the day might have a huge  benefit. Similarly, it helps you plan out and prioritize the rest of your day. For me, I plan the night before and since I’m still largely a developer, I find that if I have meetings in the middle of the day when I’m in my groove then that’s when I have the biggest problems. Try tweaking when your meetings are to suit your leadership style.

    The second part of this article talks about the idea of a devil’s advocate and is personally my favourite part. I can’t stress enough how important healthy debate is for continuously improving. I had a colleague the other day say that he doesn’t like how often he hears “because it’s always been that way”. I jokingly responded, “because we’ve always said that”! But the point is, he’s not sticking to the status quo and doesn’t want to settle. I had another colleague argue against my perspective even more recently, and it really got me thinking about how our perspectives were different and where we might need to go next. Healthy debate is awesome. Your goal is not to put your “opponent’s” face in the dirt, but to understand their perspective as much as possible and ensure they get your perspective as much as possible.

  • Heisenberg Developers: In his article, Mike Hadlow talks about how a new (what seems to be scrum-based approach?) was introduced to a software development team and how it negatively impacted them. Mike’s argument? The process that was put in place took away autonomy from developers–they should be given free reign to implement a feature as they see fit.

    While the general consensus in the comments on his blog indicates that people agree, I actually don’t. I’m well aligned to the first two sentences in his closing paragraph (autonomy and fine grained management) being important, but I think direction is incredibly important. In an agile shop, often the customer proposes features to go into the product (and when the customer isn’t available, product owners acting on behalf of the customer propose the features) and the developers work to get them done. Maybe this wasn’t the implication of the blog post, but I don’t think it makes sense to just let developers randomly choose which of the features to work on next and decide on their own how to do it.

    What works better, in my opinion? Have product owners provide acceptance criteria for what would make the feature successful. Have software testers and software developers mull over the acceptance criteria and bounce ideas back off of the product owners. Did they think of how that would affect feature B? Do they realize it will be a support or regression testing nightmare unless feature C is in place? What’s my point? Collaboration. The article doesn’t even mention it. It’s only about how process takes away from the artistic nature of programming. I feel like people should stick to hobby programming if it’s art they want to express, but when it comes time to business, it’s about delivering rock solid features that the customer wants.

    Back to estimating and tasking out features. Why break a feature down? What’s good about doing it that way? If you hit road blocks or need to pivot, it’s great to have a part of a feature done and realize that in it’s current state it might be classified as acceptable for a deliverable. Maybe it doesn’t match the original acceptance criteria, but perhaps the pivot involves adjusting that and now it’s acceptable. Task breakdown brings insight to the people working on the feature. What’s involved in making it? How are you going to test it? How are you going to support it?

    Autonomy is important. But I think that there needs to be some level of process in place for leadership in management to have insight as to what’s taking place, and there needs to be enough autonomy for developers and testers to do their job to the best of their ability. Sometimes the time invested in collaborating is one of the best investments in your development team.

  • Why The Golden Rule SucksJoaquin Roca has an awesome article on “The Golden Rule” and why it doesn’t apply in leadership. Joaquin starts by discussing why building a diverse team is incredibly important and why you should take advantage of the tensions it can create. So why does The Golden Rule suck? Well… not everyone is like you and not everyone wants to be engaged the same way you are. Everyone is different and it’s important to adapt your ways to the person you are engaging with–especially when your team is diverse. There’s also a cool leadership quiz that he has posted at the top of the article!
  • Did I Make a Mistake in Promoting This Person?!: This article is about something that happens in the tech world all too often. Caroline Samne talks about how skilled professionals are promoted into leadership in management positions–except they don’t have any expertise in this area. I’m actually a prime example of this. I was hired on as a developer early on at Magnet Forensics, and before expanding the team, I was chosen for a leadership position without any past experience. However, like the article says, I had great mentorship through our HR manager and I was empowered to seek learning opportunities to grow in this space. The moral of the story is, just because someone is skilled at X, it doesn’t mean they’ll turn out to be a great (people) leader in this space. Leadership just doesn’t work magically like that.
  • Corporate Hackathons: Lessons LearntChristophe Spoerry‘s article is all about hackathons. It’s a great way to spur some innovation in your organization if you’re allowing it to happen naturally. He shares his learnings from past experiences such as having leaders with past experience in hackathons present and having teams and/or themes picked out ahead of time. Once the hackathon starts, you don’t want to be wasting time with logistics… You want to be participating! Discuss what the outcome of the hackathon will be. Who’s going to take ownership over what was created? How will the outcomes be shared with the other participants or the rest of the organization? Get hackin’!

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


Movember Wrap-up – Weekly Article Dump

Movember Wrap-up - Weekly Article Dump

Movember Wrap-up

At the start of December, it’s time for a lot of us to shave off our glorious Movember badges from our upper lips. This year, MoMagnets did an absolutely amazing job raising money for Movember. At the time of writing, we’re sitting at just under $2400! An incredible effort by Magnet Forensics and all of those that helped with their generous contributions.

My ‘stache didn’t quite get to where I wanted to this year. It was close, but it was another connector-less Movember for me. I was almost able to get some twisting done for some not-so-legitimate connectors. Oh well… Here’s what I ended up rocking for most of the month:

Movember Wrap-up - Nick's Final 'Stache

My final Movember creation: The Anti-Connector.

Matt Chang definitely took the lead for raising the most of all the MoMagnets members at over $700! Mica Sadler is sitting in second at just under $400. That’s nearly half the team’s total between these two beauties. We also had a very gracious contribution from our CEO that I wanted to call out. Thanks so much, Adam!

There’s still a bit of time left before donations are closed for the 2013 Movember season. We have until the 9th to get some final contributions in! If you’re feeling generous, please visit our team page and make a contribution. Every little bit helps, and we greatly appreciate it!

Articles

  • Top 5 Reasons People Love Their Jobs and How You Can Love Yours, Too: Some great points on why people love their jobs. Some of these may be pretty obvious, but it’s important to be reminded about what keeps people engaged. Among the top things: the work culture, the amazing people you get to work with, and autonomy. If you’re trying to create an awesome place to work (or if you’re looking for an awesome place to work) then these are probably things you’ll want to focus on!
  • 5 Things Zapping Your Company’s Productivity: Ilya Pozin always has some interesting articles. This article takes the perspective that some of the fancy perks or awesome processes you have in place may actually be hindering productivity. One common theme that was brought up under two separate points in this article is that sometimes people need a spot where they can work in peace. People like having an fun collaborative culture, but many personality types require some quiet time in order to buckle down.
  • Reduce Your Stress in 2 Minutes a Day: I’m not the type of person that truly believes doing one tiny thing for only a moment every day is going to have an enormous positive impact on your life. However, I do think that if you can take the time to try and do a few little things here and there, that overtime, you’re likely to have more a positive outlook. In this article, Greg McKeown shares a few tips on relaxing and trying to regain some focus. I don’t think it’s anything that’s going to be life-changing, but it never hurts to think about different ways to catch your breath.
  • Building a fast-failure-friendly firm: This was a pretty cool series of slides put together by Eric Tachibana that I thought was worth sharing. There are lot’s of articles on failing and why it’s important–especially for innovating. This series of slides provides a high level perspective on how you can approach failing… the right way!
  • Code Smells – Issue Number 3: This is an article I wrote about Code Smells. This entry talks about the use of exception handlers to guide logical flow in your code and alternatives for when your class hierarchy starts to get too many very light weight classes. As always, I’d love to get your feedback. If you have other code smells, or a different perspective on the ones that I’ve posted, please share them in the comments!
  • 5 Bad Thoughts That Will Throw You Off Track: This short little list is worth a quick read through. There are a ton of things that distract us every day, but the distractions you can easily control are the ones that you cause. Examples? Don’t take on too much at once. Don’t try to make every little thing you do perfect. It’s a quick read, but well worth the reminder!
  • Not Crying Over Old Code: Another programming article for this week. As the article says, the common meme for programming is that your old code is always bad code. However, there should be a point in your programming career where old code isn’t bad, it’s just different than how you might have approached it now. If your always experiencing your old code being bad, then maybe you’re not actually that great at programming yet! Or… maybe you’re just too damn picky.
  • Things I Wish Someone Had Told Me When I Was Learning How to Code: This article by Cecily Carver is something I’ve been hoping to come across for a while now. It’s another programming article–a good read for experienced programmers but incredibly important for newbies to check out. Cecily covers some of the roadblocks you experience early on, like code never (almost never) working the first time, or things you experience throughout your programming career, like always being told of a “better” alternative. I highly recommend you read through this if you dabble in programming, or if you’ve ever considered it.

Please visit our team page for MoMagnets and make a Movember contribution if you’re able to! 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


Code Smells – Issue Number 3

Code Smells – Issue Number 3 (Image by http://www.sxc.hu/)

Code Smells

Welcome to the third edition of Code Smells! Periodically I’ll be posting about how to detect code smells and what they mean in terms of the big picture of your code. The previous installment can be found right here.

What’s a code smell? Wikipedia says it perfectly:

In computer programming, code smell is any symptom in the source code of a program that possibly indicates a deeper problem. Code smells are usually not bugs—they are not technically incorrect and don’t currently prevent the program from functioning. Instead, they indicate weaknesses in design that may be slowing down development or increasing the risk of bugs or failures in the future.

These code smells are often based on my own opinion and experience with programming. If you disagree with what I’m saying in my post, please don’t hesitate to post a comment. I’d love to clarify anything I may have worded poorly and discuss your perspective–especially if you have a completely different take on things!

The Stink List

Code Smell #7: Using exceptions to control logical flow. This is a pretty nasty path to get into and a bad code smell to stumble upon. Luckily, it’s generally relatively easy to improve. Using exception handling to control logical flow is, in general, misleading. It’s relying on a mechanism used to catch unexpected errors in order to direct the flow of your program. Often times we can use things like if statements to check for these conditions before throwing exceptions.

A common scenario where I see this is parsing. I’ll illustrate this code smell with a little C# example:


var input = "This is not a number";
try
{
  var parsed = int.Parse(input);
  DoSuccessfulStuff(parsed);
}
catch (Exception)
{
  DoFailStuff();
}

It seems a bit contrived, but I’ve seen lots of code written like this–and you know what? This works. It gets the job done. However, there are other mechanisms built-in to .NET that let us do parsing a little bit nicer:


var input = "This is not a number";
int parsed;

if (int.TryParse(input, out parsed))
{
  DoSuccessfulStuff(parsed);
}
else
{
  DoFailStuff();
}

The second set of code doesn’t need to catch exceptions to know that the parsing wasn’t successful. It may not be obvious from this example but throwing and catching exceptions can be quite expensive compared to a few logical sanity checks instead (and before getting into a debate on this, just know the impact it has on your program. I’ve had things go from taking several seconds to multiple minutes, but there are certainly cases where performance will be negligible).

The additional kicker in my contrived example is using the base Exception class to create what a colleague of mine refers to as Pokemon Exception Handlers. Thus, even if you didn’t want to restructure your code, using a specific exception type would:

  • Indicate to other programmers what you’re trying to accomplish
  • Not swallow other potential problems and have them go unseen

Now, this code smell isn’t always possible to avoid entirely. If you’re interfacing with third party components, sometimes you do have to rely on catching exceptions that you can’t otherwise check for ahead of time. If you don’t have the code, you can’t know for every path how/when/why exceptions will be thrown. The same thing could be said when running within an environment where state cannot be guaranteed. Sometimes it’s just necessary. In this case, I would suggest that instead of using Pokemon Exception Handlers, you try to catch the specific exceptions you know you need to watch out for.

Takeaway:

  • If a simple logic check can be used instead of throwing/catching exceptions, it’s likely a better bet.
  • Try to avoid exception handlers that catch all exceptions. Something nasty might sneak by as a result of it.
  • Interfacing with some code or working working in certain environments means you have to rely on exception logic. Take a deep breath and move on.

Code Smell #8: Having an object hierarchy that requires many very light weight classes. Object oriented programming and how object hierarchies are structured are pretty complicated topics of discussion, so I’m not about to try and over simplify it with discussion of this code smell. This is mostly something I’ve gathered from my own programming experience, so I’ll try to illustrate with examples that parallel things I would have come across.

When I’m building an object hierarchy, sometimes it’s not really apparent just how big and complicated it might get. I might start off with a base class and two child classes of it. Over time, the top three levels in my hierarchy have all turned into some sort of class abstraction, and I don’t hit concrete implementations until a few levels down hte hierarchy. Not a big deal–Sometimes it’s just hard to tell where things will go. When things get to the point where in order to introduce a new class and functionality all I need to do is inherit a class and override a single property or method, that’s a bit of a red flag for me.

On the surface, this seems pretty cool. The hierarchy is apparently solidified enough that extending it is really simple if all I need is a single property or method replacement. So why is this a code smell?

In my opinion, it has to do with the duplication of code. If I end up having many child classes (where child in this case represents the child-most class of my mature object hierarchy) that differ only by a single property or method, then I should look at how these classes are being constructed. I wrote recently about how I used lambda expressions to refactor similar code with classes that differed by a single method. My solution, in this case, was to examine the factory that created my classes. Instead of having 10’s of different child classes with a bunch of boilerplate code, I had one factory that could specify the code that differentiated each class.

The benefit of this?

  • Keep class hierarchies from ballooning our of control. Changing an API down the road can mean making changes in many spots.
  • Reduce duplication of boilerplate code. This might be the code required to define a simple constructor or override a getter property.

This is only one small example, but if you get into this situation in your class hierarchy, I’d recommend investigating to see if you can refactor in a similar approach. Maybe your class hierarchy is incredibly mature and isn’t changing much. If that’s the case, you may not even want to touch it. So be it. If you’re still actively adding classes to your hierarchy, it may be better to try analyzing it sooner rather than later.

Takeaway:

  • Object oriented design is a complex topic of discussion.
  • There’s no one perfect way to make your class hierarchies.
  • Having many child classes that differ by a property/method or two may be worth checking for refactoring opportunities.

Summary

I hope you enjoyed this issue of Code Smells. As always, it’d be great to open the floor to discussion. I don’t believe in absolutes, so identifying code smells is not meant to be me preaching some made up laws of programming. Let me know your thoughts on these code smells or share code smells of your own!


Lambdas: An Example in Refactoring Code

Lambdas: An Example in Refactoring Code

Background: Lambdas and Why This Example is Important

Based on your experience in C# or other programming languages, you may or may not be familiar with what a lambda is. If the word “Lambda” is new and scary to you, don’t worry. Hopefully after reading this you’ll have a better idea of how you can use them. My definition of a lambda expression is a function that you can define in local scope to pass as an argument provided it meets the delegate signature. It’s probably pretty obvious to you that you can pass in object references and value types into all kinds of functions… But what about passing in a whole function as an argument? And what if you just want to declare a simple anonymous method right when you want to provide it to a function? Lambdas.

So now you at least have a basic idea of what a Lambda is. What’s this article all about? I wanted to discuss a real-world coding experience that helped demonstrate the value of lambdas to me. In my honest opinion, I think having real world programming topics to learn from is more beneficial than many of the “ideal” scenario examples/tutorials you end up reading on the Internet. We can argue and debate that certain things are better or worse in an ideal sense, but when you have a real practical example, it really helps to drive the point home.

So for me, I love working with events. I’m very comfortable with the concept of delegation in C#. I can have one object that may notify anyone that’s interested that something is happening, and the other objects that do care are able to handle the event. Thus, actions can get delegated to those objects that care to be notified. One of my weaknesses at this point in my development experience is leveraging the concept of delegation outside of the realm of events. Delegation is powerful, but it’s certainly not limited to hooking onto events with event handlers.

The particular example I want to illustrate is a parallel of a real coding scenario. I was refactoring some code that was leveraging close to zero OOP practices. I wanted to create a nice extensible framework and class hierarchy to replace it. Once I was done, a few colleagues of mine at Magnet Forensics picked up on a bit of a code smell. We all agreed the new framework and class hierarchy was better, but there seemed to be a lot of boiler plate code going on. We got into the discussion of how lambdas could reduce a lot of the light-weight classes I had introduced. After taking their thoughts and refactoring my changes just a little bit more, the benefits of the lambdas were obvious to me.

So obvious, I had to write about it to share with all of you! Feel free to skip ahead to the downloads section to get the code and follow along with it. There are plenty of options for downloading.

The Scenario

I mentioned that this was a real world scenario. I’ve contrived a parallel example that hopefully demonstrates some of the real world issues while illustrating how lambdas are useful. Let’s imagine we have some big chunk of logic that does data processing. In my real-world scenario, this may have existed as one monolithic function. I would have one big function that, based on all the parameters I provide, can figure out how to process the data I feed it.

Problems:

  • Hard to test (You need to test the whole function even if you’re really just wanting to target a small part of it)
  • Error prone (Any small change to one part can potentially break an entire other part of the function as it grows in complexity)
  • Not extensible (As soon as you need to deviate a little bit from the structure that’s existed, suddenly things get really complicated)

By switching to more of an OOP approach, I can start to address all of the above problems. So in this example, I’ll illustrate what my initial refactoring would have looked like by introducing classes. Afterward, I’ll show what my second refactor may have looked like after taking lambdas into account. In order to stay true to some of the real world problems you might encounter when performing a big refactor like this, I’ve opted to include some fictitious dependency. I refer to this at the “mandatory argument” or “important reference”. You’ll notice in the code that I don’t really use it to do any work, but it’s demonstrating having to pass down some other critical information to my classes that the original function may have had easy access to.

Pre-Refactor: No Lambdas Here!

Let’s start with our new OOP layout. I want to have a factory that can create data processor instances for me. So let’s define what those look like.

First, we have the interface for our data processors:

using System;
using System.Collections.Generic;
using System.Text;

namespace LambdaRefactor.Processing
{
  public interface IProcessor
  {
    bool TryProcess(object input);
  }
}

And then a simple interface for a factory that can create the data processor instances for us:

using System;
using System.Collections.Generic;
using System.Text;

namespace LambdaRefactor.Processing
{
  public interface IProcessorFactory
  {
    IProcessor Create(ProcessorType type, object mandatoryArgument, object value);
  }
}

As you may have noticed, the factory interface I’ve provided above takes a ProcessorType enumeration. You may or may not agree that using an enumeration as an argument for the factory is good practice, but I’m using it to make my example simple. Here’s what our enumeration will look like:

using System;
using System.Collections.Generic;
using System.Text;

namespace LambdaRefactor.Processing
{
  public enum ProcessorType
  {
    GreaterThan,
    LessThan,
    NumericEqual,
    StringEqual,
    StringNotEqual,
    /* we could add countless more types of processors here. realistically,
     * an enum may not be the best option to accomplish this, but for
     * demonstration purposes it'll make things much easier.
     */
  }
}

And now we have a definition for all of the basic building blocks defined. These will also be used later when we refactor, so I wanted to get them out of the way right in the beginning.

Right. So, let’s create an extensible IProcessor implementation. We can address some of our basic requirements (like our artificial dependency) and create something that can easily be built on top of. All of our child classes will just have to handle validating their constructor input and overriding a single method. Easy!

using System;
using System.Collections.Generic;
using System.Text;

namespace LambdaRefactor.Processing.PreRefactor
{
  public abstract class Processor : IProcessor
  {
    private readonly object _importantReference;

    public Processor(object mandatoryArgument)
    {
      if (mandatoryArgument == null)
      {
        throw new ArgumentNullException("mandatoryArgument");
      }

      _importantReference = mandatoryArgument;
    }

    public bool TryProcess(object input)
    {
      if (input == null)
      {
        return false;
      }

      return Process(_importantReference, input);
    }

    protected abstract bool Process(object importantReference, object input);
  }
}

And now let’s provide the factory that’s going to be making all of these instances for us. Please not that the factory is left incomplete on purpose. I’ll only be providing two actual processor implementations and I’ll leave it up to you to try and fill out the rest!

using System;
using System.Collections.Generic;
using System.Text;

using LambdaRefactor.Processing.PreRefactor.Numeric;
using LambdaRefactor.Processing.PreRefactor.String;

namespace LambdaRefactor.Processing.PreRefactor
{
  public class ProcessorFactory : IProcessorFactory
  {
    public IProcessor Create(ProcessorType type, object mandatoryArgument, object value)
    {
      switch (type)
      {
        case ProcessorType.GreaterThan:
          return new GreaterProcessor(mandatoryArgument, value);
        case ProcessorType.StringEqual:
          return new StringEqualsProcessor(mandatoryArgument, value);
        /*
         * we still have to go implement all the other classes!
         */
        default:
          throw new NotImplementedException("The processor type '" + type + "' has not been implemented in this factory.");
      }
    }
  }
}

And now that we have a factory that can easily create our processors for us, let’s actually define some of our processor implementations.

We’ll start off with a simple processor for checking if some input is greater than a defined value. It should really only work with numeric values, but one of the challenges we need to work with is that our data is only provided to us as an object. As a result, we’ll have to do some type checking on our own.

using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

namespace LambdaRefactor.Processing.PreRefactor.Numeric
{
  public class GreaterProcessor : Processor
  {
    private readonly decimal _value;

    public GreaterProcessor(object mandatoryArgument, object value)
      : base(mandatoryArgument)
    {
      if (value == null)
      {
        throw new ArgumentNullException("value");
      }

      _value = Convert.ToDecimal(value, CultureInfo.InvariantCulture); // will throw exception on mismatch
    }

    protected override bool Process(object importantReference, object input)
    {
      decimal numericInput;
      try
      {
        numericInput = Convert.ToDecimal(input, CultureInfo.InvariantCulture);
      }
      catch (Exception)
      {
        return false;
      }

      return numericInput > _value;
    }
  }
}

And to put a spin on things, let’s implement a processor that operates on string values only. We’ll implement the processor that checks if strings are equal. Like the GreaterProcessor, we’re forced to get object references passed in. We’ll need to convert these to strings to work with them.

using System;
using System.Collections.Generic;
using System.Text;

namespace LambdaRefactor.Processing.PreRefactor.String
{
  public class StringEqualsProcessor : Processor
  {
    private readonly string _value;

    public StringEqualsProcessor(object mandatoryArgument, object value)
      : base(mandatoryArgument)
    {
      if (value == null)
      {
        throw new ArgumentNullException("value");
      }

      _value = (string)value; // will throw exception on mismatch
    }

    protected override bool Process(object importantReference, object input)
    {
      return Convert.ToString(input, System.Globalization.CultureInfo.InvariantCulture).Equals(_value);
    }
  }
}

Where can we go from here?

  • We can make simple inverse processors by overriding others and inverting the return value on the Process() function. Want a StringDoesNotEqual processor? It’s just as easy as  inheriting from the StringEqualsProcessor and then modifying the return of Process(). Then we add this to our factory.
  • Adding other various types of processors is easy. We just have to extend our base class and add a couple of lines to our factory.
  • This code is much easier to test than one monolithic function that does all types of processing. We can now put a nice testing framework around this, and test each method on each class individually.

Post-Refactor: All of the Lambdas!

So… Why don’t we stop here? Because we can do better.

I mentioned that to make a simple inverse processor, all I had to do was override a class and invert the return value of Process(). That’s pretty easy to do… Except I need an entire new class to do it. If I want to make more types of numeric processing, I need to provide similar type checking and conversion. This code gets duplicated every time I go to add another simple class.

I also have my factory class responsible for creating my processor instances. They’re relatively coupled already, but I want developers to have to use my factory to construct instances of processor interface and not worry about the specific implementations. So what if my factory had a bit more say in the construction if the processors? I could use lambdas to pass in the logic that’s unique to each type of processor, and keep each type of processor pretty bare bones. This would move more logic into the factory, but reduce the number of processor implementations I have to make.

So let’s do better!

Let’s start with our new IProcessor implementation. We’ll provide a delegate signature that will be the basis for the lambda expressions we pass in:

using System;
using System.Collections.Generic;
using System.Text;

namespace LambdaRefactor.Processing.PostRefactor
{
  public abstract class Processor : IProcessor
  {
    private readonly object _importantReference;

    public Processor(object mandatoryArgument)
    {
      if (mandatoryArgument == null)
      {
        throw new ArgumentNullException("mandatoryArgument");
      }

      _importantReference = mandatoryArgument;
    }

    public delegate bool ProcessDelegate<T>(object importantReference, T processorValue, T input);

    public bool TryProcess(object input)
    {
      if (input == null)
      {
        return false;
      }

      return Process(_importantReference, input);
    }

    protected abstract bool Process(object importantReference, object input);
  }
}

From here, we can come up with some child classes that that are generic enough for us to work with using lambas that still provide enough functionality for them to exist on their own. We can break our processors up based on the type of data they’ll be working with. That is, we can have a processor for numeric values and a processor for string values. This will cover a lot of the duplicated functionality that exists in the current state of our refactor if we wanted to keep creating new IProcessor implementations.

Let’s start with our NumericProcessor:

using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

namespace LambdaRefactor.Processing.PostRefactor.Numeric
{
  public class NumericProcessor : Processor
  {
    private readonly decimal _value;
    private readonly ProcessDelegate<decimal> _processDelegate;

    public NumericProcessor(object mandatoryArgument, object value, ProcessDelegate<decimal> processDelegate)
      : base(mandatoryArgument)
    {
      if (value == null)
      {
        throw new ArgumentNullException("value");
      }

      if (processDelegate == null)
      {
        throw new ArgumentNullException("processDelegate");
      }

      _value = Convert.ToDecimal(value, CultureInfo.InvariantCulture); // will throw exception on mismatch
      _processDelegate = processDelegate;
    }

    protected override bool Process(object importantReference, object input)
    {
      decimal numericInput;
      try
      {
        numericInput = Convert.ToDecimal(input, CultureInfo.InvariantCulture);
      }
      catch (Exception)
      {
        return false;
      }

      return _processDelegate(importantReference, _value, numericInput);
    }
  }
}

And similarly, a StringProcessor:

using System;
using System.Collections.Generic;
using System.Text;

namespace LambdaRefactor.Processing.PostRefactor.String
{
  public class StringProcessor : Processor
  {
    private readonly string _value;
    private readonly ProcessDelegate<string> _processDelegate;

    public StringProcessor(object mandatoryArgument, object value, ProcessDelegate<string> processDelegate)
      : base(mandatoryArgument)
    {
      if (value == null)
      {
        throw new ArgumentNullException("value");
      }

      if (processDelegate == null)
      {
        throw new ArgumentNullException("processDelegate");
      }

      _value = (string)value; // will throw exception on mismatch
      _processDelegate = processDelegate;
    }

    protected override bool Process(object importantReference, object input)
    {
      return _processDelegate(importantReference, _value, Convert.ToString(input, System.Globalization.CultureInfo.InvariantCulture));
    }
  }
}

With these two basic child classes built upon our new IProcessor implementation, we can restructure a new IProcessorFactory implementation. As I mentioned, we can leverage lambdas to move some logic back into the factory class and keep the processor implementations relatively basic.

Here’s the new factory:

using System;
using System.Collections.Generic;
using System.Text;

using LambdaRefactor.Processing.PostRefactor.Numeric;
using LambdaRefactor.Processing.PostRefactor.String;

namespace LambdaRefactor.Processing.PostRefactor
{
  public class ProcessorFactory : IProcessorFactory
  {
    public IProcessor Create(ProcessorType type, object mandatoryArgument, object value)
    {
      switch (type)
      {
        case ProcessorType.GreaterThan:
          return new NumericProcessor(mandatoryArgument, value, (_, x, y) => x <; y);
        case ProcessorType.StringEqual:
          return new StringProcessor(mandatoryArgument, value, (_, x, y) => x == y);
        /*
         * Look how easy it is to add new processors! Exercise for you:
         * implement the remaining processors in the enum!
         */
        default:
          throw new NotImplementedException("The processor type '" + type + "' has not been implemented in this factory.");
      }
    }
  }
}

As you can see, our new factory is simple like our first implementation. The major difference? We’re passing very simple lambdas that would have otherwise been functionality defined in a very light-weight child class. This allows us to move away from having many potentially very bare-bones classes and minimizes the amount of boilerplate duplication.

Summary

I didn’t post it here, but the original implementation that this example paralleled  in real life was a pain to deal with. It was hard to test, brittle to modify/extend, and just downright unwieldly. It was obvious to me that switching to a refactored object-oriented implementation was going to make this style of code easy to extend and easy to test.

The initial refactor posted in this example was a great step in the right direction. The code became easy to build upon by relying on simple OOP principals, and granular parts of the functionality became really easy to test. If I just wanted to test certain types of numeric processing, I didn’t have set up a test for my entire massive “process” function. All I’d have to do is make an instance of the processor I want to test, and call the methods I’d like to cover. Incredibly easy.

Lambdas took this to the next level though. By leveraging lambads, I could refactor even more common code into a base class. This meant that  in order to use my processors properly, the final factory class implementation definitely became required to use. It caused a paradigm shift where instead of making lots of light-weight child classes for additional processor implementations, I’d only need to implement some logic in the factory. All of my existing processors could be refactored into a handful of generic processor classes, and the factory would be responsible for passing in the necessary lambdas.

Lambdas let you accomplish some pretty powerful things, and this refactoring example was one case where they made code much easier to manage. Hopefully you can find a good use for lamba expressions in your next up-coming programming task!

Code Downloads


Article Summaries: Weekly Article Dump #17

Article Summaries: Weekly Article Dump #17 (Image from http://www.sxc.hu/)

Articles

  • It’s official: Video games make your brain bigger: I don’t have much time for video games anymore, but this is still totally awesome news. It’s in. It’s official. Video games can actually make you smarter. How great is that? If you’re like me and you find you don’t have much time for games any more, it might be worth picking up a hobby game. It’s a great way to relax provided you don’t get too addicted to it and apparently it can make you smarter. Perfect combo!
  • The myth of the brainstorming session: The best ideas don’t always come from meetings: I thought this article was pretty interesting because we do a lot of brain storming at our office. Sometimes I like to think the sessions go smoothly or that they’re productive. When I contrast them with particular cases that are a bit out of our ordinary approach, it seems like there are certainly some factors that improve the outcome.
    We’ve been dabbling in some personality tests to understand team dynamics a little bit better. To the article’s point, extroverted personalities almost always overrun introverted personalities in a brainstorming meeting from my experience. It’s really unfortunate actually and clearly not really fair if everyone is supposed to be getting their ideas out. In order to get the best results, I think that everyone needs a way to get their thoughts out, and sometimes it’s not doable if you have certain people overrunning others.
    The article also touches on a fear of judgement concept that I think certainly holds true. In a recent brainstorming style meeting, instead of having individuals put on the spot and discuss their opinions, we white boarded them all at once. There was anonymity aside from when the person right beside you writing could peek at what you were putting down. The results were much better than any of our previous meetings of this style. I can’t be entirely sure that the whiteboarding was the reasoning, but it’s definitely something I’d like to try again in the future.
  • Matt Chang – Team Magnet Recognition: This is a post I put out earlier this week. As part of my attempt to recognize the amazing team of people I work with at Magnet Forensics, I decided to write up about our superstar customer/tech support. I know I’d never survive in a tech support role, so I have even more respect for Matt Chang being able to do such a good job. He’s been a great addition to the team, and he makes our troubleshooting of customer issues infinitely easier. Thanks for all your amazing work, Matt.
  • 6 Talent Management Lessons From the Silicon Valley: In this article by John Sullivan, he discusses talent management in the valley. The fundamental idea here is that it’s all driven by innovation. Some key take away points from the article is that innovation is actually a more important goal than productivity and the ability to move fast has a huge affect on this. Additionally, people who innovate want to have an impact. Sharing stories about how previous feats have proven to have a great impact can also be a great driving force.
  • Quality & Agility in Software: Session With Paul Carvalho: This is another article I put out this week about Paul Carvalho who came to speak to our development team. Simply put, the time we had with Paul was packed with information and activities. Every second we spent with him felt like we were absorbing something new and useful. It was far too short. We had lots of great learnings to take away and bring to our own drawing board. We’re excited to be implementing some changes in the upcoming week.
  • Rather than Whine, We Can Learn from the Boring Aspects of a JobMohamed El-Erian reminds us that even the most interesting and glamorous jobs have dull moments. We shouldn’t whine or avoid these situations–they’re vital stepping stones. It’s not realistic to assume you can cut every corner and take every shortcut to get exactly where you want in your career and in life. You have to work hard at what you do and embrace even the small things that can seem boring and monotonous.
  • Fragments: Creating a Tabbed Android User Interface: This is yet another one of my posts that I shared this week. This is my first Android tutorial, and I’m pretty proud of it! It’s very basic, has lots of pictures, and all of the sample code is available to download. I’m confident that anyone interested in picking up Android programming would be able to follow along. Even experienced programmers looking for a way to get a tabbed user interface using fragments in their Android app should find some benefit too! I just found out today that my tutorial made it into the Android Weekly Issue #76, so that was pretty exciting. You can download the app too (it’s pretty basic) to see what the end result will be. Check it out and let me know what you think.

Remember to follow Dev Leader on social media outlets to get these updates through the week.

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


  • 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