読者です 読者をやめる 読者になる 読者になる

Line 1: Error: Invalid Blog('by Esehara' )

または私は如何にして心配するのを止めてバグを愛するようになったか

>> Zanmemo

あと何かあれは 「esehara あっと じーめーる」 か @esehara まで

今日のポエム: なぜ、その抽象化は失敗してしまうのか

近況

f:id:nisemono_san:20150727063023j:plain

打ち捨てられた過去について

要旨

この記事を興味深く読む一方で、やはり違和感を覚える人も多くいるようで、自分もその一人だった。恐らく、この違和感は、「抽象化」が「具体性を奪取していくもの」といったような対立項として述べられているからだ、というように思われる。しかし、果たして具体性無しに「抽象化」することが有益なことなのだろうか。それが一つの違和感のように思われる。

本文

プログラミングの世界には、YAGNI原則(You ain't gonna need it)というものがある。また、YAGNIという言葉を使わなくても、「過度な汎用化が足を引っ張る失敗例」というのは、プログラマとしての心構えを書いた本の中で、ちらほらと自嘲気味に述べられることがある。

僕も、一度そのような失敗例を見たことがあるけれど、なぜこういう失敗が起こるのか。確かにデザインパターンで組み立てられたアーキテクチャは「カッコイイ」と感じるけれども、同様に、それを利用し、実装していく側からすると「無駄だ」と感じることが多い。例えば、そのジョークのパターンとしてEnterprise FizzBuzzという冗談コードが出来るくらいだ。

一体、何故このようなことが起きるのだろうか、ということを考える上において、上の記事は参考になるような気がする。もちろん、同意するところは多いのだけれども、やはり違和感を覚える部分もある。その違和感の部分を、言語化したいと思う。

例えば、上の記事では、次のようなコードを書いている:

def transfer_gold(from_user_id, to_user_id)
  user_a = User.find(from_user_id)
  user_a.gold -= 50
  user_a.save!
  
  user_b = User.find(to_user_id)
  user_b.gold += 50
  user_b.save!
end

この具体性が無くなったものとして、def transfer_gold(amount, from_user_id, to_user_id)という定義を行っている。しかし、僕はここに「変な印象」を覚えた。確かに、具体性はなくなっていて、汎用的なものになっている。しかし、「50」というのは何処に消えたのだろう?

恐らく、このtransfer_goldというのは、何らかの具象に利用するために、使われるものだと考えられる。例えば、この「50」が、あるサービスを受けるための手数料だと、勝手に考えよう。すると、適切なコードの変更は、下のように考えられる。

def transfer_gold(amount, from_user_id, to_user_id)
  user_a = User.find(from_user_id)
  user_a.gold -= amount
  user_a.save!
  
  user_b = User.find(to_user_id)
  user_b.gold += amount
  user_b.save!
end

def pay_service_fee(customer_id, store_id)
  transfer_gold(50, customer_id, store_id)
end

この三行は「些細なコード」のようにも思える。しかし、これはtransfer_goldという「抽象化」されたコードを「具象化」された利用法に落としこむものだ。そして、さらにこのように「抽象化」されたとき、「利用料」の他に、例えば「銭湯の入浴料」にも使えることに気がつくだろう。ちなみに東京都の銭湯は460円である。

def pay_bathing_fee(customer_id, store_id)
  transfer_gold(460, customer_id, store_id)
end

賢明な読者だったら気がつくと思うのだけど、ここで、こっそりもう一つ、具象化していることに気がつく。それは、transfer_goldではfrom_user_idとされていたものが、pay_bathing_feeなどでは、customer_idなどに変更されている。ここで、transfer_goldというのは、「顧客と店」という関係性から具体性を奪取したものだという関係がわかる。

元記事において違和感を覚えるのは、何らかの抽象化というのは、ある具体性を元にしているのであって、そこから離れた抽象化は果たして意味があるのかどうか、ということだった。これ自体は哲学的には面白いテーマではあるけれども、現実的な意味で実装段階では失敗することの多いように感じる。

「「なにもしない」というコードこそが、世界一抽象化されたコードです。」というのがポイントになるのは、このような「具体性」を離れたときに何が起きるか、ということなのだと思う。「具体性」が無ければコードは成り立たない。

たぶん、混乱になっている原因は、恰も「具体性」を奪取したものが、「抽象化」であるという説明をしながらも、同時に「具体性」が無ければ、実はコードは成り立たないという風になってしまっているからなのではないか、というように感じた。つまり、本来ならば、「具体性」に寄り添う必要性があったのかな、という風に。

ただ、ひとつだけ面白いなと思ったのは、このようなボトムアップな汎用化というのは、実はテスト駆動開発の考え方に似ているということ。テスト駆動開発では、まず最初に具体的な値を渡しながら、一つ一つ、要求仕様を満たすように書いていく。とすると、自然にテスタブルかつ、仕様を満たした実装になるという風に、僕は理解しています。とすると、なぜテスト駆動が、コードの設計と結びつくのか、というと、恐らくここに接点があるのでしょう。

哲学者のヘーゲルというおっさんは、「主というのは、従が無ければ成り立たないのではないか。それは言い換えれば、主は従に縛られていると言えるのではないか」という、主従のパラドックスみたいなことを考えました。「抽象化」も同じことが言えるように感じます。つまり、「抽象化は、具体性が無ければ成り立たないのではないか。抽象化というのは、具体性に縛られている」のではないか、と言えそうです。

まとめ

ここで書かれたことは、恐らく元記事の主張とあまり変わらないように感じます。ただ、上の部分において、説明不足で損をしている部分があるかなと思ったので、書きだしてみたものです。基本的には、なんらかの「抽象化」というのは、それを「如何にして利用するか」という側面から抜け出せないのではないか。そこから離れると、途端に悪い抽象化が入り込んでくるのではないか、というのが個人的な感想となります。もちろん、過度な抽象化は、「趣味」としては面白いんですけどね……。

テスト駆動開発入門

テスト駆動開発入門

  • 作者: ケントベック,Kent Beck,長瀬嘉秀,テクノロジックアート
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2003/09
  • メディア: 単行本
  • 購入: 45人 クリック: 1,058回
  • この商品を含むブログ (161件) を見る

実践テスト駆動開発 (Object Oriented SELECTION)

実践テスト駆動開発 (Object Oriented SELECTION)

精神現象学 (上) (平凡社ライブラリー (200))

精神現象学 (上) (平凡社ライブラリー (200))

精神現象学〈下〉 (平凡社ライブラリー)

精神現象学〈下〉 (平凡社ライブラリー)

あわせて読みたい