Skip to main content

My simplest and most useful type


I have been doing some introspection on the way I write code to find ways that I need to improve. I consider this a task that one must do periodically so that we keep organized. There is a very, very simple problem that occurs in every application I know:

How to return the results of an operation to the user?

I've seen many implementations. Some return strings, some throw exceptions, some use out parameters, reuse the domain classes and have extra properties in there, etc. There is a myriad of ways of accomplishing this. This is the one I use.

I don't like throwing exceptions. There are certainly cases where you have no choice, but I always avoid that. Throughout my architectures there is a single prevalent type that hasn't changed for years now, and I consider that a sign of stability. It is so simple, yet so useful everywhere. The name may shock you, take a look:


Yes, this is it. Take a moment to compose yourself.
Mind you, this is used everywhere, in every layer. We are talking about Web APIs, Client Applications, Console Middlewares, the internal and external layers of every god damn piece of code I put my hands on.

Here are some very, very interesting properties of having it:
  • Consistency - If it is common practice to use a single, stable type, everyone knows implicitly what they are working with, what are the use cases and it just feels more comfortable.
  • Predictability - If you have multiple developers working on different tasks, they will probably have the need to return results of some shape. You don't need to argue the shape of the results, this is it.
  • Abstraction - Even if we have developers at different layers of the stack, by using a single well-defined abstraction to return results we are making our lives easier. The approach is simply the same in backend, frontend, etc.
You can see there are two types of Result. The first one is a dead simple type with Success, Code and Message properties. The Code is supposed to be unique inside an application. We then have a class that inherits from the base Result which adds a generic property allowing the user to associate an Object of a well defined type to the Result.

How does it feel to actually use this?
Let's define some very very simple methods and see how this looks:

Ok.... at first sight it seems to have some ceremony? This looks verbose, doesn't it? And all those strings hammered into the code that will eventually spread everywhere.

Dealing with ugliness

It is notable that we spend all the time dealing with the Result type, returning it, creating it, etc.I take some extra steps to clean up the code.

First of all, define some conventions that apply everywhere.
  • An empty list means an operation has succeeded. It should be the same as a list with only successful results (assuming the Object does not carry important information in such cases).
  • We never return null from a method that returns a Result or List<Result>.
  • We try to model exceptions we can deal with as Result instances. A database connection exception will be caught, transformed to a Result and then returned.

Then, to deal with the code clutter we start by defining static instances of Result. An obvious instance that is used everywhere is the OK result:

And finally define some extension methods:

Now let's take a look at the final result after using these Extension Methods:

This may not make a big difference in such a small example, but notice how much more fluent the code gets. As it gets more real-worldy it also benefits more from the approach.
The main highlights are the lack of duplicated strings and the absence of initial clutter.

Some of the methods take inspiration from the F# Option module, which has very cool functions allowing you to manipulate the values with ease in a fluent way.

What is your way of dealing with this problem?

Update: here is a follow-up on this post with enhancements on the approach and the feedback that I gathered 

Comments

Popular posts from this blog

From crappy to happy - refactoring untestable code - an introduction

I started testing my code automatically a couple of years in after starting my career. Working in a small company, there weren't really incentives for us to automate testing and we were not following any kind of best practices. Our way of working was to write the code, test it manually and then just Release It ™ , preferably on a Friday of course. I'm sure everyone can relate to this at some point in their career, because this is a lot more common than the Almighty Programming Gods of the Internet make us believe. I find that the amount of companies that actually bother writing tests for their production code is a fraction of the whole universe. I know some friends who work in pretty big companies with big names in the industry and even there the same mindset exists. Of course, at some point in time our code turned into a big pile of shit . Nobody really knew what was going on and where. We had quantum-level switcheroo that nobody really wanted to touch, and I suspect it i...

Why is the Single Responsability Principle important?

The Single Responsability Principle is one of the five S.O.L.I.D. principles in which i base my everyday programming. It tells us how a method or class should have only one responsability. Not a long time ago i was designing a reporting service with my colleague Nuno for an application module we were redoing and we had a method that was responsible for being both the factory method of a popup view and showing it to the user. You can see where this is going now... I figured out it would not be a that bad violation of the principle, so we moved on with this design. The method was called something like "ShowPrintPopup" and it took an IReport as an argument. All this was fine, but then we got to a point where we needed to have a permissions system to say if the user was able to export the report to Excel, Word, PDF, etc... The problem was the print popup would need to know beforehand if it would allow the user to export the report or not, so that it could show it's UI a...