ワークフローパターン(2/2) -構成表を使用して実際のワークフローを定義する-

今回は、前回に引き続いて、ワークフローのデータモデルに関する記事の後編です。


Vertabelo

The Workflow Pattern. Part 2

Using Configuration Tables to Define the Actual Workflow

(元記事はこちら)

Jean-Marc ReynaudJean-Marc Reynaud
フリーランスデータモデラー
2016/3/15

このシリーズの前半では、データベース内の任意のエンティティのライフサイクルを管理するための基本的な手順を紹介しました。後半の今回は、追加の構成表を使用して実際のワークフローを定義する方法を説明します。この構成表によって、各段階で選択可能なオプションがユーザに提示されます。また、部品表(BOM)構造の「アセンブリ」と「サブアセンブリ」の再利用を厳密に制御するためのテクニックも紹介します。

選択肢(Options)の定義

パート1では、ワークフローの中心となるテーブルと、それらを既存のデータベースに簡単に組み込む方法を紹介しました。次に必要となるのは、ユーザに次の論理的な状態を選択させることです。つまりこれが論理ワークフローを定義することになります。

以下の図は、ワークフローのデータモデルのすべてのパーツを示しています。

2つの設定用テーブルworkflow_state_optionworkflow_state_context がモデルに追加されています。まず始めに、次の許容可能な状態を定義するoptionテーブルから始めます。その機能が理解できたら、contextテーブルに戻り、それが果たす役割を説明します。

許される次の状態

以下の表は、構成表全体を結合させたSQLビューに似ています。ここでは結合キーを省略して、 ただtype_keysの組み合わせだけを見ます。ではSTATE.OUTCOMEの各組み合わせを考えて、ユーザーが利用できるオプションを定義します。

STATE.OUTCOME Combination (from State Hierarchy) State Context Child Disabled? Option 1 Option 2
APPLICATION_RECEIVED
.ACCEPTED
STANDARD_JOB
_APPLICATION
N APPLICATION_REVIEW
APPLICATION_RECEIVED
.REJECTED
STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED
.NOT_HIRED
APPLICATION_REVIEW
.PASSED
STANDARD_JOB
_APPLICATION
N INVITED_TO_INTERVIEW
APPLICATION_REVIEW
.FAILED
STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED
.NOT_HIRED
INVITED_TO_INTERVIEW
.ACCEPTED
STANDARD_JOB
_APPLICATION
N INTERVIEW
INVITED_TO_INTERVIEW
.DECLINED
STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED
.NOT_HIRED
INTERVIEW
.PASSED
STANDARD_JOB
_APPLICATION
N MAKE_OFFER SEEK_REFERENCES
INTERVIEW.FAILED STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED
INTERVIEW
.CANDIDATE_CANCELLED
STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED INVITED_TO_INTERVIEW
INTERVIEW
.NO_SHOW
STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED
MAKE_OFFER.ACCEPTED STANDARD_JOB
_APPLICATION
N SEEK_REFERENCES
MAKE_OFFER.DECLINED STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED
SEEK_REFERENCES
.PASSED
STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED.HIRED
SEEK_REFERENCES
.FAILED
STANDARD_JOB
_APPLICATION
N APPLICATION_CLOSED
APPLICATION_CLOSED
.HIRED
STANDARD_JOB
_APPLICATION
N
APPLICATION_CLOSED
.NOT_HIRED
STANDARD_JOB
_APPLICATION
N

まだここではコンテキストを考慮に入れていないので、 State ContextChild Disabled? はグレー表示されています。また話を単純にするために、この例ではオプションの数を2つまでにしましたが、実際には制限はありません。

さてこれがどう機能するのでしょうか?

今面接がちょうど終わったところで、面接官が結果(outcome)を記録しているところを想像してください。更新されるテーブルはmanaged_entity_stateです。論理的な結果としては、PASSEDとFAILEDの2つがあります。したがって、現在のmanaged_entity_stateは、選択された結果(wf_state_type_outcome_id)で更新されます。このモデルの例では、面接官は面接に関するメモを含めることもできます。

面接官がPASSEDを選択すると、MAKE_OFFERとSEEK_REFERENCESという2つのオプションが表示されます。これらはワークフローの次の状態です。これはプログラミングでのgo toステートメントに似ています。どちらのオプションでも、新しい行がmanaged_entity_stateに挿入され、求職申込のワークフロープロセスが次の状態に移動します。ユーザは、 due_dateを入力することにより入力期限を設定することができます。

一方、面接官がFAILEDを選択した場合、オプションはAPPLICATION_CLOSEDの1つだけです。したがって、APPLICATION_CLOSEDの状態( wf_state_type_state_id)を使用して、managed_entity_stateに新しい行が挿入されます。

APPLICATION_CLOSEDの状態では使用できるオプションがありません。これは、ワークフロープロセスが終了したことを示します。

Contextテーブル

技術職の求職申込プロセスの設定を見て、 Contextテーブルの役割を確認してみましょう。

STATE.OUTCOME Combination (from State Hierarchy) State Context Child Disabled? Option 1 Option 2
APPLICATION_RECEIVED
.ACCEPTED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_REVIEW
APPLICATION_RECEIVED
.REJECTED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED
APPLICATION_REVIEW
.PASSED
TECHNICAL_JOB
_APPLICATION
N INVITED_TO
_INTERVIEW
APPLICATION_REVIEW
.FAILED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED
INVITED_TO_INTERVIEW
.ACCEPTED
TECHNICAL_JOB
_APPLICATION
N TEST_APTITUDE
INVITED_TO_INTERVIEW
.DECLINED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED
TEST_APTITUDE
.PASSED
TECHNICAL_JOB
_APPLICATION
N INTERVIEW SEEK
_REFERENCES
TEST_APTITUDE
.FAILED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED
INTERVIEW
.PASSED
TECHNICAL_JOB
_APPLICATION
N MAKE_OFFER SEEK
_REFERENCES
INTERVIEW
.FAILED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED
INTERVIEW
.CANDIDATE_CANCELLED
TECHNICAL_JOB
_APPLICATION
Y
INTERVIEW
.NO_SHOW
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED
INVITED_TO
_INTERVIEW
MAKE_OFFER
.ACCEPTED
TECHNICAL_JOB
_APPLICATION
N SEEK
_REFERENCES
MAKE_OFFER
.DECLINED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED
SEEK_REFERENCES
.PASSED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED.SUCCESS
SEEK_REFERENCES
.FAILED
TECHNICAL_JOB
_APPLICATION
N APPLICATION
_CLOSED
APPLICATION_CLOSED
.HIRED
TECHNICAL_JOB
_APPLICATION
N
APPLICATION_CLOSED
.NOT_HIRED
TECHNICAL_JOB
_APPLICATION
N INSUFFICIENT
_EXPERIENCE
OVER
_QUALIFIED

ここでは、コンテキストはTECHNICAL_JOB_APPLICATIONです。なぜこれが重要なのでしょうか? なぜなら、結果を上書きすることができるからです。前回、部品表(BOM)構造で「組立品」と「組立部品」を再利用できると書きました。何かを一度定義してまたそれを再利用できるということは便利ですが、ときにはあまりにも制約が強すぎるかもしれません。すべてを再利用したくはないという場合はどうすればいいでしょうか?

workflow_state_hierarchyworkflow_state_optionの間にworkflow_state_contextを挿入することにより、結果(outcome)を再利用も上書きもできるようになります。このモデルでは、異なるプロセスに対して結果が有効か無効かを定義できます。

上の例では、INTERVIEW.CANDIDATE_CANCELLEDの組み合わせは無効にされています。言い換えれば、それが技術職の求職申込の結果としては選択できないということです。したがって、面接官が技術職への応募者の面接結果を記録するときに、workflow_state_context.child_disabled = 'N'のオプションしか表示されないため、CANDIDATE_CANCELLEDは選択することができません。

workflow_state_optionworkflow_state_hierarchyの直接の子ではないため、状態(state)が使用されるたびに個別のオプションのセットを定義する必要があります。しかし、このトレードオフのおかげで、各プロセスのオプションを細かく制御することができます。

結果(outcome)の理由

また、結果の詳細な理由を定義するオプションもあります。これを行うには2つの方法があります。

  1. BOMに4番目のレベルを作成して、階層内の結果(outcome)の下に理由(qualifier)を定義します。この手法をとる場合は、十分な注意が必要です。たとえば、FAILEDはさまざまな状態の結果として使用されます。しかし、異なるFAILEDの状態に対して、同じ理由を使用したくはありません。
  2. workflow_state_typeで補足理由を定義することができますが、それを任意の階層に限定して結び付けることはできず、どこでも使用できてしまいます。そこでworkflow_state_optionを使用して、特定の結果のコンテキストでの理由をリストします。これを示しているのが上の設定表で、OVER_QUALIFIEDとINSUFFICIENT_EXPERIENCEがAPPLICATION_CLOSED.NOT_HIREDという結果のオプションとしてリストされています。

いずれの場合も、アプリケーションは状態(state)または結果(outcome)ではなく補足理由(qualifier)が選択されていることを認識する必要があり(workflow_level_typeがこれを示しています)、managed_entity_state.wf_state_type_qual_idを選択した値で更新します。

テーブルの構成データ

実際の構成データをテーブルごとに見てみましょう。ここでは、idとidで参照するtype_keysを()内に示しています。簡潔にするために、記事に関連する値のみを提示します。

workflow_level_type (レベル)

id type_key
1 PROCESS
2 STATE
3 OUTCOME
4 QUALIFIER

 

workflow_state_type (状態)

id type_key workflow_level_type_id
1 STANDARD_JOB_APPLICATION 1 (PROCESS)
2 TECHNICAL_APPLICATION 1 (PROCESS)
3 INTERVIEW 2 (STATE)
4 PASSED 3 (OUTCOME)
5 FAILED 3 (OUTCOME)
6 MAKE_OFFER 2 (STATE)
7 SEEK_REFERENCES 2 (STATE)
8 APPLICATION_CLOSED 2 (STATE)
9 HIRED 3 (OUTCOME)
10 NOT_HIRED 3 (OUTCOME)
11 INSUFFICIENT_EXPERIENCE 4 (QUALIFIER)
12 OVER_QUALIFIED 4 (QUALIFIER)

 

workflow_state_hierarchy (階層)

id state_type_parent_id state_type_child_id
1 1(STANDARD_JOB_APPLICATION) 3 (INTERVIEW)
2 2(TECHNICAL_JOB_APPLICATION) 3 (INTERVIEW)
3 3 (INTERVIEW) 4 (PASSED)
4 3 (INTERVIEW) 5 (FAILED)
5 1 (STANDARD_JOB_APPLICATION) 8 (APPLICATION_CLOSED)
6 2 (TECHNICAL_JOB_APPLICATION) 8 (APPLICATION_CLOSED)
7 8 (APPLICATION_CLOSED) 9 (HIRED)
8 8 (APPLICATION_CLOSED) 10 (NOT_HIRED)

 

workflow_state_context (コンテキスト)

id state_type_id state_hierarchy_id child_disabled?
1 1 (STANDARD_JOB_ APPLICATION) 3 (INTERVIEW.PASSED) N
2 1 (STANDARD_JOB_ APPLICATION) 4 (INTERVIEW.FAILED) N
3 1 (STANDARD_JOB_ APPLICATION) 7 (APPLICATION_CLOSED. HIRED) N
4 1 (STANDARD_JOB_ APPLICATION) 5 (APPLICATION_CLOSED. NOT_HIRED) N
5 2 (TECHNICAL_APPLICATION) 6 (APPLICATION_CLOSED. NOT_HIRED) N

 

workflow_state_option (オプション)

id state_context_id state_type_id
1 1 (STANDARD_JOB_ APPLICATION.INTERVIEW.PASSED) 6 (MAKE_OFFER)
2 1 (STANDARD_JOB_ APPLICATION.INTERVIEW.PASSED) 7 (SEEK_REFERENCES)
3 2 (STANDARD_JOB_ APPLICATION. INTERVIEW. FAILED) 8 (APPLICATION_CLOSED)
4 5 (TECHNICAL_JOB_ APPLICATION.APPLICATION_CLOSED.NOT_HIRED) 11 (INSUFFICIENT_EXPERIENCE)
5 5 (TECHNICAL _JOB_ APPLICATION.APPLICATION_CLOSED.NOT_HIRED) 12 (OVER_QUALIFIED)

これらの表を正しく設定することは、大変複雑な作業になります。できれば入力作業は、ユーザが使いやすいインタフェースを持ったアプリケーションを介して管理されるべきでしょう。

Alternative Sequences(別の並び順)

いくつかの表にalt_sequenceという列があります。これは、ユーザに提示されるさまざまな選択項目の値のリストを並べ替えるために使用されます。通常、これは使用頻度に基づいて降順になり、最も頻繁に使用されるオプションが一番上に表示されます。

この記事では、job applications(求職申込)について説明しましたが、時間の経過とともにエンティティの状態を管理する必要がある多くのタイプのワークフローにこのモデルを使用できます。あるいは、このモデルを独自にカスタマイズして、特定の要件に合わせたパターンとして機能させることができます。

Leave a Reply