BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Javaアプリケーション開発におけるコード生成の役割

Javaアプリケーション開発におけるコード生成の役割

ブックマーク

原文(投稿日:2009/09/03)へのリンク

SpringSourceのSpring Roo、Skyway Builder Community Edition 6.3、Blu AgeのM2Springといった最近リリースされたコード生成ツールを見ると分かるのは、エンタープライズJavaアプリケーションの開発におけるコード生成の役割に再び関心が集まっているということだ。

コード生成も含んだモデル駆動開発(MDD)は、ますます関心を集めつつある。それは一般的なJavaアプリケーションで自動生成できるものがいくつもあるからだ。一般的なウェブJavaウェブアプリケーションはDAOのようなクラス、XMLのマッピングファイル、SpringやLog4Jの設定ファイルを利用するが、これらはどれも自動生成が向いている。

Rooは双方向型のコード生成フレームワークで、Springベースのウェブアプリケーションで必要となるデータファイルのほとんどを生成してくれる。Rooにはコマンドラインシェル、タブキーでの補完、前後関係を判断した操作、ヒント機能などが備わっている。他にもSpringアプリケーションの標準ディレクトリでの構成、ビルド設定ファイルの管理、ドメインオブジェクト作成、RESTベースのウェブユーザーインターフェースのためのウェブ用レイヤ自動生成などもできるようになっている。

Skyway Builder Community Edition 6.3は先月リリースされたばかりだ。この新しいバージョンではSpring MVC scaffoldingがサポートされており、SpringベースのJava CRUDアプリケーションを既存あるいは新しいドメインモデルから生成することができる。またSpring DSLとの連携、Spring MVCやSpring Web Flowを使ったシステムのコード生成もできる。Skywa Builderの商用版であるSkyway Builder Enterprise Edition 6.3ではIBM Rational Software Architectと連携してUMLを実行可能なSpringアプリケーションへ変換する機能も備える。他にもSpringサービスを利用するRIAアプリケーションを作るためのDWR(JavaScript/JSONを利用するためのフレームワーク)のサポート、JET(Java Emitter Templates)を用いたコード生成用テンプレートをプロジェクトレベルでカスタマイズもできる。

IBMのMDDツールであるRational RhapsodyはUML 2およびSysML、要件トレーサビリティ、コード生成、テスト容易化設計(DFT)をサポートしている。双方向型のモデル駆動ツールであるRhapsodyは、要求図、ユースケース図、シークエンス図、アクティビティズ、状態チャートによってプロジェクト要件を管理する。ユーザがモデルから要件へトレーサビリティリンクを張ると、自動的にトレーサビリティ、影響分析、カバレッジ文書作成がおこなわれる。またRhapsodyはモデル駆動テスト(MDT)もサポートしている。MDTはMDDの利点をテストプロセスにも導入しようとする新しい考えだ。エンジニアはMDTによって、繰り返しおこなう設計のシミュレーションをおこないプロセスにおけるエラーの早期発見したり、テストの自動化、要件に対応する設計の検証をおこなう要件ベーステストを組み込み、IBM Rational Rhapsody Automatic Test Generation Add Onを使った設計からのカバレッジテストの自動作成ができるようになる。

Blu Ageは最近リリースしたM2Springによってコード生成ツールの集団に入り込んだ。M2SpringはMagicDraw UMLとBlu Age Agile Model Transformationを組み合わせることでSpringアーキテクチャに基づいたモデリングおよび自動コード生成をおこなう。生成されるSpringウェブアプリケーションのクラスやデータファイルは、Service層(ビジネスルール、アプリケーションサービス、ウェブサービス)、Presentation層(ユーザインターフェース、ユーザロール、セキュリティポリシー)、Persistence層(ビジネスオブジェクト、DAO実装、DAO Finder)に分けられる。M2SpringがサポートするモデリングおよびJEEテクノロジはUML 2.2、OCL 2.0、XML 2.1、EMF UML 2.2.x XMI、Struts、Spring、Hibernateなど多種にわたる。

その他のコード生成を伴うJava開発ツールにはLombokとSpoonがある。Lombokではgetter/setterメソッドの自動生成、自動リソース管理(@Cleanupアノテーションを使用)、アノテーション駆動の例外ハンドリングの機能が提供されている。

InfoQはSpring RooプロジェクトのリードであるBen Alex氏とのインタビューで、Javaアプリケーションにおけるコード生成の役割について聞いた。氏が言うには、ほとんどのディベロッパがコード生成を日々使っていて、Eclipseの"generate getters/setters"機能を使うことも、他のどこかからコードをコピーしてきて貼り付けることもそれに含まれるという。一番の動機となっているのは特定の要件をなるべく速く実装すること、毎回最善の方法を再発見する手間を避けることだ。モダンなコードジェネレータはこれらの動機を具現化したものであり、一方では"generate getters/setters"をそれ以上に生産性に関わるレベル(アプリケーションの各種の層など)へ拡大したものにすぎない。そして"generate getters/setters"と同じように、利用が簡単で、重複するコードを取り除き、修正されたコードをなぜ修正されたか意識しないでも変更することができる。

コード生成フレームワークについて、ソフトウェアのアーキテクトおよびディベロッパが求めることができるのはどういったことだろうか?

ディベロッパはIDEを評価するのと同じようにコードジェネレータを評価すべきです。私がよくするのはこう自問してみることです。このソフトウェアは自分の生産性を大幅に向上させるだろうか?使って覚えるのは簡単か?多くの組織で使われているものか?これを使ってもすぐに使用を止めることができるか?今後も活発にメンテナンスがされる製品か?コミュニティはあるか?そのクオリティ(未解決の障害の数、エンドユーザのブログの多さ、アーキテクチャの透明性など)は高いか?プラグインやアドオンで機能を拡張することが簡単にできるか?

IDEについての問いの他にも、コードジェネレータ特有の問いも必要です。長い目で見た時にこのジェネレータはコードを付加的に修正したり自動的に変更したりする効果(たとえば、どのような双方向の変更がサポートされているか)が期待できるか?ジェネレータをコントロールする方法が、自分の知識・スキル・経験にとって刺激となるか?自分の使っているIDEとよく連携するか?IDEの将来のバージョンでも使えるか、あるいはジェネレータかIDEのどちらかの新しいバージョンをインストールすると使えなくなるか?生成されるコードは自然でクリーンで一貫性があり使えるものか?自然に使えるほど柔軟な使い方を備えているか?あることをする時、それを自動的におこなってくれるか、あるいは自分で思い出さないといけないか?コードジェネレータ(あるいはプラグインやアドオン)の新しいバージョンによってプロジェクトが破綻してしまう可能性はあるか?

ほとんどのアプリケーションでは、自動生成が難しく人手で書く必要のあるビジネスロジックやバリデーションルールが存在する。コード生成ツールはこの問題をどう解決するだろうか?

Hunt氏とThomas氏は著書The Pragmatic Programmersでジェネレータの2つのタイプについて述べています。それがパッシブ型とアクティブ型です。

パッシブ生成は生成を一度だけおこない、それ以降は人の手でメンテナンスされることになります。多くのディベロッパがIDEの"generate getters/setters"のような機能によるパッシブ生成を利用しています。パッシブ生成での出力は、生成コマンドが実行される時に、何を生成するかディベロッパが指定することで決まります。パッシブ生成の問題は、自分たちで未来永劫コードをメンテナンスしないといけないことです。この型のジェネレータは生成したコードを更新しません。具体的な問題だと、もし生成したコードが依存する箇所を変更してエラーが起きるようになった場合、該当するコードを消して再度生成するということがありますが、これは一般的におこなわれていることです。

一方、アクティブ生成は実行される度に出力をおこないます。アクティブ生成ではコントロール情報を保存する手段が提供されることで、後で実行したり求められる結果を作成することができます。そのコントロール情報の手段は非常に多岐にわたりますが、一般的には自動作成されたメタデータ(たとえばフォームのソースコードのパースとバインド)とJavaアノテーションやJavaDocタグ、XMLファイル、GUI設定で決められたユーザ設定の組合せが用いられます。きちんとした(Rooのような)アクティブ型ジェネレータでは、普通ソースファイルにカスタムロジックを埋め込むだけで、ジェネレータがそれを検知して変更に関わるファイルだけを自動的に更新します。カスタムコードを書くということをシステムに知らせる必要はありません。それはRooのようなシステムを使う上では当然のことだからです。

アプリケーション開発プロセスにおいて自動生成も手動コーディングも両方が必要な場合において、アーキテクチャ面および設計面でのグッドプラクティスを促進するにはどうすればよいか。

多くのジェネレータがアプリケーションのスケルトンを作るのに使われます。これはジェネレータの中に埋め込まれたベストプラクティスが生成されたアプリケーションに反映されるということです。その後もそれと同じアーキテクチャパターンが反映されますので、ジェネレータを普通に使っていればこれらのベストプラクティスも継続的に促されます。このような一貫性は、異なるスキルセットをもつチームがいる組織や長期のメンテナンスが必要なプロジェクトにおいて大きなメリットとなります。

ここでユーザから上がる大切な疑問は、ジェネレータに埋め込まれたプラクティスが本当にベストプラクティスであるかということです。複数のプロジェクトで複数のユーザによって利用されるジェネレータは、設計のフィードバックを多く取り込んでいるので大抵の場合は最良のものです。これから使おうとするユーザは、実際に出力されるアーキテクチャをチェックして、テスト容易性、メンテナンス容易性、設計の整合性、重複、依存性を批評すべきです。そして、優れたジェネレータのほとんどは著名な組織によって公に認められたアーキテクチャを備えているものです(たとえばSpringSourceはRooのアーキテクチャをベストプラクティスとして認証しています)。

Grailsのような(実行時にほとんどのコードを生成する)方法は従来のコード生成フレームワークと比べるとどうだろうか。

Grails、Rails、Djangoなどはパッシブ型のジェネレータ機能をもち、初期のアプリケーションスケルトンやウェブコントローラなどの作成を引き受けます。これらは実行時に(動的言語あるいはリフレクション技術を使って)アクティブ型のジェネレータによって生成されたものであるかのように働きます。

これらには文書化されているというメリットがありますが、動的言語の実行時技術であるため静的言語のコンパイル技術と比べると時間面で短所があります。これらは基本的に異なる開発パラダイムの話であり、あらゆるプロジェクトに対してどちらが優れているといえるものでもありません。SpringSourceはRooとGrailsの両方を手にしているので、エンドユーザは好きなパラダイムの方を選べますし、Spring製品の非常に素晴らしい生産性と品質を利用できるのです。

モデル駆動ソフトウェア開発全般の今後、特にコード生成についてはどう見ているのだろうか。

プログラミングをより高度に抽象化するという目標は続いていくはずです。しかし(新しいフレームワークの数およびそれを採用する人の数からわかる)現在のトレンドは、プログラミング言語のイノベーションとDSLに関心を集めているようです。DSLのアプローチは生成ツール間の主な相違点です。中にはシンプルなコマンド("create-controller"など)もあれば、より高度なシェル(タブキーでの補完、前後関係の認識、ヒント機能など)を持つものがあります。高度なシェルはユーザが学習コストを下げるだけでなく、強力(でより抽象化された)なコマンドの利用を簡単にする働きもあります。

これらのことを考えると、コード生成はソフトウェア開発において重要な役割を担い続けるでしょう。静的言語はまだまだ圧倒的に多数派であり、そのような言語でプログラマの生産性を高めるにはコード生成の技術が必要です。動的言語に特化したフレームワークであっても、初期アプリケーション構築や重要なアプリケーションデータファイルなどの箇所でコード生成が利用されています。より高度なDSL、より先進的で便利なシェル、コンパイル単位の革新的な分割、双方向型の高品質なコード生成といったトレンドは、コード生成の進化を次へ進める土台となっています。

InfoQはSkywayチームのJack Kennedy氏ともインタビューをおこない、ソフトウェア開発におけるコード生成について聞いた。Scrum、XP、カンバンのようなアジャイル/リーンソフトウェア開発方法論を用いているプロジェクトでのコード生成の果たす役割についての氏はこう答えた。

開発方法論を用いているかどうかにかかわらず、パターンベースの生成および自動化のテクニックはソフトウェア開発ライフサイクルのすべてのフェーズ(分析、設計、実装、テスト、デプロイ)に影響を与えます。コードの生成は分析における概念要素を実際に落とし込むことから始まります。それらはパターンベースの設計でより特性をもったものになり、その設計をパターンベースのコードおよびテストユニットに変換します。アジャイル/リーンソフトウェア開発方法論では、パターンベースのコード生成および自動化のテクニックを使う動機が重要なものになります。これらの開発方法論は相対的に小さなプロジェクトで成功を収めていますが、ソフトウェア業界でより広く採用されるには、大規模に拡大でき、分散でき、複雑な配信の要件をも満たさないといけない試練があります。ほとんどの関心はスキルの高いディベロッパたちと大規模な作業効率の見積もりの精度が欠けていることに集まっています。パターンベースのコード生成および自動化のテクニックを開発ライフサイクルに導入すると、スキルの劣るディベロッパを投入するチャンスを組織のもたらし、広く認められた繰り返し利用可能な生成コンポーネントによって憶測の作業を減らすことができます。モダンな開発方法論では継続的インテグレーションと実行可能な開発イテレーションが要求されるため、機能するアプリケーションを最低限の時間投資と一貫した品質で作ることが極めて重要になります。

scaffoldingは時間と労力の節約になり、またコードの質を保つ。ほとんどのアプリケーションデータファイル(ウェブ、Log4J、Springの設定ファイルなど)が自動生成されるのもそのためだ。コード生成ツールの価値はこの点にあるのだろうか。

基本的に、ソフトウェア生成プラットフォームの価値は、対象となるデプロイ環境に必要な実装の調整にかかる開発タスクを自動化することにあります。そこでは一貫性、品質、再利用という価値が暗黙的にもたらされます。この価値はシステムへの入力要件にかかるコストとシステムからの機能的出力の価値とを比べることで評価されます。あらゆることでいえるように、その目的はコストを最小限にして価値を最大限にすることです。今までのコードジェネレータでは、その生成システムに入力されたひとつの"概念"についてしか生成物を作れませんでした。データモデリングに関していえば、このことは一般的にいってデータモデルがさまざまなフォーマットの中の一つによって作成されること、そしてそのデータモデルの"クラス"が生成されることを意味します。多くのUMLソリューションではもっぱらこのレベルの生成をおこないます。しかしながら、多くのチームで入力のコストに見合うだけの価値を出力されたものに見出せずにいます。

エンタープライズアプリケーションを作成するための実装技術がシンプルになり、ソフトウェア生成の世界が成熟してきたのにつれて、どれだけのものを自動的に生成する機能があるかが重要になってきました。CRUDの機能を備えたフルスペックのアプリケーションを生成して組み上げる機能は、十分価値あるものとなり、それにより多くのディベロッパがDSLや生成技術を利用できるモダンなRAD環境やツールを採用するようになりました。これは間違いなくひとつの転換点です。しかしそこにあるのは、まだ最終的な状態でも、理解されるべき目指す価値でもありません。この業界が有用な生成の選択肢や入力フォーマットについてより広範なサポートをするようになれば、多くのディベロッパが生成技術を採用する方向に移るでしょう。

この記事に星をつける

おすすめ度
スタイル

BT