Constant interface

Most people will think this isn’t quite an Anti-Pattern. But it’s one of the most common ones. The idea is that you put all your constants in an Interface’s definition to be able to namespace them, and have more context about what you’re accessing without injecting.

The problem is that this Interface is now part of the implementation. And most would argue that constants belong in configuration objects and exported as part of the API.

But instead of dealing with injecting configurations and making sure you pass the correct one’s: we can embrace the constant interface, and just decouple the definition from the values.

Let’s see what I’m talking about. Here’s an example of us using the Constant Interface Anti-Pattern in Swift (with enums instead of protocols)

This builder is accessing the constants through the name space. If we want to remove these implementation details we can introduce a generic type that contains our Constants. And we can continue with the exact same code as before.

Let’s begin by defining a protocol:

And we introduce a generic type with the same name to our builder:

And now you can define your actual Constants

But now, you might say: you’re still including which constants you’re using right into the Builders signature. This isn’t much better. Well that’s where type erasure comes to the rescue. With type erasure we can refer to our builder without extra generic information getting in our way.

How Type Erasure works

We start by encapsulating the builder’s api into a protocol:

And we create a wrapper class that erases the generic constraints:

And we can now always refer to AnyBuilder as the new builder:

TADA! We have successfully removed what makes this Anti-Pattern an Anti-Pattern.

Object orgy

Granted. I’ve only included this particular one because I find the name so amusing. Yeah. I’m a child. But Object Orgies are a frustrating and problematic issue in many code bases. They’re called this way because everything has access to everything. Anything can be changed from anywhere. Systems like this tend to be very chaotic. Not only because it can be very unclear where what is going on, but our types give no guide or indications about how to approach problems.

Consider the following class modeling a Book:

In this code anything can read and write any properties of the Book. Refactoring this can be problematic since the flow of the application heavily depends on being able to change these properties at any time. But how could we introduce some extra safety without completely rewriting the flow of the system?

An answer might be adding extra safety by writing a wrapper with a Phantom-Type.

But what’s a Phantom-Type, anyways? A Phantom-Type is a generic parameter that is not directly used, but instead serves as an type safe indicator of how we can deal with the object. And we can even regulate how we read and write properties of an object using these types.

Phantom-Types don’t have to be that scary

So let’s start by a creating a simple wrapper. We’ll call it Safe.

Safe has a generic parameter for the object that it’s wrapping and a parameter determining the read and write rights we have on it. Let’s put it to the test!

We can start by creating a protocol signaling that we can read the title of the book:

And we can say that when the Rights conform to ReadTitle, our Safe implementation will expose the title as a read only property:

Well that was easy. Now let’s do it with Writing to Title:

And Presto! You can now slowly make sure that instances of code that use Book, can only read and write what they’re supposed to and you can think twice before a method wants to read and write every property.

Now of course this technique is very powerful and can be used in very elegant systems. You can read more about it in Sebastian Sellmair’s post about the topic.

So? What’s the point of all of this?

Mainly? To say that not everything is black and white. Rewriting a system might be the cleanest solution for many. And it’s clearly a lot more fun. However, sometimes we can take pride in writing clean solutions around not that clean codebases and feel proud we made something better.

Of course, most of my solutions here are not ground breaking or even perfect. But it goes to show that every piece of code can be rescued and maybe even turned into art.

P.S.: Here’s a cute cat or whatever