MyProtocol に適合した MyClass のインスタンスを変数に持つ方法

## 問題点の整理
try! Swiftに参加した時の話です。登壇者の Michele Titolo さんの話に気になる話題が出ていました。

あるプロトコルを持ったサブクラス、を定義した時の話です。定義自体は簡単です。Michele さんの例は以下の通りです。

```.swift
protocol Themeable {}
class ListViewController: UIViewController, Themeable {}
```

問題は、さて、これを変数などに持つ時はどうすれば良いですか？

```.swift
var themedViewController: // UIViewController, Themeable ????
```

ちなみに Objective-C ならこんな風に書くことができます。

```.objc
@protocol Themeable <NSObject>
@end

@interface ListViewController : UIViewController <Themeable> {
}
@end
```

```.objc
UIViewController<Themeable> *themedViewController;
```

つまり、`Themeable` な `UIViewController` はそのどちらかの型として変数に置かれ、利用時に必要に応じてキャストして使われる事が強いられる事になります。例えば、`UIViewController` の変数とすれば、`Themeable` なメソッドにアクセスする時はその度事にキャストしてあげなくてはなりません。

Michele さんは２つの方法を提案しています。

#### 方法１

```.swift
public protocol ViewControllerProtocol {
	var view: UIView! { get }
	var storyboard: UIStoryboard? { get }
	init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
	func viewDidLoad()
	// etc
}

protocol ThemeableViewController: Themeable, ViewControllerProtocol {}
var themedViewController: ThemeableViewController
```

#### 方法２

```.swift
var themed: Themeable {
	get {
		return self.viewController as! Themeable
	}
	set(newThemeable) {
		if let themedViewController = newThemeable as? UIViewController{
			viewController = themedViewController
		}
	}
}

var viewController: UIViewController
init<T where T: Themeable, T: UIViewController>(viewController: T) {
	self.viewController = viewController
}
```

説明は割愛させていただきますが、本人も Hack-y と言っている通り、ストレートフォーワードとはいきません。

## 第３の方法

私もこの問題の解決方法をずっと考えていました。嘘です。時折思い出しながら、なんとかならないものかと思いなやんでおりました。そんな時たまたま読んでいた Qiita の記事を読んでいていて「ピン！」としました。その記事はこちらです。

[UIStoryboardからViewControllerをロードするときにenumとprotocolとextensionを使ってカッコよくやる方法](http://qiita.com/mitz/items/91a47eee524a6789ab74)


その中にこんな表現がありました。

```.swift
extension StoryboardIdentifiable where Self: UIViewController {}
```

こ！これだ！と思い、こんな風に書いてみました。

```.swift
protocol Themeable {
	var viewController: UIViewController { get }
}

extension Themeable where Self: UIViewController {
	var viewController: UIViewController { return self }
}
```

これで、`Themeable` は `UIViewController` であるという縛りを入れる事ができます。`Themeable` な `UIViewController` とそのインスタンスを生成してみましょう。

```.swift
class ThemeableViewController: UIViewController, Themeable {}
let themeable: Themeable = ThemeableViewController()
```

themeableViewController 自体が viewController であるという訳ではありませんので、viewController のメソッドにアクセスする時は以下のようにします。

```
themeable.viewController.view.backgroundColor = UIColor.clearColor()
```

不完全と言われればそれまでですが、コンパイル時に `Themeable` は `UIViewController` がある事が保証されています。例えば、`UIViewController` をベースとしないクラスを `Themeable` に適合させても、コンパイル時にエラーとなります。

```.swift
class ThemeableObject: NSObject, Themeable {} // error
```

すっきり爽快という訳ではありませんが、ストレートフォーワードに思えます。

## そもそも

そもそも、なんで `Themeable` と `UIViewController` と分離したのですがという人もいるかもしれません。確かに `ThemeableViewController` なんてクラスを設けて、すべての具象クラスはこいつのサブクラスにすればいいじゃないかという考え方もあります。ただし、`UITableViewController` や他のサブクラスをどう `Themeable` で扱えばいいかと考えると、`Themeable` と `UIViewController` を分離するメリットもご理解いただけるのではないかと思います。

## 終わりに

おそらく、もっと知恵を集めれば、もう少し良くできそうな予感がしますが、今日はここまでとします。

Michele さんの登壇話は以下から参照いただけます。

https://realm.io/news/michele-titolo-swift-protocols-promised-land/