colloquial
model-driven development
( 日常会話的モデル駆動開発)
[email protected]
2007.06.27
ソフトウェア・シンポジウム 2007 新潟
grails の構成
JVM
groovy
jdk ライブラリ
spring, hibernate, ...
grails
Web アプリケーション
プラグイン
groovy とは
• JVM 上で走る動的オブジェクト指向言語
• Java との互換性
• 軽量言語
• 動的オブジェクト
Java との互換性
• ( ほとんど)すべてのJavaクラスをgroovyから使える
• つまりgroovyコードから任意のJavaメソッドを透
過的に呼べる
• ただしいくつかのキーワードが追加されている
• すべてのgroovyクラスをJavaから使える
• お互いのクラスをimplement/extendできる
軽量言語
• タイピング量の減少
• ';', imports が減らせる, returnがなくてもよい, ...
• 強力な機能
• GString, 正規表現
• collections, ranges
• switch-case の拡張, ...
• 動的な型付け (静的型付けも可能)
• 演算子の多重化
• スクリプト可能 (classなしでもよい)
動的オブジェクト指向
• すべてはオブジェクト
• クロージャ
• GroovyBeans
• メタ・プログラミング
• ビルダ
• expando
grails を使ってみる
• http://grails.org/
• 全部入り, インストールは簡単
• ただしEclipseはすぐには使えない
• 現在のバージョンは0.5.6
• 今年の10月に1.0が出ることになっている
grails の作業工程
✓ % grails create-app
✓ % grails create-domain-class
✓ JUnit でテスト
✓ % grails create-controller → scaffolding
✓ JUnit & Canoo でテスト
✓ カスタム・アクション/ビューの追加
✓ JUnit & Canoo でテスト
✓ 配布
grails のコマンド・ターゲット
% grails bootstrap
% grails bug-report
% grails clean
% grails compile
% grails console
% grails create-app
% grails create-controller
% grails create-domain-class
% grails create-job
% grails create-plugin
% grails create-script
% grails create-service
% grails create-tag-lib
% grails create-test-suite
% grails create-webtest
% grails generate-all
% grails generate-controller
% grails generate-views
% grails generate-webtest
% grails get-dependencies
% grails help
% grails init
% grails install-dojo
% grails install-ivy
% grails install-plugin
% grails install-templates
% grails package
% grails package-plugin
% grails package-plugins
% grails run-app
% grails run-webtest
% grails set-version
% grails shell
% grails stats
% grails test-app
% grails upgrade
% grails war
grails のアーキテクチャ
model
controller view
http req
create, refer, update, delete
render
fetch
GSP
wicket
hibernate
o/r map
spring junit canoo
quartz xfire
sitemesh ajax
GORM
w/ taglibs
...
ドメイン・クラス
•
% grails create-domain-class book•
ドメイン・クラスは基本的にはGroovyBeanに以下を追加したもの
•
関連•
制約•
RDBに自動的にマッピングされる•
GORMを利用(= groovy化されたHibernate, つまり事実上すべて のRDBを利用可能)関連
• static belongsTo = [ Class, ... ]
• static hasMany = [ property:Class, ... ]
• addToProp(bar)
• static mappedBy = [ property:"property", ... ]
• static embedded = [ "property", ... ]
制約
• static constraints = {
• property(key:value, ...)
• ...
• }
• 自前制約
• validator:{ ... } // クロージャの威力!
制約
• blank
• creditCard
• inList
• length
• matches
• max
• maxLength
• maxSize
• min
• minLength
• minSize
• notEqual
• nullable
• range
• scale
• size
• unique
• url
• validator
CRUD
• new Book(title:'book of tea', ...).save()
• def b = Book.get(1)
• b.author = 'Okakura Tenshin'; b.save()
• b.delete()
一覧
• Book.exist(1)
• Book.count()
• Book.list()
• max:, offset:, sort:, order:
• Book.listOrderByDateCreated()
問い合わせ
• 動的ファインダ
• 動的メソッド注入のおかげ
• 制約ビルダ
• groovy のビルダ機能のおかげ
動的ファインダ
• Book.find('HQL query')
• Book.findAll('HQL query')
• Book.findByAuthorAndDateCreatedBetween('Jon Doe', new
Date()-30, new Date())
• 'And' の場所に'Or'も使える
• 'find' の場所に'findAll'も使える
• 演算子としては
• Between, GreaterThan, GreaterThanOrEqual, IsNull,
IsNotNull, LessThan, LessThanOrEuqal, Like, NotEqual
• なければ'Equal'の意味
制約ビルダ
• def c = Book.createCriteria()
• def results = c.list {
• like('title', 'Grails%')
• between('dateCreated', new Date()-10, new
Date())
• }
• このビルダは内部的にはHibnernate Qeuryを生
成する
コントローラ
• % grails create-controller book
• ドメイン・クラスBookのコントローラは便宜上
BookController という名前に統一
• コントローラはhttp request/post/getを受け付ける
• def index = { ... } // デフォルト・アクション
• http://example.com/app/book/action/params
スキャフォルディング
•
ドメイン・クラスからCRUDアプリケーション用のコントローラ/ ビューを実行時に生成する•
def scaffold = Book•
以下のデフォルト・アクションを自動的に生成•
list, show, delete, edit, update, save<grails-0.5.6>/src/grails/templates/scaffolding/Controller.groovy
•
静的スキャフォルディング - テンプレートを*Controller.groovyにコ ピー•
動的スキャフォルディング - 動的にメソッドを注入•
さらに自前のアクションを追加/上書きできるアクション
• アクションは
• redirect(action:list, params:params), または
• キー/バリュー・コーディングされたモデルを
同名のビュー (例えば<app>/grails-app/views/
book/show.gsp) に渡す, または
• 明示的なrender "..."
情報の流れ
actionName: action actionUri
controllerName: BookController controllerUri
flash log params request reponse session
sevletContext
new Book(params) Book Request Attributes
controller
def action = { [book : new Book(params)] }
<html> <body>
${book.title} </body>
</html>
action.gsp
ビュー
• grails のビュー・テクノロジはGSP(groovy版JSP)
• <% ... %>
• "${...}"
• <g:...></g:...>
• スキャフォルディング用.gspテンプレート
<grails-0.5.6>/src/grails/templates/scaffolding/*.gsp
• GSP ベースのスキャフォルディングと他のビュー・
テクノロジ(例えばwicketなど)を併用できる
gsp のタグ
• Logical Tags
• * if
• * else
• * elseif
• Iterative Tags
• * while
• * each
• * collect
• * findAll
• * grep
• Assignment Tags
• * def
• * set
• Linking Tags
• * link
• * createLink
• * createLinkTo
• Ajax Tags
• * remoteField
• * remoteFunction
• * remoteLink
• * formRemote
• * submitToRemote
• Form Tags
• * actionSubmit
• * actionSubmitImage
• * checkBox
• * currencySelect
• * form
• * hiddenField
• * datePicker
• * select
• * localeSelect
• * textField
• * textArea
• * timeZoneSelect
• UI Tags
• * richTextEditor
• Rendering & Layout Tags
• * render
• * renderErrors
• * layoutHead
• * layoutBody
• * layoutTitle
• * pageProperty
• * paginate
• * sortableColumn (Since 0.5)
• Validation Tags
• * eachError
• * hasErrors
• * message
動的タグ・ライブラリ
• % grails create-tag-lib foo
• <app>/grails-app/taglib/FooTagLib.groovy
• def isAdmin = { attrs, body -> ... }
• <g:isAdmin> body </g:isAdmin>
フレームワーク統合
• grails には多くのフレームワークが統合されている
• つまりgrailsは裏に隠された多くのフレームワーク
の接着剤
• Spring, Hibernate, JSP, JUnit, Canoo, Mesh, Quartz,
XFire, Acegi Security, ...
• プラグインのメカニズムを使うと, これらのフレーム
ワークを置き換えたり, 別のフレームワークを追加す
ることができる
プラグイン
• % grails create-plugin
• プラグイン自身も実行時にgrailsに統合
されるgrailsアプリケーション
• 多くのプラグインが提供されている
• 例題としてgrails wicket pluginを見てみる
プラグイン
•
<plugin>/scripts/_{Install,Upgrade}.groovy•
<plugin>/grails-app/{controllers,...}•
<plugin>/FooGrailsPlugin.groovy•
def version = 0.1•
def name = "foo"•
def dependsOn = [ bar:1.0 ]•
def doWithSpring = { ... }•
def doWithWebDescriptor = { ... }•
def doWithApplicationContext = { ... }•
def doWithDynamicMethods = { ... }•
def artefacts = [ FooArtefactHander, ... ]•
...プラグイン・メタクラス
•
org.codehaus.groovy.grails.plugins•
GrailsPlugin (interface) extends ApplicationContextAware (Spring)➡
AbstractGrailsPlugin (abstract class) extends GroovyObjectSupport (groovy)➡
DefaultGrailsPlugin (concrete class)•
注: 上記はgroovyではなくJavaで書かれているBeanWrapper (Spring) GrailsPluginClass
FooPlugin
AbstractGrailsClass GrailsClass
plugin instantiate
DefaultGrailsPlugin interpret
AbstractGrailsPlugin
GrailsPlugin
DefaultGrailsPluginManager
AbstractGrailsPluginManager
GrailsPluginManager
* 1
MetaClass (Groovy)
ExapndoMetaClass
DynamicMethodsMetaClass
ProxyMetaClass 1