I think there’s great benefit in not only knowing how to design your code to use common patterns but also to be able to speak about them clearly and concisely to others. If I mention that the problem sounds like it could be solved using the Strategy Pattern, somebody who knows what I’m talking about shouldn’t need much more of an explanation than that. Knowing certain terms in code will help with communication. Obviously, the better your team is at communicating, the more successful you’re going to be.
Very Simple Projection
I’ve seen the following code all over the place. It’s very common to turn one collection into another or loop through and capture certain properties of the items you’re enumerating. How often have you seen this code:
public IList<string> GetNames(IEnumerable<Person> people)
IList<string> names = new List<string>();
foreach (var person in people)
This is simple projection, but languages are seemingly giving you better ways to achieve this same thing. I’ll get to that later.
Different types of projection
I see three basic types of projection. There are variations of these same ideas, but for the most part these cover the bulk.
Selection: Imagine you have a collection of customers and you want only the email addresses, this is where selection projection would be used. This isn’t always a one-to-one relationship, your customers may have more than one email address (if you allow it) and you’ll end up with more items in the projected collection than the starting collection.
Creational: This is the type of projection that returns new values from an existing collection. Below, you’ll see two concrete examples in C#.
Transformation: Given a list of numbers, you want those numbers squared. This is similar to creational, because you’ll be getting a new item, but it shouldn’t modify the elements in the original collection.
Projection with LINQ in C#
An example that lends itself well to the concept of projection is the following:
My user interface allows strings to come into my application. I want to transform these strings into tags like any blog post, video or photo might have assigned to it. I don’t want my tag service class to have to deal with strings, I want to give it a collection of Tag objects. How do I do this?
With LINQ, this creational projection was very simple:
public void SaveTags(IEnumerable<string> tagNames)
var tags = tagNames.Select(name => new Tag(name));
Another great use of creational projection are some of the usages I’ve seen with SelectListItems in the ASP.NET MVC space. Given a list of objects, create a list of HTML drop down items for a select list.
K. Scott Allen has a good write up entitled Drop-down Lists and ASP.NET MVC on this very thing. There are also many good examples over on the MSDN Visual C# Developer Center.
Your Thoughts on Projection…
I see this pattern often enough but I don’t hear the term “projection” nearly as often. Is there a more common name to this that I’m not hearing or are people just not referring to it by this name?