---
title: "Long parameter lists"
slug: long-parameter-lists
section: tech
date: 2019-01-09T11:11:00.000Z
canonical: https://roland.leth.ro/blog/tech/long-parameter-lists
---

For example’s sake, let’s say we have a `UIButton` subclass that we want to be customizable at call site, so we add two parameter’s to its `init` method:

```swift
final class Button: UIButton {

   init(textColor: UIColor, borderColor: UIColor)

}

// ...

let button = Button(textColor: .darkText,
                    borderColor: .darkText)
```

Looks pretty OK.

Some time passes and the need to customize its background color appears, at which point we’d need another param:

```swift
final class Button: UIButton {

   init(textColor: UIColor, borderColor: UIColor, backgroundColor: UIColor)

}

// ...

let button = Button(textColor: .white,
                    borderColor: .white,
                    backgroundColor: .darkText)
```

Still not _that_ bad, although I'd start to argue.

Some more time passes and we now need to have it big or small, have rounded corners or not and animate on  touch sometimes. Adding three more params would suffocate both the implementation site _and_ call sites.

We could add default params, as to make call sites prettier, but it’s still not the best we can do. What if we wrapped all these params in a `Config` object and used that for the `init`?

```swift
final class Button: UIButton {

   init(config: Config)

}

extension Button {

   struct Config {

      var textColor: UIColor = .darkText
      var borderColor: UIColor = .darkText
      var backgroundColor: UIColor? = nil
      var animatesOnTouch = false
      var cornerRadius: CGFloat? = nil

   }

}

// ...

let button1 = Button(config: Button.Config())

var config = Button.Config()
config.textColor = .white
config.borderColor = .white
config.backgroundColor = .darkText
config.animatesOnTouch = true
config.cornerRadius = 8

let button2 = Button(config: config)
```

The `init` is clean, the call site is clean and we create a custom `Config` object only when needed and set only the properties we need.

Looks a lot better, doesn’t it?

As a bonus tip, I like to nest related objects, like `Config` in our case. I prefer `Button.Config` to `ButtonConfig`; while they’re basically the same, both from the number of characters to the way you’d pronounce it, nested objects feel more semantically correct, more organized.