@kyanny's blog

My thoughts, my life. Views/opinions are my own.

破れ紙の片割れのようなMixinができてしまうワケ

最近「Mixin は避けられれば避けたほうがよいのではないか」と思い始めている。扱いに困るダメ実装の Mixin を簡単に作れすぎてしまうからだ。

Wikipedia の定義によると、

mixin とはオブジェクト指向プログラミング言語において、サブクラスによって継承されることにより機能を提供し、単体で動作することを意図しないクラスである。

とのことなので、そもそも Mixin される側の実装と結びつきが強くなるのは仕方ないのだろう。しかし、まれにだが破れ紙の片割れのような実装を持つ Mixin ができてしまうことがある。

一枚の紙を適当に手で破って二枚にする。断面はギザギザだが、破った二枚の紙の断面はぴったり一致する。もともと繋がっていたものを切り離したのだから当然だ。だが破れ紙の断面にぴったり合うような別の紙を用意するのは簡単ではない。別の紙を合わせる必要があるのならば、紙を破るときにそれを見越して断面がギザギザしないように注意深く破っておかなければならない(実際には、破るのではなくハサミかカッターで切って断面が綺麗になるようにすべきだろう)

ダメな Mixin は破れ紙の片割れに似ている。 Mixin される側と合わさって初めて用をなすが、断面(インタフェース)がギザギザに入り組んでいるので、新しく Mixin を適用したいクラスを作るのが非常に難しくなる。コードの再利用を促進するためにわざわざ別のパーツとして分割したのに、そのパーツの組み込み方が難しくて再利用したくてもできない、なんてことになりがちだ。

なぜそんな Mixn が出来上がってしまうかというと、もともとひとまとまりになっていた実装の一部を深く考えずに抜き出して Mixin へと分割してしまうからだ。ひとまとまりのコードを書いた本人はそれらのコードがどのように相互作用しあって動作するかよくわかっているので、分割後のコードもうまく脳内で組み合わせてすんなり読める。だから、他人の目からみると密結合していて分割できそうにないようなコードであっても分割できてしまうのだ。

不運なことに、継承や Mixin などはオブジェクト指向プログラミングにおいて一般に良い設計手法とみなされている。なので、上記のようなダメ設計・ダメ実装の Mixin であっても、「Mixin という良い手法を使っているのだからこれは良い設計・良い実装だ」という誤った大義名分が幅をきかせやすい。ちょっと無茶だな、と思っても、そういう感覚は個人の感性・センスによる部分が大きいので言語化しづらく、したがってレビューでも指摘しづらい。「手法は良いがお前の設計・実装が悪い」と単刀直入に(しかも相手の気分をなるべく害さず)言うのは難しい(特に英語だと)。

これはあくまで特定の Mixin の設計・実装が悪いだけであって、 Mixin という手法そのものには利点がたくさんある。そこに異論はない。だが、 Mixin は便利で強力な分、再利用性と可読性の高い Mixin を設計・実装するには相応の能力やセンスが求められる。にもかかわらず能力不足だったりセンスが悪いひとの手によるイマイチな Mixin が作られてしまってうやむやのままコードベースに根を張ってしまうのは避けたい。という悩みが冒頭の「Mixin 避けるべきでは」という疑問につながる。

ではどうすればよいかというと、移譲が使えるのなら移譲すればよく、そうでなければ再利用を諦めてコピペするのも悪くないのでは、という気がしている。そもそも汎用的に使えるほど一般化したユースケースを見極められていないからインタフェースが破れ紙のギザギザになってしまうわけで、そういうコードは無理やり引き剥がさず混然一体とした状態のままにしておくほうがよいのではないか。経験上そういう箇所は変更の機会が多いので、ほどなくして「似ているが異なるもの」として分岐していくことが多いし、時間が経ってもずっと分岐せず重複したままだったらその時点で改めて分割したほうがよりよい切り離し方ができるはずだ。

iOS Swift の勉強 (3)

絶対に挫折しない〜を引き続き読んでいる。 Playground で UI 部品のインスタンスを作るコードを書いて、インスタンスのプロパティやメソッドを使って部品を操作する、というあたり。 Playground って irb/pry みたいなインタラクティブシェルのことでしょ?とたかをくくっていたらプレビューで GUI 部品そのものが表示されてびっくりした。

for ループで Slider 作ったらプレビューはどうなるんだろう、と思ってやってみたら、当たり前だが部品がループ回数分表示された。せっかくなのでランダムな value を生成してみた。 Swift でランダムな数字を得る方法はいくつかあるようで、違いがよくわからないので適当に 1 以下の少数になるようにコピペ改変した。ランダムな数字のほうのプレビューがなんか妙なグラフっぽい表示もされていてこれは一体なんなのだろう。

f:id:a666666:20150515012953p:plain f:id:a666666:20150515013017p:plain

Duolingo継続30+日

毎日メールで「継続何日目です!今日も頑張りましょう(このトピックを勉強しなさい)」みたいなお知らせが届くが、それに貼ってある継続日数の画像のカウンタは30+で打ち止めのようだ。数字の積み上げ自体にはあまりこだわりがないので昨日は一回休みにして、今後はノルマ達成を意識しすぎずのんびりやっていこうと思う。

f:id:a666666:20150514224330p:image
f:id:a666666:20150514224337p:image
f:id:a666666:20150514224352p:image

Be Kind そのためにできること

Be Kind

Digg Deeper より。いい話だった。同意できる。

Kind であろうとするために自分がこれまでのところ実践していることは、

  • 聞かれたことに丁寧に答える(口頭であれチャットであれ)
  • 面倒くさいレビューを避けずに取り組む(これはまだかなりムラがある)
  • 広く意見を求められている議論にはちゃんとレスする
  • 仕事や知識を独占しない(ひとりで抱え込まない、適時誰かに意見を求める、など、取り組んでることを「見える化」する)
くらいで、特筆できることはなかった。

ではさらに何ができるだろうか。

積極的に絡んでいって「何か困ってることない?手伝えることある?」というのは、そういうロール(役割)でないのであれば、お節介すぎる気がする。本来の自分の仕事に時間を割くべきだし、時間が余ってるなら自由研究とかすればよい。

最近社内で技術トピックの Webinar が流行ってて、そういう形でノウハウをシェアするのはよさそう。ただ、英語でスピーチする大変さは去年思い知ったし、質疑応答はもっとこわい。質問の英語を聞き取れなかったり意味がわからなかったりすると詰む。

いまのところネガティブなフィードバックをもらわずにすんでいるので(ポジティブなフィードバックも少ないけど。そもそもそういうフィードバックのプロセスが公式に組み込まれていない)、実践していることを見直しながら継続しつつ、さらに上を目指すための何かを模索する、くらいでいいのかもしれない。

iOS Swift の勉強 (2)

iBooks で読める英語のマニュアルっぽい本(短いほう)を少し読んだがさっぱり意味がわからないので「絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】」という本の Kindle 版を買って読み進めている。

冒頭の「知識は必要になったときに学ばないと身につかない」という考え方には大いに同意する。「だから最初に座学でいろいろ教えても身につかないので、まずわかってなくていいからとにかく手を動かしてやってみて、それから詳しい説明で理屈を学ぶ」というアプローチはすごくいいと思う。なのに最初のほうの章で Map アプリを作ってみて以後は Swift の文法の説明がずっと続いていて話が違うじゃないかさっさと iPhone アプリを作らせろ、という気持ちになってきている。

あとこの本には全く落ち度がないのだが、配列の要素の数字を足し合わせるという演習問題をやってちょっと寄り道して reduce とかあるのかな?と思い試してみたら、 reduce あるのだが関数のシグネチャ?の読み方がわからなくて調べても combine: ってなんだよとかそういう部分の説明がないままに Xcode の補完でいきなり登場して、「意味不明だし検索でも正解にたどり着けない疑問」に遭遇してしまって、寄り道のせいで挫折しそう。

f:id:a666666:20150514025550p:plain

フォーカスがあたってハイライトされてる initial: U の部分はどうやら initial: は実際のコードを書く際には不要で 0 とか数字のみで ok なのに、その後ろの combine: は無いとダメっぽいのは何故??とか(しかもぐぐってでてくるブログとか Qiita とかの記事では combine: 無しのサンプルコードのほうが多いのだが combine: の有無がどう違うのかも、どこにリファレンスドキュメントがあるのか探せず調べられない)、その後ろの薄くハイライトされている (U, T) -> U の部分は実際にはどういうコードで穴埋めするのが正解なのか(カッコや -> は必要なのか、とか)ぐぐってもこれだ!という例を探し当てられなくてストレスがたまる。

絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】

絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】