コードの自動生成は嫌い。

コードの自動生成は基本的に嫌いな訳ですが、最近ちと分からなくなってきたり。


何でコードの自動生成が嫌いかってぇと…

  • 最初は自動生成しても、それを一度カスタマイズし始めると、その後は、コードの自動生成が使えなくなる可能性が高い。
    • GenerationGapパターンは、1つの解決策ではあるものの、実装継承が前提になるし、
      カスタマイズポイントはちゃんとオーバーライド出来るようにしないといけないのが、イマイチ。
    • EMFの@generatedタグってのもあるって最近知った。
      要はdocletを使って、自動生成エンジンが触っても良い場所をマーキングするのです。
      苦しいな〜。と思うものの、意外と悪く無いんじゃないかと。まぁ、例によって染まってるだけって話もありますが。
  • 自動生成したコードをどう管理するか?ってのは、結構難しい。面倒な事はしたくない。
  • コードを自動生成しだすと、中身が複雑怪奇になり易い。
    そもそもシンプルにまとまるなら、自動生成なんてイラナイって話もある。
    • 最近、WSDL2Javaが吐いたコード見てゲンナリしたですよ。
  • ツールを使うのが面倒。
    • Excel最強伝説とか、ほんと勘弁して欲しい。後、ejbcとかejbcとかejbcとか(どちらにしても、超個人的な恨み)
    • 逆に言うと、この問題はIDEにツールが統合されてるなら、気にならないかも…。

CGLibやらJavaAssistやらを使って動的にやってるとは言え、要はコードの自動生成な訳で。
VM上にしか存在しない.classファイルみたいな位置付けって、怖いな…と思う事も。
動的なコードの生成をコーディングするのって、一種のメタプログラミングかな…とも思う訳ですよ。
それって大丈夫か?とか。何がどうなると大丈夫なのかって話はあるけども。


只、今までは動的なコードの生成って、リフレクションの延長線上で考えてたんで、
そもそも、コードの自動生成とは思ってなかった、っつう話もある訳ですよ。感覚的には。
でも、S2で動的なコードの生成が、分り易い形でデーンと目の前に現れた事によって、
今までリフレクションで解決してきた問題を、全部動的なコードの生成で解決出来るジャン、
しかもパフォーマンスも高いし。みたいな…。
正直言って、S2でCGLib使ってるのを見るまでは、存在だけは知ってたけれども、使ってみたいとは思ってませんでした。ハイ。
だってさ、怖いんだもんよ。それにリフレクションだとコードの実装が超楽だし。
そうするとデスヨ、どこまで動的なコードの生成でやんのが妥当なのかって線引きが必要になるのかな…と。


主に自分の中で。


トレードオフになるような項目は幾つかある訳ですよ。

  • パフォーマンス
    • 普通に考えれば、パフォーマンスは向上する…筈。
      と言うか、リフレクションより遅くなるならやるメリットは無いですよ。
  • メンテナンス性
    • 誰でもがメタプログラミング出来る訳では無い。
      よって基本的には、メンテナンス性は下がると思われ。
  • バグに対するリスク
    • メンテナンス性とほぼ同義の筈なんだけど、
      動的に生成されているコードがバグってる時って、調査するのが難しいと思うんですよねぇ…。
      S2をJavaAssist対応した時、id:koichikさんはどうやってデバッグしたんだろう…。
      デバッグなんてしてないのかな…。明日聞いてみよう。


んで、例えリフレクションを実装の方針として選択したとしても、
状況が変わったら動的なコードの生成へリファクタリング出来るとエエなぁ…みたいな…所もある訳で。
単なるリフレクションから、動的なコード生成へのリファクタリングにも、パターンみたいなの無いかな…とか(未調査)。


こうなってくると、トレードオフの結果コードを自動生成するのも、アリなんじゃね?って感じになってくる訳で。
何がどうなるやら分りずらい動的なコード生成よりも、実行されるバイトコードに対応したソースコードがあった方が、
良い時だってあるんじゃないかと。
それで、話がループしだす訳ですよ、よって話は最初に戻る。


戻っちゃいけないので、何が間違ってたのか、考えてみたり。
動的なコード生成の位置付けを、既存のツールによるコードの自動生成とごっちゃにしたのがいかんかったのかな。
逆に、リフレクションの延長線上にあるようなコードの自動生成ならやってもエエんちゃうん?とか。
もっと書くと、リフレクションの延長戦上に無いコードの自動生成は、それがダイナミックに行われるか否かに関わらず、
やったらあかんのちゃうんかな。と。


そーすっと、リフレクションの延長線上にあるコードの自動生成って、何だ?って事に。
確実にリフレクションの延長だって言えるのは、S2のAspect実装。
逆説的に考えてみる。僕のイメージする悪しき自動生成コードの特徴は…。

  • 自動生成されたコードが、機能として完結していない。機能として完結させる為には、何らかのカスタムコードを記述しなければならない。
    • GenerationGapを使うようなコードの自動生成は、コレですな。
    • でも、S2のAOP実装だって、MethodInterceptorとしてカスタムコードを記述しとるなぁ…。
      MethodInterceptorを全く何も記述しないとしたら、機能として完結してると言えるのだろうか…。
      変な話、実装継承を前提としていたGenerationGapに対するリファクタリングでしかない…とか?
  • 力技でやろうとしている事を、ツールにやらせる事で、時間的なコスト誤魔化している。つまり、根本的な問題を解決していない。
    • システムにおけるホットスポットを内包してしまったりすると、そのツールのメンテナンスが超大変。


やっぱり良く分らなくなってきた…。何やろ…。続きはまた晩に。


ネタ元