Say no to primitives in your API.. and make your software more explicit

A while ago I wrote some code like this:

public interface ICanBroadcast
{
 public void Broadcast(string message) { ... }
 public void Broadcast(string message, string author) { ... }
}

A bit later the requirements changed and from now on it was required to specify the topic:

public interface ICanBroadcast
{
 public void Broadcast(string message, string topic) { ... }
 public void Broadcast(string message, string author, string topic) { ... }
}

In case you were using Broadcast(string message) the compiler would rightfully inform you that no such method exists. In case you were using Broadcast(string message, string author) the compiler does not catch the error and incorrectly uses the author as topic. I can only hope that you have a suite of tests that makes you notice that something is wrong when you upgrade to my latest release.

Let’s make the difference between an Author and a Topic more explicit (to our API consumers and the compiler) by creating explicit types to represent the concepts:

public interface ICanBroadcast
{
 public void Broadcast(Message message, Topic topic) { ... }
 public void Broadcast(Message message, Author author, Topic topic) { ... }
}

The joy of using a typed language ;)

2 Comments.

  1. While I can agree that using primitives can open potential problems, I’m not sure about passing each value as a class. Perhaps if you’re going to create a Message class, you could add properties for Author, Topic, etc., (they could still be strings) and just pass the one Message parameter to the Broadcast() method. That would be my opinion based on your example. Do you have a reason for that being less desirable? Interested to hear your opinion. Thanks for posting.

  2. I am not opposed to having methods that have a method specific input and output type, eg.

    DoXResult DoX(DoXInput) { ... }
    

    In my experience the concepts of Author and Topic quickly start their own life, and then it is a lot easier to factor those changes into an Author type than figuring out where a string should be interpreted as an Author.