Refactoring to: Parameter Objects

I’m currently reading Refactoring to Patterns (affiliate link). Yesterday, when I wrote about the Creation Method for an object that has a lot of parameters, it made me think of @modocache‘s amazing talk on Swift Patterns in iOS API Design, specifically the part of about Parameter Objects. This has come up for me a few times since I initially saw the talk, so I wanted to document it here.

The Problem

Let’s say you’re writing a BananaUIKit library that includes a simple BananaAlertView:

BananaAlertView

The initial code might look something like this:

This is great until a user of this framework comes along and asks for the ability to make the BananaAlertView brown instead of yellow…

To make sure this change is not breaking to other consumers of this framework, we can use Swift’s default parameters:

This works fine as long as we’re adding parameters to functions, but this doesn’t work if we want to add parameters to something else, such as a closure for when a button on the BananaAlertView is clicked:

But what if we need to change the parameters in the closure? What if the client also need the button’s text?

The solution is to just add the button’s text as an argument to the ButtonCallback:

But this breaks everything… When calling the show method, the ButtonCallback now has to take in two arguments instead of one…

So what do we do? Parameter objects to the rescue!

The Solution

The solution is to create a parameter object for the closure:

If we ever need to add an additional parameter, it’s completely fine. The buttonCallback never changes!

And of course you can easily remove (or deprecate) parameters:

Other Uses

And of course this could be used in a more general way to refactor a method as it gets more and more parameters:

Trade-Offs

And just like with any pattern, it’s good to know it, but it comes with tradeoffs. It is our job as programmers to find the right balance 🙅.

For parameter objects, the positive is that you can Future-proof your API, but they are a lot of overhead. You don’t want to have to create a new struct for every single method and closure in your app!

So use this wisely!

Finally, I highly recommend watching @modocache’s full talk here!

Join me for a Swift Community Celebration 🎉 in New York City on September 1st and 2nd. Use code NATASHATHEROBOT to get $100 off!

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.