これからはじめるRuby on Rails

2010年10月6日(水)
川尻 剛

はじめに

Rubyと出会ったころ、その簡潔さに感動した著者は、「ここまで自然言語に近い形でプログラムが書けるのであれば、インターネットとPCの違いすら理解しない妻でも、少しはプログラミングができるようになるかもしれない」と、家庭での普及に挑戦したことがあります。

その試みは、渡した入門書を「はじめてのRUBAI」と読まれた時点で頓挫したわけですが、その経験から「Rubyの文法に従ってはいるが、何やら他言語の匂いを感じるコード」のことを、Rubyの潜在力を生かしきれていないという意味で「RUBAIコード」と呼ぶことにしました。

そして、社内のさまざまな分野のプログラマにRuby開発を指導してみて分かったのは、"RUBAIコード"には、実装レベルの間違いと、設計レベルの間違いがあるということです。

実装レベルの間違いとは、処理を他言語の習慣に従って記述することで引き起こされます。Javaプログラマがハッシュのプロパティを1つずつ代入したり、Cプログラマがメソッドの先頭で全変数を宣言したりしてしまうようなことを指します。これは、単純にRubyの文法やAPI(Application Programming Interface)を知っていないことに起因していますので、経験とともに改善されていくようです。

危険なのが、後者の設計レベルの間違いです。慣れ親しんだほかのWebアプリケーション・フレームワークと同じ発想で、Railsアプリケーションを設計してしまうことを指します。こちらは、一度走り始めてしまうと、途中でどんなに改善しても、結局は「Ruby on Strutsもどき」などになるだけで、Rails本来の生産性の高さを発揮せずに終わってしまいがちです。これを避けるためには、あらかじめアーキテクチャの違いを知っておくしかありません。

本連載は、データベース(DB)アプリケーション開発に着目し、RailsにおけるO/Rマッピング・ライブラリである「ActiveRecord」と、その周辺の話題に焦点を絞って解説します。第2回までは、主にJavaプログラマなどを対象に、Railsアプリケーション設計の注意点と、ActiveRecordの基本的な使い方を解説します。第3回と第4回は、Rubyプログラマ向けに応用テクニックを紹介していきます。

ActiveRecordとアクティブ・レコード・パターン

Railsアプリケーションは、従来と同じ方法で設計すると危険です。Railsは、基本的には、命名規則など、Webアプリケーション開発の良い習慣を取り入れたものになっています。このため、これまでの開発手法の延長上にあるはずです。しかし、試しに既存のアプリケーションをRailsに置き換えてみるとすぐに分かると思いますが、従来の設計書がさっぱり使えないのです。

著者自身も「同じMVC(Model View Controller)フレームワークなのだから、大きな違いはないはず」と考え、ユースケースと画面遷移図を受け取ってはみたものの、その書き直しに大部分の時間を費やした、ということが多々ありました。何が違うのかを考えてみると、原因はどうもActiveRecordにありそうです。

ActiveRecordは、Martin Fowler(マーチン・ファウラー)氏の書籍『Patterns of Enterprise Application Architecture』(PoEAA)で紹介された、アクティブ・レコード・パターンを実現したものです。「データベース・テーブルまたはビューの行をラップし、データベース・アクセスをカプセル化して、データにドメイン・ロジックを追加するオブジェクト*1」と定義されています。

  • [*1] 『Patterns of Enterprise Application Architecture』(Martin Fowler 著、2002年、Addison-Wesley Professional)/『エンタープライズアプリケーションアーキテクチャパターン』(Martin Fowler 著、テクノロジックアート 訳、長瀬嘉秀 監訳、2005年、翔泳社)

アクティブ・レコード・パターンは、データ・ソース・レイヤーに位置しますが、ロジックの置き場所にもかかわります。まずは、ドメイン・レイヤーとの関連から見ていきましょう。

アプリケーションを設計する際には、大きく分けて、2つのアプローチがあります。1つは、プロセスに注目する方向です。もう1つは、データを中心とする方向です。

前者(プロセスに注目する方向)は、主にトランザクション・スクリプトと呼ぶパターンで実現されます。これは、データと振る舞いを分離し、振る舞いを手続き型の関数のように定義するものです。トランザクション・スクリプトの特徴は、ロジックの重複が多くなる反面、シンプルで分かりやすいことです。

後者(データを中心とする方向)は、ドメイン・モデルと呼ばれるパターンで実現されます。データ自身に振る舞いを持たせることによって、再利用性や拡張性を高めます。特徴は、どこまでも凝ることができる点です。

ドメイン・モデルは、大きく2つに分類できます。(1)「豊富なドメイン・モデル」は、継承やGoFパターンの導入といったオブジェクト指向のテクニックを駆使して、ビジネスそのものをモデリングします。(2)「シンプルなドメイン・モデル」は、テーブルとクラスを対応付ける程度にとどめます。

アクティブ・レコード・パターンは、シンプルなドメイン・モデルを実現します。同パターンの特徴は、テーブルやビューごとに操作を集約し、再利用することです。

このように、前者(トランザクション・スクリプト)と後者(ドメイン・モデル)には、それぞれ特徴があります。日本の受託開発の現場では、トランザクション・スクリプトが採用されることが多いようです。理由は、よく指摘されるように、

  • ほかのロジックの動作を気にする必要がないので、人海戦術に向く
  • 日本の業務の大部分がワークフローなので、処理とデータを分けた方が現実世界に近くなる
  • そして何より、顧客の承認を得やすい

といった点が挙げられます。

承認が得やすい理由は、処理が本質的に手続き型言語の関数であるため、実際の業務の流れに近く、顧客にとって分かりやすい、というものです。

一方、Rubyは、型とコンパイラがありません。このため、そもそも大規模開発にはあまり向きません。少数精鋭で、コミュニケーションをとりながら、ロジックを再利用していくスタイルに向いています。こうした理由から、アクティブ・レコード・パターンが採用されています。

アクティブ・レコード・パターンを現場で使う際に起こりがちは問題は、データ指向のパターンに対して、プロセスを中心とした設計をしてしまうことです。

例えば、ユースケースは、サービス・レイヤーと対応付けることができます。このため、トランザクション・スクリプトとは非常に相性が良いと言えます。しかし、トランザクション・スクリプトにおいてクラス図が役に立たないように、ドメイン・モデルでは、「何の振る舞いなのか」というところまで設計しないと、活用できません。

株式会社日立ソリューションズ

技術開発本部 Rubyセンタ所属
1977年生まれ。入社後、自社フレームワークの開発を経てRIAの調査などに関わる。
最近は「お客様とチームがより幸せなるマネジメント」を目標としてプロジェクトマネジメントを勉強中。著書に「Java開発者のためのAjax実践開発入門」(共著)など。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています