区分値のグルーピング (GroupingMap)

区分値機能の中で、とても重要なものです。

ぱっと見イメージ

e.g. サービスが利用可能なステータスのグルーピング定義 @classificationDefinitionMap.dfprop
map:{
    ; MemberStatus = list:{
        ; map:{
            ; topComment=会員ステータス; codeType=String
            ; groupingMap = map:{
                ; serviceAvailable = map:{
                    ; groupComment = サービスが利用できる会員
                    ; elementList = list:{正式会員;仮会員}
                }
                ...
            }
        }
        ; map:{ ... }
        ...
    }
    ...
}
e.g. サービスが利用可能なステータスのグルーピング判定 @classificationDefinitionMap.dfprop
// サービスが利用可能な会員だったら (正式会員、仮会員)
Member member = ...
if (member.isMemberStatusCode_ServiceAvailable()) {
    ...
}

// サービスが利用可能な会員を検索 (正式会員、仮会員)
MemberCB cb = new MemberCB();
cb.query().setMemberStatusCode_InScope_ServiceAvailable();
cb...

区分値のグルーピング概要

さーて、さて

こんなif文、書こうとしてたら、ちょっと待って! (見かけたら要注意)

e.g. そのif文、ちょっと待った! @classificationDefinitionMap.dfprop
if (正式会員 || 仮会員) {
    ...
}

この条件を、業務的に一言で表せないでしょうか? (他でも再利用したいのではないでしょうか?)

正式会員と仮会員
は、"サービスが利用可能な会員" と言える (そのつもりの条件である)

なら、こう書きたいですね。

e.g. プログラムではこう書きたい @classificationDefinitionMap.dfprop
if (サービスが利用可能な会員) {
    ...
}

プログラム上では業務的な目的だけを指定し、それを実現する手段は一元管理しておけば、いざ "サービスが利用可能な会員" が増えたときに、影響範囲がとても少なくなります。現実的な区分値変更ができるようになります。

そこで GroupingMap

DBFluteの区分値では、複数の区分値要素を一つにまとめて扱うことができます。@since 0.9.9.7A

dfpropにて、topCommentと同じmapの要素として、groupingMap を追加します。 そこで、コメントと要素のリストを指定します。要素の指定は、コードではなく要素名 (e.g. 正式会員, Formalized) となります。

e.g. サービスが利用可能な会員ステータスのグルーピング定義 @classificationDefinitionMap.dfprop
map:{
    ; MemberStatus = list:{
        ; map:{
            ; topComment=会員ステータス; codeType=String
            ; groupingMap = map:{
                ; serviceAvailable = map:{
                    ; groupComment = サービスが利用できる会員
                    ; elementList = list:{正式会員;仮会員}
                }
                ...
            }
        }
        ; map:{ ... }
        ...
    }
    ...
}

そして、自動生成すると、以下のようなメソッドが使えるようになります。

e.g. サービスが利用可能な会員ステータスのグルーピング判定 @classificationDefinitionMap.dfprop
// サービスが利用可能な会員だったら (正式会員、仮会員)
Member member = ...
if (member.isMemberStatusCode_ServiceAvailable()) {
    ...
}

// サービスが利用可能な会員を検索 (正式会員、仮会員)
MemberCB cb = new MemberCB();
cb.query().setMemberStatusCode_InScope_ServiceAvailable();
cb...

SchemaHTMLで表示されます

GroupingMapの設定は、SchemaHTMLでも表示されます。

ドキュメントとして価値の高い情報となりますので、その時は再利用をしない Grouping だったとしても、積極的に Grouping していくと良いでしょう。

暗黙の区分値でも使えます

暗黙の区分値でもテーブル区分値でもどちらでも利用可能です。

グルーピングのグループ参照

グルーピングの設定の中で、別のグループを参照することもできます。@since 1.0.5L

グループの区分値要素に $$ref$$.[group-name] と指定すると、参照したグループの要素をそのまま取り込みます。自分よりも先に(上に)定義されたグループだけ参照できます。

e.g. グルーピングの設定の中で、別のグループを参照 @classificationDefinitionMap.dfprop
...
    ; groupingMap = map:{
        ; serviceAvailable = map:{
            ; groupComment = サービスが利用できる会員
            ; elementList = list:{正式会員;仮会員}
        }
        ; afterAll = map:{
            ; groupComment = 結局、全部じゃん
            ; elementList = list:{$$ref$$.serviceAvailable ; 退会会員}
        }
        ...
    }
...
}

また、アプリでは利用せず、ドキュメント利用だけにするグループを作ることもできます(@since 1.0.5L)。 他のグループから参照されるだけのグループを作るときに利用すると良いでしょう。

e.g. ドキュメント利用だけのグループ @classificationDefinitionMap.dfprop
...
    ; groupingMap = map:{
        ; serviceAvailable = map:{
            ; groupComment = すると、CDefやEntityでは生成されない
            ; elementList = list:{正式会員;仮会員}
            ; isUseDocumentOnly = true
        }
        ; afterAll = map:{
            ; groupComment = こっちは、プログラムで利用できる
            ; elementList = list:{$$ref$$.serviceAvailable ; 退会会員}
        }
    }
...

そのif文、ひとことで言うと?

if文の中の複雑な条件、ひとことで言えますか?...これが再利用の始まりです!

業務上の目的を導き出すこと、これがポイント。

区分値の羅列だったら GroupingMap だし、そうじゃなくってもメソッド化したりロジック化したり、何かしら再利用できるでしょう。 いかに、抽象度を一つ上げた業務概念を...

あっ、こっちでも同じようなこと言ってましたね。...そう、同じなんです。