ダイコン時代の設計手法 - ユースケース分析
ユースケースの管理単位は、画面系なら関連のある複数の画面の組み合わせ、
帳票系なら1帳票、バッチ系ならジョブネット。
ユースケース単位に、ロバストネス分析を行って全体構造を把握します。
ロバストネス分析を行うときにもっと重要なのがコントロール。
コントロールはVO(〜を〜する)で記述します。
画面系の場合は、ほぼリンクやボタンのクリックのイベントが
1つのコントロールになります。
バウンダリでは画面の入出力項目、帳票の出力項目を定義します。
ユースケースでは具体的な画面は意識しない方がいいなんてことが
いわれたりしますが、それはきれいごと。
実際はこの段階でモックを作ったほうがユーザから多くのフィードバックを
引き出すことができ、仕様をつめることができます。
業務ロジックを含まない画面の仕様はここで固めます。
エンティティはER分析のインプットです。
コントロールはステートレス。
状態がある場合は、一時的な状態はバウンダリに、永続的な状態は
エンティティにマッピングします。
この辺は、UI層のモデルの話が絡んできます。
UI層のモデルは画面項目定義に反映され、エンティティはエンティティ定義に
反映されます。
エンティティ定義は、S2DaoではExcelで定義されデータベースとの
ラウンドトリップも実現する予定です。
コントロールはこの後、UI層のコントローラ、サービス層、永続化層に
マッピングします。
UI層のコントローラの仕様は、画面のイベント定義に反映されます。
サービス層の仕様は、サービス定義書に反映されます。
ユースケース記述(ルール記述)を使ってもいいのかもしれません。
- > id:akonさん
ルール記述書は、事前条件・事後条件・シナリオで構成されているもので、
詳しくはまた後で。
永続化層の仕様はSQL定義書に反映されます。
SQL定義書は、S2Daoの定義そのものであってもいいかもしれません。
S2Dao入門(1)
S2Daoではエンティティのクラスを作成するために2つの方法が提供されます。
- Excelにテーブル定義を書いて、DDL, エンティティのソースを書き出す。DDLを直接データベースに適用することも可能。
- 作成済みのテーブルのメタデータよりExcel、エンティティのソースを書き出す。
Excelとデータベースのラウンドトリップ開発も可能です。
これらの機能は、antのTaskとして提供されます。
今回は次のようなソースが書き出されたとします。
public class Emp {
public static final int dept_RELNO = 0;
private Integer empno;
private String ename;
private String job;
private Integer deptno;
private Dept dept;
getter, setterメソッド省略
}
Emp用のDaoを作成します。っていってもinterfaceです。
public class Dept {
private Integer deptno;
private String dname;getter, setterメソッド省略
}
それではさっそくコンポーネントの定義です。えっ。これだけですか。
interface EmpDao {
Class BEAN = Emp.class;
List getAllEmps();String getEmpByEmpno_ARGS = "empno";
Emp getEmpByEmpno(Integer empno);String getEmpsByJobDeptno_ARGS = "job, deptno";
List getEmpsByJobDeptno(String job, Integer deptno);void insert(Emp emp);
void update(Emp emp);
void delete(Emp emp);
}
EmpDao#getAllEmps()を実行すると次のようなSQL文が発行されます。
<component class="EmpDao">
<aspect>
<component class="org.seasar.s2dao.interceptors.S2DaoInterceptor">
</aspect>
</component>
OUTER JOINの構文は、RDBMSを自動的に判定して組み立てます。
EmpDao#getEmpByEmpno(7788)を実行すると次のようなSQL文が発行されます。
SELECT emp.empno, emp.ename, emp.job, emp.deptno, dept.dname AS dname_0
FROM emp LEFT OUTER JOIN dept ON emp.deptno = dept.deptno
7788の部分は実際はバインド変数が使われます。
EmpDao#getEmpsByJobDeptno(null, null)を実行すると次のようなSQL文が発行されます。
SELECT emp.empno, emp.ename, emp.job, emp.deptno, dept.dname AS dname_0
FROM emp LEFT OUTER JOIN dept ON emp.deptno = dept.deptno
WHERE emp.empno = 7788
EmpDao#getEmpsByJobDeptno("CLERK", null)を実行すると次のようなSQL文が発行されます。
SELECT emp.empno, emp.ename, emp.job, emp.deptno, dept.dname AS dname_0
FROM emp LEFT OUTER JOIN dept ON emp.deptno = dept.deptno
EmpDao#getEmpsByJobDeptno(null, 30)を実行すると次のようなSQL文が発行されます。
SELECT emp.empno, emp.ename, emp.job, emp.deptno, dept.dname AS dname_0
FROM emp LEFT OUTER JOIN dept ON emp.deptno = dept.deptno
WHERE emp.job = 'CLERK'
EmpDao#getEmpsByJobDeptno("CLERK", 30)を実行すると次のようなSQL文が発行されます。
SELECT emp.empno, emp.ename, emp.job, emp.deptno, dept.dname AS dname_0
FROM emp LEFT OUTER JOIN dept ON emp.deptno = dept.deptno
WHERE emp.deptno = 30
EmpDao#insert()を実行すると次のようなSQL文が発行されます。
SELECT emp.empno, emp.ename, emp.job, emp.deptno, dept.dname AS dname_0
FROM emp LEFT OUTER JOIN dept ON emp.deptno = dept.deptno
WHERE emp.job = 'CLERK' AND emp.deptno = 30
EmpDao#update()を実行すると次のようなSQL文が発行されます。
INSERT INTO emp(empno, ename, job, deptno)
VALUES(emp.empno, emp.ename, emp.job, emp.deptno)
emp.*の部分は実際はバインド変数です。
EmpDao#delete()を実行すると次のようなSQL文が発行されます。
UPDATE emp SET empno = emp.empno, ename = emp.ename,
job = emp.job, deptno = emp.deptno
WHERE empno = emp.empno
emp.*の部分は実際はバインド変数です。
このような開発者の心(method signature)を読んでSQLを自動生成する機能は
DELETE FROM emp
WHERE empno = emp.empno
S2Daoのうりの1つです。
自動生成の法則の説明はまた後で。