説教臭いブログ

中途半端なので、タイトル変えてみた。多分説教臭いと思う。

Java=保守的、Ruby=楽観的なようで着実。という印象について。

私の雰囲気から。

エンジニアの経験は、10年目くらい。で、言語の経験は大体・・・

Java ・・・最初の言語。コード量は30%くらい。
■VB6 ・・・ 次に自社でやった。5%くらい。
VB.NET ・・・ VB6が嫌だったので自分のPJから導入。50%かな。
PHPとか ・・・ 保守の必要で触った言語はもうちょっとだけ。
Ruby ・・・ 8ヶ月。

 

現在は、フリーランスでやってるんですが、1社目に小さなソフトハウス(?)で色々やって、2社目はプロジェクトリーダーしてました。フリーになってお世話になっている2つ目の現場で、Ruby on Rails の案件に未経験ながら入れてもらっています。

 

今回の話題は、最近感じる JavaRuby の開発の性質の違い。

 

尚、長い文章を読んでもらう時に先が見えない文章になると申し訳ないので、最初のほうで言いたいことをなるべく分かりやすく提示しておきたいなと思ってます。

 

まずは結論(言いたいこと)

Javaの開発の時には「いかに他人のバグに遭遇しないか」とか「あれはこういう問題があって」みたいな消去法でツールを選択し、いかにしてリスクを回避するのか?に一番重要なポイントを置いている印象があります。

Rubyの開発ではいかに既存のツール(プラグインなどのこと)を採用して自分で作る部分を減らすか?ということに意識が強いな、という違い。DRYという前提そのものだとは思うのですが、他人の作ったものに対するスタンスは「基本的に信用」、ですね。

Javaやってて、Rubyを始めた身としては、プログラマ目線でもビジネス目線でも圧倒的にRubyの周りにある「文化」の方が、みんなハッピーになれる!と。

で、その根底には「テストを書く」というのがあるんじゃないかと思います。というかテストファーストはいいよ!という価値観に至る経緯書いています。

 

Javaの話から。 

Javaの開発の時に基本設計レベルで会話していたのは、「どのMQ使う?安定してる?(または安定しているバージョンなのか?) 」とか、「フレームワークを使う?自分で作ったほうがいいんじゃない?」とか、「テストどうする?テスト仕様書のフォーマットは?」とかいう内容で、どういうことを意味しているかというと、「人の作ったものは信用ならない。」みたいな雰囲気があるなぁ、と。

 

去年まで入っていた会社でやっていた勉強会(CEO[兼CTO]主催)では、こんなような図(この図はメキシコの麻薬カルテルの相関図・・・)を使っての説明。

f:id:beco_ippei:20120606022915j:plain

『これはとあるシステムのメソッドの相関関係を表した図で、丸がメソッドで先が呼び出し、丸が大きいほど呼び出されている。この線が多くなると、修正に対する影響が大きくなるので、保守性を考えて共通化を排除することが望ましい』というような話をしてました。確かにこんなメソッド直したくない。

あと、A/Bの2つのサブシステムから利用されるライブラリCを修正する場合、Aの要件に合わせたCのあるクラスの修正が、Bでは仕様が異なるため既存コードをコピーして新しいクラスを・・・・、ということになることも、共通化しなければ起こらない、と。

その時はイマイチ腑に落ちず、意見も出しましたが、最初から上記理論を肯定する文脈で話がされているので、何言ってるの?そんな訳無いじゃん、という雰囲気に。

・・・・。

 

また、新たなサイト開発を行うことになった時には、こんなことを言われました。

『既存のFWは色々と問題があって、要求にFitしないのが多い。なので、FWは自作しよう。そうすれば、ブラックボックス化されたフレームワークやライブラリのバグへの対応は行わなくて良い』

つまり、自分(達)のコードが一番信用できるんだ、という話でしょうか。

 

対してRubyの案件では

(といっても1つしかやってませんが)積極的にGemを導入して、「誰かが既に作った機能を一から作るのはイケてない」となります。別にプラグインというレベルでなくても、同じことを何度も繰り返して記述することすらDRYじゃないと、となってリファクタされたり。

少しやりすぎ感を感じることもありますが、Strategyパターンでカバーできない類似機能は、メタプログラミングで書いたりして結構バサバサと直されちゃいます。可読性が下がることもあるので、必ずしも良いとは思いませんが。

 

書きながら考えてみて、2点。

なぜ、このような感覚の違いがあるのでしょうか?

1,Javaは古くからあって成長しながら、古い資産も多く使われている

2,Rubyでは、TDDやBDDが普通。テスト書いてないのは未完成と同じ

  (という位の感覚が一般的なのかな、と。Javaはまあ浸透してませんよね) 

特に、2はとても大きくてテスト無かったら(というか浸透していなかったら)品質に関する意識もちょっと違ってきそうな気がします。

実際、ネットワーク図を出した話もある程度テストが書かれていたら「影響が・・・」というのはテストで検出できるので、大きなリスクにはならないはずだし、共通化を排除すると「同じ仕様を前提に設計される別の機能」というのもあるはずで、同じ動きを期待する処理を2箇所に書く、という場合に変更が2箇所になる。10箇所の場合は10箇所を変更するのか?さすがにこれはちょっと。

ただ、その場合でもテスト書いてて仕様変更でテスト直せばいいですが、テストコードのメンテも大変なことになる。やっぱりダメかな。なんであんな極論を言ってたんだろう?エンジニアとして遙かに高いレベルにいるはずなのに、時々理解しがたい言動があって結構付き合いにくい人だったな、と改めて思い出します。

 

改めての結論は、

テスト書いておけばデグレードを防ぎやすくなるし、リファクタできるし、何よりも品質に対する自信が生まれる。そうした習慣が広まれば、おそらく他人のコードも信用して読むことができるようになるし、疑うより先に信じる感覚が生まれるんじゃないでしょうか?ということ。

みんな同じような悩みや苦労を重ねて、結果として色々なソフトウェア資産が生まれているはずで、その資産を利用しないとまた同じ経験をすることになって、とあまり幸せな感じはしませんね。実際にやっぱり保守する資産(というか世間では負債と呼ばれる)=コードが増えるので、あんまり得する人はいませんでした。

(一部の意識の高い方を除いた)Javaエンジニアの方は、いろんなFWを覚えるよりも先にテスト書きましょう。で次にFWやらライブラリやらを覚える。で楽したいですね。

 

例外がいくつか。

とはいえ、そうなる背景もいくつかあって、

A、Java案件では業務系、大規模、ウォーターフォール的、分業化 といった状況があってその場合は大抵が経験の浅いプログラムしか出来ない人が実装する。となると、テストを書くスキルが無い。

B、非エンジニアのマネージャー/上司は、テストコードによって総コストが下がる、ということを理解できない。

C、受託の案件が多い。となると、保守性を意識したコードを書く必要が無いとベンダーが感じる場合、保守しやすいコードを書いてコスト増やすのは無駄に近い。

D、Javaの書きやすいテストフレームワークに出会わない。

E、その他(                        )

そんな場合は、テスト書くことを推し進めることができるリーダーの下でやるか自分がなるかしないと、ですかね。そんな話も今度書きたいですね。

しがらみやら制約が多いのもJava案件の特徴でしょうか。
それははもうここで語ることではないですね。。。