Primitive Obsession code smell

The primitive obsession code smell means you’re using primitive types (ex: string, int) excessively instead of encapsulating them in objects. This leads to sloppy code that’s error prone, such as when you have very long parameter lists full of primitives. I’ll show an example of this problem and how to fix it.

Here’s a simple example of this problem:

void SendMessage(string message, string firstName, string lastName, string emailAddress)
{
    //send message to person
}

//Call the method
SendMessage("Passing in lots of primitives is error prone!", "Bob", "bob@example.com", "Sterling");
Code language: C# (cs)

Notice that the emailAddress and lastName parameters are transposed in the method call. This is a bug that’s difficult to detect, and this is a common error caused by primitive obsession.

To fix this primitive obsession example, first encapsulate the related parameters by putting them in a Person class.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAddress { get; set; }
}
Code language: C# (cs)

That’s better, but we can go one step further. Email addresses are encapsulated by the MailAddress class (in System.Net.Mail). This contains other properties besides the email address string and also does validation. So it’s better to use that instead of string for EmailAddress:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public MailAddress EmailAddress { get; set; }
}
Code language: C# (cs)

We don’t need to encapsulate every single primitive, just where it makes sense. Don’t go overboard and end up with a bunch of tiny classes.

Now SendMessage()’s parameter list can be changed to use Person as a parameter.

void SendMessage(string message, Person person)
{
    //send message to person
}

//Ah, that's better.
var person = new Person()
{
    FirstName = "Bob",
    LastName = "Sterling",
    EmailAddress = new MailAddress("bob@example.com")
};
Code language: C# (cs)

Much better.

Leave a Comment