どうも。つじけ(tsujikenzo)です。このシリーズでは、2021年9月から始まりました「ノンプロ研GAS中級講座6期」について、全7回でお届けします。最終回の7回目を、5回に渡ってお送りしています。
前回のおさらい
前回は、「要件定義」をお届けしました。
今回は、2回目で「外部設計」です。
業務アプリケーションを外側からみたら、どのように見えるのかを決めていきます。
今日のアジェンダ
- クラス図
- 業務フロー図
クラス図
前回作成したユースケース図では、業務アプリケーションで必要な、ヒト・こと・モノに登場してもらいました。
この、ヒト・こと・モノをオブジェクトとしてとらえてみましょう。
クラスを作成する
ユースケース図に登場した、ヒト・こと・モノをすべてオブジェクトとして書き出してみます。
復習ですが、クラスは、オブジェクトを生成する機能です。
具体的なオブジェクトを眺めながら、どんなクラスを作成したら、必要なオブジェクトが生成されるかを考えます。
ヒト
たとえば、ヒトでいうと、Staffクラスが1つあれば、インスタンスに、辻オブジェクトと高橋オブジェクトが生成できそうです。
スプレッドシート
スプレッドシートは、データ入力用、加工用、印刷用、という構造にすると管理がしやすいです。(詳しくはこちらのブログで)
データ加工はGASで行いますので、「データ入力用」と、「印刷用」のシートを用意しましょう。
そのまま、クラス化します。
[つじけコラム] ユーティリティクラスは作るの?
GWSの、Spreadsheetクラスの便利な関数を集めた、ユーティリティSpreadsheetクラスなどは、できれば作りません。
もし、便利な関数などを作成し、使い回ししたいばあいは、ライブラリを活用するといいでしょう。
シートは、インスタンスごとに1枚作成してもかまいませんし、1枚を共有してもかまいません。
シートの自由な運用ができるのも、クラス化のメリットです。
PDFを担当するクラスは、業務アプリケーションの規模によって、切り分けが必要です。
業務アプリケーションの規模が小さい場合は、PDFクラスでさまざまな処理を担当してよいでしょう。
PDFクラスのお仕事
- PDFを作成・保存
- PDFを探す
- PDFの結合・分割
- PDFのblob化
もし、PDFクラスが肥大化してきたばあいは、たとえば、1.と3.のクラスを分けるのも手です。
クラスを切り分けるときは、「createPDFクラス」や、「processPDFクラス」など、なにをするかクラス名で明示することが大事です。
今回は、createPDFクラスを作成しました。
Gmail
Gmailは、GWSのサービスの1つです。
Gmailでは、アタッチメントや下書き作成やスレッドなど、さまざまなオブジェクトの操作が考えられます。
なので、ちゃんと、オブジェクトに対応したクラスが提供されています。
普段、何気なくメソッドを書いていますが、GmailAppのメソッドは、静的メソッドです。
//createDraft()は静的メソッド
const now = new Date();
const recipient = "mike@example.com";
const subject = "current time";
const body = `The time is:${now.toString()}`;
GmailApp.createDraft(recipient, subject, body);
また、GmailAppクラスは、コンストラクタをもっていません。
const g = new GmailApp(); //TypeError: GmailApp is not a constructor
console.log(g);
つまり、GmailAppクラスは、インスタンスを生成して使うことを想定していません。
このような継承はできないことを理解しておきましょう。
class MyGmailApp extends GmailApp { }
さきほども言いましたが、Gmailに関する便利な関数を作成したのなら、ライブラリを活用するほうがいいです。
ユーティリティ系のクラスを作成する必要はありません。
GASのプロジェクトのアカウントが、Gmailのアカウントに紐づいているので、インスタンス生成時に Gmailアカウントを渡す必要もありません。(それができると便利なこともあるんですけどね)
と、なると、作成するクラスは、大きく分けて以下の2種類が考えられます。
- GmailSearchクラス・・・Gmailのスレッドやメッセージを検索するクラス
- GmailDraftクラス・・・Gmailの下書きを作成、送信するクラス
これらのクラスに、オブジェクトを渡すことで威力を発揮します。(詳細は第4回目)
今回は、GmailDraftクラスを作成しました。
完成図
完成したクラス図はこのような感じです。
本来なら、トリガーやonOpenもクラス化するはずですが、functionでかまわないと思いますので、補足的にクラス図に置いています。
ProtertyStoreやトリガーについても、業務アプリケーションの規模が小さいうちは、クラス化する必要はないと思います。
スプレッドシートのひな形を流用して、別のひな形を運用するばあいなどは、クラスを継承しますが、別の機会にご紹介したいと思います。
業務フロー図
業務フロー図は、実際に、ユーザーがどのような流れでデータを入力するのか、などを可視化したものです。
もちろん、この時点では、シート構成や、カスタムメニューなどは未完成だと思いますので、ダミーデータなどを用意して、それっぽく見せるのがポイントです。
業務フロー図でシェアしたい内容は以下です。
- ユーザーはどんなタイミングでFunctionを実行したいのか
- 実行したいFunctionはどこから呼び出すのか
- (実行したいFunction名がイメージできるならなお良し)
- スプレッドシート編集時、などの、トリガーでうごく処理はなにか
- 時限式トリガーでうごくFunctionはなにか
もちろん、ザックリでかまいません。
ユーザーに目視確認してもらいたいフローも、書いておきましょう。
ゆくゆくは、業務フロー図をそのまま、業務アプリケーションマニュアルとして使えます。
この段階で、修正したいクラスなどが見えるばあいもあると思います。必要に応じて、ユースケース図やクラス図を見直してみましょう。
まとめ
以上で、「外部設計」をお送りしました。
UMLを学んでいるひとからしたら、「これがクラス図?笑わせるぜ!」と思われるのは百も承知です。
しかし、クラス図はノンプログラマーにとって敷居が高く、手が出しづらいものです。
なので、今回はまず 「ヒト・こと・モノをオブジェクトとしてとらえよう」 という点だけにフォーカスしてみました。
カスタムクラス・メソッド
もし、GWSのクラス名と同じクラスやメソッドを作成するばあいは、Customという言葉を付けるようにしています。
- class CutomPropertyStore
- getCutomCreateFile()
- setCustomValues()
ご留意くださいませ。
次回は、 「内部設計・コーディング・テスト」 をお届けします。
このシリーズの目次
[GAS]オブジェクト指向によるGAS開発のススメ