ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

ソースコードジェネレータコミュの評価してください

  • mixiチェック
  • このエントリーをはてなブックマークに追加
ジェネレータを作ったので、時間に余裕がある方、評価していただけると嬉しいです。
簡単に説明すると、Genというテンプレートクラスを継承してジェネレータクラスを作成します。継承する立場で、Genの仕様は十分だろうか、他に必要な要素はないかについての感想や評価をしてください。特にEntityの要素について指摘してもらえると助かります。

/**
* Entityで保持されるクラス要素からクラスを自動生成する
* @author chun
*/
public class Gen {
private Entity entity;
public Gen(Entity entity){
this.entity=entity;
}
/**
* Entityを取得
* @return Entity
*/
protected Entity getEntity() {
return entity;
}
/**
* ヘッダー行を自動生成
* @param buf
*/
protected void generateHeader(StringBuffer buf){
Entity e=getEntity();
buf.append("// id=").append(e.getId()).append("\n");
}
/**
* クラスのJavadocを自動生成
* @param buf
*/
protected void generateJavadoc(StringBuffer buf){
Entity e=getEntity();
buf.append("/**\n");
buf.append(" * ").append(e.getNameJp()).append("\n");
buf.append(" * @orner : ").append(e.getOrner()).append("\n");
buf.append(" * @designed date : ").append(new Date(e.getCrDt())).append("\n");
buf.append(" /*\n");
}
/**
* クラスシグニチャを取得
* @param buf
*/
protected String getClassSigniture(){
return "public class "+getEntity().getName();
}
/**
* ソースコード(内部)を自動生成
* @param buf
*/
protected void generateSrc(StringBuffer buf){
buf.append("//********** ここからフィールドの定義 *****************\n");
generateFields(buf);
buf.append("//********** ここまでフィールドの定義 *****************\n");
buf.append("//********** ここからコンストラクタの定義 *****************\n");
generateConstructor(buf);
buf.append("//********** ここまでコンストラクタの定義 *****************\n");
buf.append("//********** ここからメソッドの定義 *****************\n");
generateMethods(buf);
buf.append("//********** ここまでメソッドの定義 *****************\n");
}
/**
* コンストラクタを自動生成
* @param buf
*/
protected void generateConstructor(StringBuffer buf){
Entity e=getEntity();
buf.append("\tpublic ").append(e.getName()).append("(){\n");
buf.append("\t\tsuper();\n");
buf.append("\t}\n");
}
/**
* フィールドを自動生成
* @param buf
*/
protected void generateFields(StringBuffer buf) {
}
/**
* メソッドを自動生成
* @param buf
*/
protected void generateMethods(StringBuffer buf) {
}
/**
* ソースコードを自動生成
* @param buf
*/
public String generate(){
StringBuffer buf=new StringBuffer();
generateHeader(buf);
generateJavadoc(buf);
getClassSigniture();
buf.append(getClassSigniture()).append("{\n");
generateSrc(buf);
buf.append("}\n");
return buf.toString();
}
public static void main(String[] args)throws Exception{
EntityImpl impl=new EntityImpl();
impl.setName("Hoge");
impl.setId("id1");
impl.setNameJp("ほげ");
impl.setOrner("たろ");
impl.setType("GenEntity");
impl.setCrDt(new Date().getTime());
Gen gen = new Gen(impl);
String str=gen.generate();
System.out.println(str);
}
}

public interface Entity {
/**
* クラスID
*/
String getId();
/**
* クラス名(英名)
*/
String getName();
/**
* クラス名(和名)
*/
String getNameJp();
/**
* クラスステータス
*/
Integer getStatus();
/**
* クラス定義更新日
*/
Long getUpDt();
/**
* クラス定義作成日
*/
Long getCrDt();
/**
* クラス定義取り消し日
*/
Long getRmDt();
/**
* オーナー
*/
String getOrner();
/**
* クラスタイプ
*/
String getType();
}
public class EntityImpl implements Entity {
private String id;
private String name;
private String nameJp;
private Integer status;
private Long upDt;
private Long crDt;
private Long rmDt;
private String orner;
private String type;
public EntityImpl(){}
public String toString(){
return id+","+name+","+nameJp+","+status+","+upDt+","+crDt+","+rmDt+","+orner+","+type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNameJp() {
return nameJp;
}
public void setNameJp(String nameJp) {
this.nameJp = nameJp;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Long getUpDt() {
return upDt;
}
public void setUpDt(Long upDt) {
this.upDt = upDt;
}
public Long getCrDt() {
return crDt;
}
public void setCrDt(Long crDt) {
this.crDt = crDt;
}
public Long getRmDt() {
return rmDt;
}
public void setRmDt(Long rmDt) {
this.rmDt = rmDt;
}
public String getOrner() {
return orner;
}
public void setOrner(String orner) {
this.orner = orner;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

コメント(11)

いよいよ自作ですね。がんばってください。
規模が大きくなってきたらテンプレートエンジンを使うのもいいですよ。
(私はシンプルな velocity を選択しました。)
思いついたままに書くと
・クラス名は、simpleNameとpackageに別けておくと楽
・クラスIDはプロジェクト固有のものなら不要と思われます。
プロジェクト固有の情報は別のインターフェイスにするのも手かと思われる。
・オペレータ(自動生成を実行した人)
・ジェネレータのバージョン
・ソース情報(Entityにセットする為に読み込んだファイルの情報、タイムスタンプ、ファイル名他)
・シリアルバージョンUIDは必要になることが多いのでGeneratorの抽象クラスに欲しい
・Javaソースファイルのエンコードの指定

あと出力対象をクラスに絞ってしまうのは勿体無いので、こんな構成はどうでしょう?
・interface GeneratableEntity
・interface ClassEntity extends GeneratableEntity
・interface Generator
・public abstract class BaseClassGenerator<E extends ClassEntity> implements Generator
・interface DAOClassEntity extends ClassEntity
・public class DAOClassGenerator implements Generator<DAOClassEntity>
> ynieさん
がんばります。

> なかのさん
アドバイス、ありがとうございます。
すばらしいです。
とても参考になります。
> なかのさん

自動生成する場合、その要素を定義した人と自動生成を実行した人の名前を管理するのはいい考えと思いました。登場人物の候補は

・Entityにデータをセットした人
・Genのサブクラスを作った人
・自動生成を実行した人

ですね。

GenのサブクラスとしてDaoGen(EntityはDaoGenEntity)とJspGen(EntityはJspGenEntity)を作って見たいと思います。


> ・シリアルバージョンUIDは必要になることが多いのでGeneratorの抽象クラスに欲しい

これって自動採番とかすればいいんでしょうか。
シリアルバージョンUIDの採番のノウハウ知らないのでググらなきゃ。
ぼくの場合は、設計書とテンプレートを合体させてソースを生成しているので、次のような情報をファイルのヘッダに出力しています。
・設計書のファイル名、タイムスタンプ、作成者
・テンプレートのファイル名、版数、作成者
・自動生成したファイル名、日時、担当者

シリアルバージョンUIDには生成時の時刻のlong値を使っています。つまり、自動生成したファイルの日時が違ったら、内容に変更が無くても、直列化復元出来ない仕様にしています。
いま、JSPのジェネレータを作っているのですが、JSPこそジェネレータうってつけのモジュールじゃないか、という気分になってきました。

専用ジェネレータを作るか、汎用テンプレートエンジンを使うか、迷うところですよね。少しだけ比較してみました。捕捉があればお願いします。

専用ジェネレータのメリット・デメリット
Java知ってれば使える。やろうと思えばなんでも出来る。フォーマットしてやるのがいちいち面倒くさい。コンパイルが必要。

テンプレートエンジンのメリット・デメリット
お作法を覚える必要がある。知らないと保守出来ない。フォーマットの変更が割と気軽に出来る。コンパイル不要。
僕が作ろうとしてるのは専用ジェネレータの方なのでなかのさんとは少し方向が違いますが、根底は一緒と思います。イメージはこんな感じです。

1.ジェネレータ開発者は「ジェネレータ」を開発する
2.システム開発者は「設計情報」を定義する
3.ジェネレータ運用者は「設計情報」を「ジェネレータ」に入力し「ソース」を自動生成する
4.システム開発者は「ソース」を確認し、イメージと違うなら2に戻り「設計情報」を再定義するか「ソース」を修正する

現場のニーズに『コストのかからない再利用』があります。こいつをやっつけるのに有効なのがこうした「ジェネレータ指向開発」と思っています。近い将来、こうした概念が広まることで開発効率とシステム品質が飛躍的に向上すると確信しています。
補足です。
9の「ジェネレータ指向開発」は造語です。
通常の開発は「設計情報を元にアプリを実装」しますが、ジェネレータ指向では

・設計情報を元にアプリを自動生成するジェネレータを実装する
・既存のジェネレータがあれば再利用またはカスタマイズする
・既存の設計情報があれば再利用またはカスタマイズする

となる、という意味です。

ジェネレータはプロセスを変える、というのは以前から思っていたことでしたが、最近いろいろな人とお話させて頂いて確信に変わりました。しかし、プロセスが変われば失敗も増えるはずです。その意味で、成功レポートをできるだけ収集しておく必要があります。これは時間がある時に調査しようと思っています。

そういうサイトをご存知であれば教えてください>皆様

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

ソースコードジェネレータ 更新情報

ソースコードジェネレータのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。