寄付窓口はこちら

try! Swift プロトコルエクステンション: 歴史について #tryswiftconf Day2-3

Matthew Gillingham

Tonchidot, GREE, Mediweb、Eventacularといった日本企業で7年間iOS開発をしています。また、5年以上もAppleのプラットフォーム上で開発している人達の国際的なコミュニティであるTokyo iOS Meetupのオーガナイザーをしています。

twitter.com

Swift 2.0のプロトコルエクステンションに至るまでの、プログラミング言語におけるコードの再利用と共通化の歴史をお話しします。

レコードクラスというコンセプト、サブクラス、Null参照を作りました。 あとで何十億ドルもの過ちだと言っています。

しかしこれはオプショナルではありません

f:id:niwatako:20160303113210j:plain

有料道路の料金徴収をシミュレーションしました f:id:niwatako:20160303113243j:plain

いろんな車がありサブクラスが必要になりいろいろアクションする。 f:id:niwatako:20160303113304j:plain

車のタイプで動きが違う。 f:id:niwatako:20160303113319j:plain

そういったコンセプトとして継承を作った f:id:niwatako:20160303113340j:plain

アランKも共感 f:id:niwatako:20160303113346j:plain

継承が他の言語に大きな影響、抽象クラスも生まれた f:id:niwatako:20160303113414j:plain  f:id:niwatako:20160303113432j:plain

これが理想と考えられていた

f:id:niwatako:20160303113448j:plain

抽象クラスを作り、具象クラスを実装、コードシェアリングをすると。

しかし必ずしもこれが向いているとは限らない、グループ化したりして、一箇所変更すると抽象化したものとは変わってくる。具体化すると違うものになってしまうことがある。そこでもう少し自由になろうと

アランKはオブジェクト指向は難しいと言っている f:id:niwatako:20160303113558j:plain

シングル継承は価値はない f:id:niwatako:20160303113637j:plain クロスカッティング問題がある f:id:niwatako:20160303113640j:plain

たとえば。。。 f:id:niwatako:20160303113651j:plain

スクロールビュー上で何か実装したらUITableViewにも対応してもらいたい。

でも構造上実は簡単には共有できない。シングル継承の問題。クロスカッティング。 f:id:niwatako:20160303113721j:plain

そこでプロトコルプロトコルエクステンション。 f:id:niwatako:20160303113814j:plain

オブジェクト指向Lispで考えられました。 f:id:niwatako:20160303113838j:plain

複数から継承していく、しかしそれにも問題がある。ダイヤモンド問題。 f:id:niwatako:20160303113900j:plain

同じインターフェースを持つかもしれない親を複数継承したいと、問題になる。 f:id:niwatako:20160303113906j:plain

この解決のため、 Flavor:複数のものを混ぜてクラスに入れていく f:id:niwatako:20160303113929j:plain

60-70年代のオブジェクト指向が限界を感じられた f:id:niwatako:20160303113959j:plain かいけつしようとして更に新しい問題、それがダイヤモンド問題 f:id:niwatako:20160303114021j:plain 

f:id:niwatako:20160303114042j:plain 通信業界で使っていて問題に気づいた。Smaltalkに着目して、C拡張で解決しようとした f:id:niwatako:20160303114124j:plain

新しいエンティティを追加した時、For loopでアップデートする、大きなシステムでやると、いろんなおところで変更しなくてはいけないのを解決したいと思った。 SmallTalkの中にオブジェクトにPrintめそっどをもたせ、新しい物を作るときはPrintだけを変えてForLoopを買える必要はない、ダイナミックディスパッチに着目した。 f:id:niwatako:20160303114235j:plain f:id:niwatako:20160303114239j:plain

しかし間違ったオブジェクトを放り込んでエラーになることがある

解決しようとしてまた新たな問題が生まれる。 f:id:niwatako:20160303114301j:plain

JobsがNextStepでProtocolを導入 f:id:niwatako:20160303114326j:plain

誰が発明したのか明らかではないが、プロトコルは実質的にメソッドの名前で具体的な実装情報は入っていない。 f:id:niwatako:20160303114408j:plain f:id:niwatako:20160303114412j:plain Arrayに入るものはプロトコルに準拠している f:id:niwatako:20160303114438j:plain 準拠していなければコンパイラエラーが出る Printメソッドを持っているか確認できる

もう一つ興味深い特性としてダイヤモンド問題がない。メソッド名のみのため f:id:niwatako:20160303114528j:plain

Appleはネクストを買収しフレームワークに入った。 f:id:niwatako:20160303114553j:plain

2015年にはSwiftはProtocol指向言語と言っています。Extensionも有ります。 f:id:niwatako:20160303114629j:plain

メソッド名だけでなくなった。

私はAutolayoutを使っています。トップアンカーボトムアンカーが新たに導入、レイアウトガイドも出来ました。同じようなプロパティだが継承関係がありません。 f:id:niwatako:20160303114651j:plain

でもプロトコルとしてプロトコルが入っている f:id:niwatako:20160303114754j:plain

Extensionでこういうことが出来る f:id:niwatako:20160303114800j:plain

その結果クリーンな形でコードを共有し簡単に効果を出せます。

こういう時はどうでしょう f:id:niwatako:20160303114842j:plain

f:id:niwatako:20160303114854j:plain

ここでは問題はありません。Aが実装を提供しているからBは満足している。

Extensionが両方あったらコンパイラエラー f:id:niwatako:20160303114921j:plain

そこで独自実装するか? f:id:niwatako:20160303114949j:plain

こういうのはどうでしょうか f:id:niwatako:20160303115008j:plain

コリジョンするとデバッグしにくい。 申し上げたいのは、プロトコルエクステンションはパワフルだが、別の複雑さを導入してしまう f:id:niwatako:20160303115048j:plain

名前は慎重につける必要がある。名前の衝突の可能性が増える。

解決は、過去の歴史のように、ベストプラクティスの模索をやっていく必要があるでしょう。 f:id:niwatako:20160303115121j:plain

一つの解決策として考えられるのはプロトコルを使ってオブジェクトを定義しているから、プロトコルとしてどのメソッドで使うのかキャスティングするということが出来ませんか?同じ実装をもったプロトコル、どちらも実装を持つエクステンションがある。オブジェクトとしてキャスティングしてプロトコルとして呼び出せるか

可能だ。ただ複雑なところが他にもあって、デフォルト実装のあるプロトコルがあって実装があるクラスがあってキャストすると。。。予期しない挙動が起きることも考えられます。

MixInとどう違うのか

幅の広い問題だ。メソッドの実装である場合もあればSwiftの場合はプロパティを、実際には提供しない、提供する場合もあるが。非常に幅広いトピックなので言語ごとに戦略が有り異なるタイプが有る。 違いとしては例えばProtocolExtensionは度のクラスに定義されるかを文法で示すことが出来たりする。多くの言語がいろいろな形でやっていて非常に興味深いといえると思います。

気に入った記事は はてなブックマーク

はてなブックマークアプリiOS開発チームから来ました! はてなブックマークにはSwift特集があります! 良い記事を見逃さないように、ご利用ください! http://b.hatena.ne.jp/hotentry/it/Swift

そして良いまとめ記事があったらはてなブックマークでブックマークしましょう! try! Swift の記事で盛り上がると嬉しいです!