December
30

Following my post on the Special Case pattern, I just wanted to give a few more examples in which the pattern proves to be really helpful. In the previous post, we talked about using the Special Case pattern when returning collections, but you can use it in other places as well.

Subclassing

Suppose we have a cached collection of User objects, and we want to fetch a specific User and save it to the database.

User user = cache.Get(”John”);
if (user != null)
{
     user.Save();
}

If we subclass User with a class called MissingUser, and have our cache object return it when it can’t find a user, we can reduce our calling code to:

User user = cache.Get(”John”);
user.Save(); 

MissingUser.Save() overrides User.Save() and does nothing.

Side note: we could definitely go with checking cache.Contains(”John”), and acting on the result, but I think this is too much detail for this level of abstraction, and may be violating Tell, Don’t Ask.

Instantiation

Suppose we want to display a User’s profile. Our User class has a string called Name and a bitmap called Picture.

User user = profiles.Get(”Mark”);
if (user != null)
{
     this.Name = user.Name; // Binding is for the weak.
     this.Picture = user.Picture;
}

When a User is not found in the profiles repository, we could make it return an instance of the regular User class, where User.Name = “Not Found”, and Picture is something like

Missing User

This way, we can just write:

User user = profiles.Get(”Mark”);
this.Name = user.Name;
this.Picture = user.Picture;

and a profile will always be displayed.

Conditioning on Instantiation

What if we wanted to check if a User exists in a managers repository, and only if it is not found, fetch it from a clerks repository? One might be tempted to write something like:

User user = managers.Get(”Ahmed”);
if (user != null)
{
     // Ahmed is a manager.
     Display(user);
}

else
{
     // Ahmed must be a clerk.
     user = clerks.Get(”Ahmed”);
     Display(user);
}

In the previous examples, we avoided the conditional (null check) by using Special Case. If you look at the requirement for this example, you’ll see that the conditional is built into it, and there is no way to get around it.

But if we use the same technique we used in the second example, we could create an instance of User, that has a boolean property called Exists, which will be populated according to the result. This way, we could express our condition much better:

User user = managers.Get(”Ahmed”);
if (user.Exists)

{
     // Ahmed is a manager.
     Display(user);
}

else
{
     // Ahmed must be a clerk.
     user = clerks.Get(”Ahmed”);
     Display(user);
}

No code saved here, but our intention is much clearer this way.

What the hell is a “if (user != null)”? English, people.

kick it on DotNetKicks.com

6
December
27

Guys, will you knock it off with returning nulls from methods? You should return Special Cases, not nulls! nulls tend to bypass any polymorphic structure, and cause code to be cluttered with null checks. For example:

public IEnumerable<Picture> GetAllPictures()
{
  if ( .. there are pictures .. )
  {
    return pictures;
  }
  else
  {
    return null;
  }
}

Oh boy, users of this method would have to check for nulls every time before they operate on it: (if they don’t they might get a NullReferenceException, which s-uhhh-cks)

var pictures = GetAllPictures();
if (pictures != null)
{
  foreach (var picture in pictures)
  {
    …
  }
}

Isn’t that null check a big distraction from the actual logic? If you use a Special Case for that enumerable and return Enumerable<Picture>.Empty(), the calling code could be reduced to:

var pictures = GetAllPictures();
foreach (var picture in pictures)
{
  …
}

Much better, no?

kick it on DotNetKicks.com

2
December
9

I just hate it when people say “I’m working on unit tests for feature X” on daily scrum meetings.

When you get assigned to implement feature X, unit tests are just another part of that assignment. Just like planning, compiling, banging your head on the keyboard or writing documentation.

Sure, I get it, you want to show that you are very trendy and professional, especially since the project manager has asked everyone to unit test. But if you want to be a real professional, just silently work on unit tests and say “I’m working on feature X”.

And write those unit tests before code. And don’t drink water from a puddle.

0