Personal tools
You are here: Home ブログ 井上 Grails勉強会
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent entries
Apache2.4のリリース予定は来年(2011年)初め(あくまで予定) inoue 2010-12-23
Herokuの発音 inoue 2010-12-20
雑誌記事「ソフトウェア・テストPRESS Vol.9」の原稿公開 inoue 2010-12-18
IPA未踏のニュース inoue 2010-12-15
労基法とチキンゲーム inoue 2010-12-06
フロントエンドエンジニア inoue 2010-12-03
ASCII.technologies誌にMapReduceの記事を書きました inoue 2010-11-25
技術評論社パーフェクトシリーズ絶賛発売中 inoue 2010-11-24
雑誌連載「Emacsのトラノマキ」の原稿(part8)公開 inoue 2010-11-22
RESTの当惑 inoue 2010-11-22
「プログラマのためのUXチートシート」を作りました inoue 2010-11-19
「ビューティフルコード」を読みました inoue 2010-11-16
Categories
カテゴリなし
 
Document Actions

Grails勉強会

先週の金曜日にワークスとの共同勉強会がありました。題材はGrailsでした。諸般の事情により資料の公開はできません。GroovyもGrailsも基本的にゼロ知識で聞いたので、どちらの知識も僅か1時間程度の知識という前提で以下を読んでください。

Grailsの感想は、くやしいけど良くできている、です。くやしがるいわれは何もないのですが。今、何の偏見も予断も持たずに、Ruby on RailsとGrailsを見たら、Grailsを選んでしまいそうです。現実には、偏見と予断があるので、Railsを選択しています。

RubyとGroovyを見比べても、Groovyの方が良く見えてしまいます。Groovyは、書こうと思えば変数の型を明示できたり、Javaのクラスをそのまま使えたり、リテラル表現の簡易さはRubyと同程度にできそうだったりと、良いところだらけです。Rubyの方が良いところって何があるんだろう、と考えてしまうほどです。たぶん、あると思いますが。Rubyの良いところを探すために、Groovyを調べるのも不毛なので、特にGroovyを調べてはいません。

RailsとGrailsの違いで気づいたことのひとつが、Grailsの方は明示的なクラスの継承を書かない点です。Railsでは、例えばデータベースのテーブルに対応するモデルクラスは、次のようにActiveRecord::Baseクラスを継承して書く必要があります。

class User < ActiveRecord::Base
end

こう書くことで、usersという名前のテーブルを探して、必要なインスタンス変数やメソッドをUserクラスに定義します。

内部的にはinheritedという、子クラスが作られた時に呼ばれるコールバック関数がRubyにあり、Railsはそれを利用してします。次のコードを実行すると、Derivedクラスを定義したタイミングで、親クラスのinheritedメソッドが呼ばれます。

class Base
  def self.inherited(subclass)
    p subclass
    p subclass.class
  end
end

class Derived < Base
end

ActiveRecord::Baseクラスのself.inheritedメソッドで、子クラス(上の場合だとUserクラス)への参照と名前が分かるので、名前からテーブルを探して、子クラスを改造します。

Grails(Groovy)の内部的な仕組みは知りません。

もう一点、RailsとGrailsの違いで気になったのは、用語の差です。Railsのappディレクトリの下には、controllers、helpers、models、viewsの4つのディレクトリがあります。このうち、helpersはビューの下請け処理用のディレクトリなので、置いておきます。その他は、いわゆるMVCアーキテクチャの用語そのままです。

Grailsはcontrollers、domains、services、viewsの4つのディレクトリがあります(helpersがあったかは未確認)。GrailsのdomainがRailsのActiveRecordに相当します。個人的には、Grailsの区分の方が好みです。

Railsのアプリで、いわゆるビジネスロジック的な処理をどこに書くべきかを最初迷いました。viewsの下に書くのは論外なので、controllersの下かmodelsの下です。コントローラが太るのは好みに合わないので、消去法でmodelsの下になりました。しかし、個人的には、データベースと結び付いたクラスとそうでないクラスの間に線を引きたいと思いました。そのため、modelsディレクトリの下にfoo_service.rbのような、サービスクラスを作ることに決めました。

Grailsのことは知りませんでしたが、Grailsと似た区分をしていたことになります。もっとも、Grailsの「ドメイン」の用語の使い方は微妙です。ドメインがそのままデータベース定義に等価になるのは、用語として微妙に感じます。ActiveRecordパターンだからそういうものだ、と言われてしまうと返す言葉も無いのですが。

個人的な用語の好みは、データベースへのアクセス層と、Webアプリのロジックを提供する層のふたつに分けて、前者をエンティティ層、後者をサービス層と呼ぶスタイルです。ビジネスロジック層とサービス層に分けて、サービス層は薄いAPI層であるべきだという反論もあるかもしれません。その辺の宗教論争をする気はありませんが、個人的には、データベースに結び付いた層とそれ以外、という2層で充分だと思っています。つまり、Grailsの区分と同じということです。

勉強会の中でコントローラクラスのインスタンス化の話がでました。Railsのコントローラクラスのインスタンスオブジェクトは、リクエストごとに生成されます。JavaのServletでコントローラクラスがシングルトンオブジェクトなのと対照的です。

一見、リクエストごとにインスタンスを生成するRailsは非効率に見えます。実際には、コントローラクラスのインスタンスは軽いのであまり問題にならないはずです。更にもうひとつ仕掛けがあります。Railsのコントローラクラスのインスタンスは、そのままビューから参照されるコンテキストの役割も負います。Spring Frameworkの用語を使うと、「狭義のモデル」の役割を、Railsのコントローラクラスは負っているのです。ビューから参照したい状態があれば、Railsのコントローラオブジェクトは、ビューに渡すコンテキストオブジェクトを新たに作るのではなく、自分自身のプロパティに状態を持たせます。JavaのServletのコントローラしか知らない人にとっては驚きの動作ではないでしょうか。この動作により、結局、リクエストごとに必要なインスタンス化の回数はRailsでもJava Servletでも同程度になる気がします。裏は取っていませんが、Grailsのコントローラクラスのインスタンス化の仕組みもRailsと同じだと思います。

勉強会の中でクロージャの話題がでました。クロージャとクラスメソッドの関係について書いておきます。最初に結論を書くと、クロージャとクラスメソッドはそもそも異なる概念ですが(なので、関係ありますか、と聞かれたら関係無いが答えです)、クロージャを使うとクラスメソッド的なことが実現できます。クラスメソッド的なことを実現するのに、(C++やJavaのような)暗黙のthisパラメータによる手法以外に、クロージャでも実現できる、ということです。

クロージャを教科書的に言えば、「関数+環境」です。「関数」の部分は関数オブジェクトでも関数ポインタでもどちらで考えても構いません。「環境」は教科書的な意味はともかく、関数が定義された場所のスコープで見えている変数と考えてください。結果的に、クロージャは、関数が定義されたスコープで見える変数の状態を持った関数になります。「状態」は本当は「環境」と別に定義された専門用語ですが、ここでの状態は、一般用語に近い用語で考えてください。クラスのメソッドも、ある意味、状態を持った関数です。クロージャで、クラスベースのメソッドと同様のことができるのが想像できると思います。もちろん、クラスメソッドを実現するには、thisポインタの方が効率的でしょう。なので、Groovyのクラスメソッドがクロージャという点に関しては、理屈上の問題は無いと思いますが、真偽に関しては不明です。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/grails/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.