ジェネレータのつくり方とアーキテクチャ
今回作成したジェネレータ「scaffold_generator.rb」の構造について解説し、なぜそのような設計にしたのかを説明します。
最初にアーキテクチャの全体像を説明します。

「scaffold_generator.rb」はJudeで作成されたクラス図の情報を取得してきます。取得にはJRubyおよびLuRuJuというツールを使います。
読み込んだモデル情報はジェネレータ内部のクラスのインスタンスとしてメモリ上に保存されます。
データをすべて読み込んだらERBというテンプレートエンジンを使用しています。これにより、ソースコードの一部をプログラムで動的に変更させながら、各種のソースを自動生成することができます。
テンプレートエンジンERB
テンプレートエンジンのERBはRailsのViewを作成するためにも使われています。この使い方は単純で、例えば次のように利用します。
require 'erb' class Sample attr_reader :name def initialize(name) @name = name end def show_source erb = ERB.new template puts erb.result(binding) end def template <<EOS This is template Hey <%= @name %> This is end line EOS end end sample = Sample.new("ushio") sample.show_source
This is template Hey ushio This is end line
テンプレートの内容はdef templateメソッドの中身になります。
erb = ERB.new template
と指定すると、テンプレートを読み込みます。
erb.result(binding)
とすると、現在のクラスの属性をテンプレートに引き渡して、ビューを取得します。
今回はクラスの属性@nameをtemplateの中の<%= @name %>に代入した結果を返却します。
これを例えばファイルに吐き出せば、簡単にファイルを自動生成できます。
ジェネレータのつくり方
この手のジェネレータは大変簡単に作れます。特にLuRuJuとかERBのあるRubyは大変有利だと思います。言語仕様的にもRubyは、このようなアプリケーションの作成に融通が利きやすくなっています。
ジェネレータの作り方は簡単です。
- 手作りでジェネレートしたいアプリケーションを作成してみる。
- ジェネレートしたいアプリケーションのバリエーションを考える(今回だと、1対1、1対多…など)
- 手作りしたアプリケーションとバリエーションを比べながら、どの部分が可変でどの部分が変わらないか、また変わる部分もプログラミングで自動的に作成できるものはないかを考える。
- 固定の部分をテンプレート化し、可変部分をプログラムで生成できるようにする。
このような感じで設計すれば良いでしょう。
クラスの構造
今回作成した「scaffold_generator.rb」ですが、Judeで作成したダイヤグラムをJudeAPI-LuRuJu経由で読み込み、このアプリケーションの「モデル」に格納します。
汎用的にするには、JudeAPIの「モデル」と同じ「モデル」を「scaffold_generator.rb」にも作るのが、一番単純で、変更にも強そうに見えます。
しかし、今回の場合、筆者の考えではJudeの「モデル」を「scaffold_generator.rb」の「モデル」として採用すると、確かに一番変化に強い形にはなりますが、アプリケーションとして複雑になり、なおかつロジックも増えてしまいます。
これはなぜかと言うと、Judeの「モデル」はそもそもJudeというUMLツールを構築するのに必要だった「モデル」です。ですので、とても汎用的にいろいろな場面に対応できるように作られています。
今回の場合、クラス図からActiveScaffoldのいくつかのクラスファイルと、マイグレーションファイルを生成するという非常に限定されたアプリケーションになっているので、モデルもそれに都合が良い構造をしている方が楽にアプリケーションを構築できます。
「再利用性」や「汎用性」を考えると、考えない時と比べて、約2.5倍の工数が掛かると言われます。確かに、これらの考慮が必要な場面もありますが、今回は特定用途のためだけであり、新しいバージョンにしたい時は作り直しても大したダメージがない程度です。
こういう「再利用性」「汎用性」を取るか、現在の「工数」を取るかのトレードオフを悩んだ場合は、「シンプルさ」という考えを思い出しましょう。つまり今一番簡単な解決策を採用するのです。ただし、アプリケーション内で「重複」しないようにしていきます。
アプリケーションは、基本的に一番「シンプル」な作りで作っていきますが、コードが「重複」したら、リファクタリングして、重複がないような状態を保っていくようにするとよいでしょう。
話は長くなりましたが、早速Judeのモデルと、今回のアプリケーションのモデルを比較してみます。
