swiftで、タンポポのせみたいな設定作業をクロージャ使って見やすくする

# swiftのクロージャを使って設定情報を書きたい
他言語では設定をクロージャを使って書いたりするので、その流れでやってみた。
（ちなみにswiftは一昨日から触り始めて、知識はほぼwikiから）

## やりたいこと
いま、たくさんのページにUITextFeildをデザインに従っていっぱい埋め込むという、タンポポのせみたいな仕事をしている。
<strong>storyboardを使わずに。</strong>

どういう仕事かというと、ページ全部で100ページあるとすると、10ページずつ、大まかにUITextFieldの設定が違う。
そして、1ページの中にあるいくつかのUITextFieldの設定はさらに細かく違う。

こうなると、UITextFieldを生成するのに、さすがに毎回以下のように書くわけにはいかない。

```swift:
let textField = UITextField()
textField.borderStyle = UITextBorderStyle.RoundedRect // 枠
textField.font = UIFont.systemFontOfSize(15) // フォントサイズ変える
textField.textColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // 色を変える
textField.placeholder = "ここに書き込んでください"
textField.textAlignment = NSTextAlignment.Center // 中央寄せする
// 次は文字が入るぴったりのサイズに変えて、次は...etc
```

## くくり出す
普通に考えて、共有できる部分をくくり出してみる。
100ページのうち、10ページずつで固定されるものは、（ここでは例として）borderStyleとtextAlignmentとする。
buildTextField()というメソッドを作って、そのへんのクラスに放り込んでおいた（適当）。

```swift
class UIBuilder {
    class func buildTextField() -> UITextField {
        let textField = UITextField()
        textField.borderStyle = UITextBorderStyle.RoundedRect // 枠
        textField.textAlignment = NSTextAlignment.Center // 中央寄せする
        return textField
    }
}
```
呼び出す。

```swift
let textField = UIBuilder.buildTextField()
textField.font = UIFont.systemFontOfSize(15) // フォントサイズ変える
textField.textColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // 色を変える
textField.placeholder = "ここに書き込んでください"
```
これだけでも、タンポポのせがちょっと楽になる。
UITextFieldの生成と一部の設定が隠蔽されているので、知らない人が読んだ時に若干戸惑いが発生する可能性があるけど、背に腹はかえられない。

## カオス
現実のタンポポのせは辛いもの。

最初の例は問題を簡単にするために、TextFieldが1個しかないことになっているけど、当然1ページの中に複数ある。
そうなると、ソース上で1つ1つのtextFieldを判別できる変数名にする必要がある。

…あるよね？
さすがに、textField1とかtextField2とかいう変数にすると、後で見た時に辛いと思ってくれるよね？

とりあえず辛いということにして、意味のある名前をつける必要がある。
<strong>「えーと、この画像の上にある、この四角の中の、このラインの上で、隣に丸がある…」</strong>みたいな名前をつける。
そう、<strong>textFieldOnHogeInPiyoUnderFugaWith...</strong>みたいな名前をつけるんだ…！

このへんでstoryboardに帰りたくなったけど、我慢した。
さて、素直に書いてみましょう。

```swift
let textFieldOnHogeInPiyoUnderFuga = UIBuilder.buildTextField()
textFieldOnHogeInPiyoUnderFuga.textColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // 色を変える
textFieldOnHogeInPiyoUnderFuga.placeholder = "ここに書き込んでよね"
// ほか3行ほど設定

let textFieldOnHogeraInPiyoUnderFuga = UIBuilder.buildTextField()
textFieldOnHogeraInPiyoUnderFuga.font = UIFont.systemFontOfSize(15) // フォントサイズ変える
textFieldOnHogeraInPiyoUnderFuga.placeholder = "ここに書き込むべき"
// ほか4行ほど設定


// あと5個だよ！
```
いや…わかる…わかるよ。
所謂クソコードってやつね。わかる。あれね。

1行が長すぎるし、タイプミス（Xcodeだから補完ミスか）してても正直わからん。

## クロージャによる設定
名前はしょうがないとして、できるならその変数の使用回数を減らしたい。あと、もうちょっと明示的にまとまりを示したい。
ので、

```swift
class UIBuilder {
    class func buildTextField(settingFunc: (UITextField)->Void) -> UITextField {
        let textField = UITextField()
        textField.borderStyle = UITextBorderStyle.RoundedRect // 枠
        textField.textAlignment = NSTextAlignment.Center // 中央寄せする
        settingFunc(textField)
        return textField
    }
}
```
とクロージャを受けるようにしておいて、

```swift
let textFieldOnHogeInPiyoUnderFuga = UIBuilder.buildTextField() { f in
    f.textColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // 色を変える
    f.placeholder = "ここに書き込んでよね"
    // ほか3行ほど設定
}

let textFieldOnHogeraInPiyoUnderFuga = UIBuilder.buildTextField() { f in
    f.font = UIFont.systemFontOfSize(15) // フォントサイズ変える
    f.placeholder = "ここに書き込むべき"
    // ほか4行ほど設定
}
```
とする。

これでタンポポが綺麗にのせられるようになった。
速くなったり、すごく事故が減るとか、そういうメリットがある書き方ではないんだけど、見やすい。
見やすいのはメンテしやすい。

なお、現実のコードでは、第一引数のクロージャは省略可能にしないと空のクロージャを登録する場面がでてくる。
この例だと必要性がないので書いてない。

## 余談
例えばRubyでは、同様にクロージャを使って設定情報を入れるというのは良く見る。

```rb
foo = Foo.build() { |setting|
  setting.hoge = true
  setting.fuga = false
}
```
けれど、こうするより

```rb
foo = Foo.build( {
  hoge: true,
  fuga: false
})
```
と書いた方が、後者の方が自由度が少なくてハマることが多いと個人的には思う（ここまで書いといてなんだが）。

前者のようにクロージャで書くと、中に何でも書けるので、クロージャ内部で書いた方が良いことと、外で書いた方が良いことが曖昧になる。
上の例だと、意図としてはbuild()するのに必要な補足情報をクロージャで入れる、という感じで書いたのだろうけど、build()した後にゴニョゴニョするようなコードを入れてしまう事がある。

TODO: この部分をswiftで書き直す。