
Blue Prismベストプラクティス 構築編 1 オブジェクトの粒度とその内容
プロセスとオブジェクト
プロセスとオブジェクトの役割分担に悩まれる方も多いかもしれません。
大原則はシンプルです。
ロジックは、オブジェクトには実装しない。
ロジックは、すべてプロセス側に実装する。
です。
ロジックとは、業務判断です。判断・分岐、ループ・繰り返し、エラー処理などが含まれます。このような業務ロジックは、オブジェクトから極力排除します。
オブジェクトには、画面への書き込み、画面からのデータ読み込み、ボタン押下、画面遷移などの、アプリケーションに対する操作のみ実装するようにします。
プロセスは、その操作オブジェクトを呼び出す、とし、プロセスとオブジェクトの役割分担を明確に分けるように実装します(役割分担についてもう少し詳しく、この後に投稿する「設計編 1 プロセスとオブジェクトの役割分担」でも解説します)。
オブジェクトの粒度
(プロセスとオブジェクトの役割分担が明確にできた、とここでは仮定して)
では、1オブジェクトはどのように切ればよいのでしょうか。
Blue Prismのベストプラクティスでは、「1オブジェクトは、1画面単位で実装すべし」となっています。
「1オブジェクトは1アプリケーション」ではありません。皆さんが思っているより、より細かい単位で切ることが求められます。
さらに、ひとつのオブジェクトの中に切られる、アクションページはどうでしょうか。「1アクションページは、1操作単位で実装すべし」となっています。これにより、再利用性がぐんと高まります。なんてったって、オブジェクト指向ですから。「手続き型」にしないでください。
こんな感じですね。
Start→Attach→画面確認→操作→画面確認→End。
以上。これだけ。
つまり、オブジェクトのひとつのアクションページは、以下のような、実装になっていることが望ましいとされています。
データをフィールドに書き込んで、ボタンを押す、というアクションの場合の例
1. 入力対象画面に正しく遷移できていることを確認する(場合によっては、入力対象フィールドの存在を確認する)
2. 入力データを書き込む
3. ボタン操作し画面を更新(もしくは遷移)する
4. ボタン操作が想定通り正しく実行できたことを、遷移すべき画面の存在確認で行う
これの繰り返しをプロセス側で呼び出すことで、堅牢なシステムが出来上がります。
。。。そうですね。お察しの通り、当然、結果として、スタジオ上に多くのオブジェクトが出来ますね。。。。。。フォルダ(グループ)を使って整理しましょう。。。
1アクションページの中身
ではこれを具体的に実践するために、何を心掛ければ良いでしょうか。
答えはこうです。
以下を入れるのがグッドなプラクティスとされています。
1. Start直後にWaitステージを入れる
2. 操作後にWaitステージで画面チェックする
3. IN/OUTパラメータを使う
4. 他のアクションページやオブジェクトを呼び出さない。判断ロジックを入れない
5. Start直後にアタッチを入れる
1. Start直後にWaitステージを入れる
Start直後にWaitステージを入れて、自分が目的の画面に遷移してきていることを確認しましょう。このとき、必ずCheck Existなど条件を指定して、画面の存在確認を行うWaitステージの実装にします。
これがないと、画面によっては、操作対象フィールドの描画が完了していないうちに、Blue Prismが処理(例えば、フィールドに値を書き込む、など)を実行しようとします。画面描画完了のスピードは、開発環境や本番環境でも全く違いますし、システムに負荷がかかってレスポンスが悪化している場合など、想定より多くの時間がかかることもよくあります。単純かつ一見冗長そうな実装ですが、エラーで落ちる確率を格段に下げることができる、非常に効果の高い実装です。
こんな感じですね。
2. 操作後にWaitステージで画面チェックする
Start直後と同様に、ボタン押下などの操作ステージを行ったあとでは必ず、操作後に想定している画面に遷移したかどうか、確認するようにします。
1と2を組み合わせると、プロセスからすると同じ処理を2回繰り返すことになる場合もありますが、ここで発生するオーバーヘッドやパフォーマンスへの影響は微々たるものです。それよりも、確実に意図通りに動いていることを、その場その場で確認し、場合によってはエラーを報告する、という実装にすべきです。これにより格段に堅牢性が上がります。将来、再利用される際のバグ発生リスクも低減できます。
いずれのWaitステージでも、条件無しのWait(=単純なスリープ)は実装しないようにしましょう。
3. IN/OUTパラメータを使う
画面操作を行うデータの値をオブジェクト内のデータアイテムの変数に書いて利用することは避けましょう。当初は例え固定値を常に書き込む要件であったとしても、将来にわたって、それがあっているとも限りません。値は、上位のプロセスからInputパラメータで渡すようにし、上位のプロセスへ結果情報をOutputパラメータで渡して、上位プロセス上で判断・利用ロジックを記載するという実装にしましょう。これは、このオブジェクトの再利用性を向上させる、非常に有効な手段です。
4. 他のアクションページやオブジェクトを呼び出さない。判断ロジックを入れない
原則、他のアクションページや他のオブジェクトを呼び出す実装は回避すべきです。また、条件分岐など、判断ロジックやループ処理など、ビジネスロジックに該当するような処理は、オブジェクトに実装すべきではありません。複数の手続きをひとつのページに含んで実装すると、再利用性は極端に下がります。現在の要件だけでなく、将来の要件への対応もきちんと想定しておきましょう。
もし複数の手続きや判断処理などの実装が必要な場合は、プロセス側でそれらを順番に呼び出してあげれば良いだけです。例外処理もはるかにやりやすくなります。
5. Start直後にアタッチを入れる
Start直後にWaitステージを入れたついでに、アタッチページの呼び出しを入れるようにすると良いでしょう。
各アクションページは、特定の順序で呼び出されるとは限りません。どのアクションページを最初に呼び出されても、確実に、そのアプリケーションに接続できる実装にしておくと、再利用性が向上します。結果、こんなシンプルな実装になっていることが望ましいです。
まとめ
オブジェクトは、より小さく、よりシンプルに実装しましょう。ビジネスロジックは排除しましょう。
大きなオブジェクトは、サーバとロボット間のネットワークを多く消費し、ロボットのメモリリソースをより多く消費します。ひとつのオブジェクトは一人の開発者しか編集できませんので、チーム生産性にも悪影響です。一つの大きなオブジェクトを多数のプロセスが利用するのであれば、もしそのオブジェクトの修正が必要になった場合、多くの対象プロセスに影響が出ます。
先に示した点を注意して、オブジェクトの設計・実装をすることにより、再利用性と堅牢性が確実に上がり、エラー発生頻度を低減できます。
また、スタジオ画面でのデバッグ作業から、コントロールルームでのテスト実行へ、作業が移行したタイミングでも、これによる生産性の向上は、確実に感じていただけると思います。一度、皆さんが作られたロボットの実装を見直してみて下さい。
次回は、構築編 2 エラーハンドリングについて解説していきます。
※本投稿は、別ブログで掲載・公開していた内容に加筆・修正を加え再掲載しています。