Brendan Enrick

Daily Software Development

Parameter and Return Type Interfaces

At some point, I’m sure you’ve had someone suggest that you use an interface instead of a concrete class as a dependency. Assuming you’re following the Interface Segregation Principle, that could be exactly what you want to do. Well written interfaces can make your code much simpler and more clearly define your dependencies. That’s why Interface Segregation Principle is one of those popular SOLID principles you’re always hearing about.

NP-Interface-Segregation

I recently read an interesting tweet from Derik Whittaker talking about using IEnumerable when an ICollection or IList would be the better choice. 

Ugg, may want to fix your code rather than do this "// ReSharper disable once PossibleMultipleEnumeration"

This move toward making everything IEnumerable<T> is a trend happening across the C# community. I believe that ReSharper (a tool I use and love) is leading to some of this. When you write a method that takes in a collection as a parameter, and your method does a foreach over that collection, ReSharper will suggest (correctly) to change it to an IEnumerable. This is because you only enumerated it once, and that means that you can be more relaxed in your requirements.

Side Note: IEnumerable is not technically the requirement for a foreach loop.

The problem people run into with IEnumerables is that they’re not all collections. IEnumerable<T> just means that there is a method to get an Enumerator. In simple terms, I mean that it’s possible to walk through the items in the enumerable one at a time. Sometimes that requires work that’s more than constant time to get to the next item in the enumerable class. The comment that Derik mentioned in his tweet is one that tells ReSharper to not warn you about a possible issue. That issue is that you might be doing the work of walking through the enumerable more than once. When it sees an enumerable that is enumerated for a second time, you’ll receive this warning.

Keep Your Method Parameters Permissive

3364773646_ebc547a3fa_o

When you’re making a method parameter, you want to make sure that you’re only requiring exactly what you need. In doing this, you’ll likely create interfaces following the Interface Segregation Principle. When dealing with collections, you’re likely to accept an IEnumerable<T> if you only enumerate once. You might accept an ICollection<T> if you need to enumerate a couple of times, allow adding and removing, or need to count the items. If your collection needs random, array-like index access, you should consider using IList<T>. 

This allows the caller of your method to give you whatever they have at the time. You really don’t care as long as it has what you need. If their object is an IEnumerable that isn’t also an IList, they can convert it before providing it to you. Working this way makes your API much more flexible, since you’re making your minimum requirements clear.

Return Usable Types From Your Methods

6555544311_79789a44b9_o

Sadly, I see the reverse being pushed as a positive. You will find information telling you to return IEnumerable<T>, so that you can easily change. This, however, means that you’re providing your method’s consumer with no information about the object they’re receiving. If they need access to array-like indexing, they have to call ToList() on your return value in order to use it.

Since ICollection<T> implements IEnumerable<T> and IList<T> implements ICollection<T> and IEnumerable<T>, you can return an IList<T> allowing your method’s caller to use IList<T>, ICollection<T>, or IEnumerable<T> depending on their usage. You’re using an interface and still giving the consumer the power of choice. You can avoid tightly coupling to a concrete implementation while still providing a useful return value.

I almost never return IEnumerable<T>. I don’t know that the return value will only be enumerated once. That’s outside my current layer of abstraction, so I shouldn’t be dealing with it. The safe bet is just to return a useful collection if that’s what I have. If my value really is enumerable, but not a collection, I will return an IEnumerable. In all other cases, it should be a more useful interface. lists an collections really are cohesive concepts that should be grouped into one object when needed.

SOLID Principles – Software Craftsmanship Calendar Topics

The SOLID Principles are a set of Object Oriented Design Principles that are very interrelated and when followed can improve your code. Additionally, they make a great acronym that implies the benefits of using the principles. In 2011, at NimblePros, we made a calendar of Software Craftsmanship Principles and made humorous images to go along with them. We continued making the calendar for three more years and then missed 2015. Now we’re making a software craftsmanship calendar for 2016. Please back the calendar on Kickstarter, so there will be a 2016 edition.

Single Responsibility Principle

While it might seem useful at the time to just keep this stuff together, you may eventually realize it isn’t.

SingleResponsibilityPrinciple

Avoid tightly coupling your tools together.

Open Closed Principle

It’s important that your code be open to extension while being closed to modification. This means that you should be able to add additional functionality without significantly altering the existing functionality. Remember the dangers of changing code; bugs can easily be created.

OpenClosedPrinciple

Brain surgery is not necessary when putting on a hat.

Liskov Substitution Principle

Any class implementing an interface needs to be substitutable for that interface. For example, you can’t have missing functionality when implementing your interface, or it’s not really substitutable. Developers shouldn’t need to be careful about using a specific implementation of an interface. That was the point of using an interface.

LiskovSubstitutionPrinciple 

If it looks like a duck, quacks like a duck, but needs batteries – you probably have the wrong abstraction.

Interface Segregation Principle

Your interface should match only the needs of its users. If you pile on too many features to your interface, you make it hard to implement and difficult to use. The implementations are also likely violating the Single Responsibility Principle just to implement your interface.

NP-Interface-Segregation

Tailor interfaces to individual client’s needs.

Dependency Inversion Principle

Don’t get too specific on your dependencies. Make sure that you’re depending on something stable. This is often some kind of an interface. In our example below, an outlet and a plug make the connection nicely. You don’t want to hard-code specifically to the connection you have; you might need to change your connection at some point.

NP-Dependency-Inversion

Would you solder a lamp directly to the electrical wiring in a wall?

I hope you enjoyed these SOLID principle pictures. And if you want to see more of this kind of humorous take on important software development principles and ideas, back our Software Craftsmanship Calendar 2016 on Kickstarter.

Commenting Methods Using Liskov Substitution Principle

After reading the title of this post, some people might be wondering why I am advocating commenting at all, because I’ve spoken out against commenting code before. My team and I were recently reading through some code that was littered with comments, and I do mean littered. There were tons, they were mostly useless statements like “//run”, and I swear there were more of them than actual code. This of course sparked some preaching to our choir about how comments in code are often less-than-useful. We of course settled on the time when they are useful being the XML comments on methods, but those should also only be used when writing public libraries where others will not have access to the source code or unit tests.

Comments on those methods are useful since tons of people will use the method and will not be able to see the guts of the method or examples of how to use it. This makes the comments useful. However, they need to be kept up-to-date (difficult task).

So what does all of this have to do with Listkov Substitution? Well, the principle basically says that all of the classes which implement an interface (or inherit) need to work the same way. There should be no difference between implementations as far as the calling code is concerned. In fact it is really about making sure that we maintain a consistent abstraction. If we say something about the interface it must hold true for the implementation. This means that any comments about the interface must hold true for every implementation.

We were wondering if the comments needed to be on each of the concrete classes or if we could just put it on the interface, and this was confirmed for me by Ben Heimann who quickly made an interface and a concrete class. Then he commented just the interface method and not the concrete one. We of course knew we would see the comment when using the interface, but we also saw it when we were dealing with the concrete class. Great work Visual Studio 2010! This means we don’t have to duplicate and also signals that we should follow LSP.

The concern is that if you have the comment in both places you would have to update them both. This also means that they could differ, and if they ever needed to intentionally differ then it means that we are violating LSP. Having the comment in the one place should at least point to the fact that we should maintain the same behavior for the calling code in all implementations of our interfaces.