COBOL屋の呪縛
今回の日本出張ではいくつかのプロジェクトの状況をみてきた。で、思ったこと。
「COBOL時代のデータ構造を引きずることで、生産性や保守性が落ちている」
フラグだらけのマスター
本物のコードをだすわけにはいかないので、すごく簡略化した例で説明したい。あるシステムを利用できるユーザのマスターテーブルがあるのだけど、そいつには「なんちゃらサービス利用可否フラグ」みたいなのがたくさんついているのね。
この方式の問題は以下の通り。
- テスト負荷
- フラグがあるということはそれをチェックするif文があるということ。
- if文があればテスト件数は最低2件は増える。
- 入れ子になれば、4件、8件...と増えていく。andやorでも同じ。
- コードの冗長性
- 「あるユーザがサービスAを使えるか」を調べる処理と「あるユーザがサービスBを使えるか」を調べる処理はほぼ同様になることは明らか。
- 「サービスAを使えるユーザ」を調べる処理と「サービスBを使えるユーザ」を調べる処理もほぼ同様になることは明らか。
- テスト負荷が高くて冗長性も多いということは、生産性や保守性が落ちて行くということ。
- サービス追加時の負荷
- ユーザ管理テーブルにカラムを追加し、検索SQLを書いて、テストして...
- テーブル構造とソースと同期を取らないといけないから、後戻りも大変。
COBOL屋の呪縛
で、こういう「大福帳」みたいなテーブルを設計するのって、RDBの知識が足らないCOBOL世代[*1]なのね。データはシーケンシャルレコードに詰め込んで保存しておけ、と叩き込まれた世代。レコード設計とテーブル設計は全然別のものなんだけど、その違いがわかってない。正規化されたテーブルを見ると「性能が下がる」とか言い出しちゃう。
正規化で別テーブルにするという概念がないから、オブジェクト指向の概念も当然、ない。にも関わらず、Javaとかで開発を進めてしまう。複雑なSQLでデータ検索して、Javaなのにカラム単位で代入していって、メソッドの引数もプリミティブ型ばかり...要はJavaの皮をかぶったCOBOLになってしまう。行数がふくれあがって、if文だらけで、インターフェースが粗雑だから入力チェックも重くなる。つまりテストが増える。ちうか、激増する。そして「テスト自動化なんて無理」と言い出す。
オブジェクト指向だと
多対多の関係にあるユーザとサービスを用意すれば良いだけのこと。Railsならusers, services, user_servicesの3テーブルで実装するでしょ。
class User < ActiveRecord::Base has_many :user_services has_many :services, :through => :user_services end class Service < ActiveRecord::Base has_many :user_services has_many :users, :through => :user_services end class UserService < ActiveRecord::Base belongs_to :user belongs_to :service end #あるユーザが使えるサービス一覧 User.find(id).services #あるサービスを使えるユーザ一覧 Service.find(id).users
大福帳方式と違って、サービス追加時にテーブルをいじくる必要はない。servicesテーブルにレコードを追加して、そのサービスを使えるユーザをuser_servicesテーブルに登録するだけでよい。「あるサービスを使えるユーザ」「あるユーザが使えるサービス」を調べるコードは「ほぼ同じ」ではなく「全く同じ」だが、行数はとても少ない。ちうか、一行。
呪縛から逃れるには?
どんなに優れたフレームワークでも、そこにあるデータ構造が腐っていたら、そのフレームワークの効果を享受できない。Railsであっても、大福帳テーブルでは意味がない。
となると、作り替えなのかな...
古いJavaアプリ(Tomcat以前のJ2EE直呼び、およびJBoss利用)をRailsで書き換えるというプロジェクトがあったのだけど、コードの行数は一桁(二桁減に近い、一桁)減ってしまった。減った行数もすごいけど、冗長性がほとんどなくなったことのほうが嬉しかった。その分、テスト負荷がへるわけだし、保守性も向上する。
まあ、これはJavaで数万行(もう少しで10万行)という小規模な対象だったから作り替えも簡単だったのだけど、100万行単位のを相手に「作り替えましょう」と言い出す勇気は正直なところ、ない。このあたりどうすればよいのかは考え中。
*1:および、その知識を引き継いだ世代