はじめに
こんにちは。
キャスレーコンサルティング IT(インテグレーションテック)部の松岡です。
いつの間にか6月!!!
今年ももう半年!?
あっという間ですね・・・
梅雨の季節になり、ムシムシ…ベトベト…で嫌になっちゃいますね。
気温も高くなってきたので、熱中症に気をつけて小まめに水分補給しましょう!
ところで、そろそろ4月入社の新人さんは
「なにか作ってみたい!」
と、思ってるのではないでしょうか。
そこで今回、章を数回に分けて“じゃんけん”をテーマにブログを書こうと思います。
アプリケーションアーキテクチャや、デザインパターンの考え方を織り交ぜながら
設計から実装までを、一気通貫でやっていきたいと思います!!
要件
まず、じゃんけんといえば「グー」「チョキ」「パー」の組み合わせで勝敗が決まるゲームですよね。
なので、じゃんけんAPIには”グー”,”チョキ”,”パー”のいずれかを送り、
じゃんけんAPI側の出し手(“グー”,”チョキ”,”パー”)と
勝敗の結果(“勝ち”,”負け”,”あいこ”)を返すようにしましょう。
それだけではつまらないので、
・じゃんけんの成績照会機能
・じゃんけんAPIの戦略変更機能
も追加しましょう。
また、APIシステムは基本的に
「その処理の結果が正常終了したか」
「失敗して異常終了してしまったか」
以下のような項目を、一緒に返すのがベターです。
結果コード | 「0:正常」「9:異常」のような処理の結果 |
結果詳細コード | 必須ではないがあると障害時の切り分けが楽(例 「9001:桁数不一致」など) |
結果メッセージ | 処理結果の説明。異常終了時に設定されるイメージ |
今回は、上記項目の「結果コード」と「結果メッセージ」をレスポンスに含めるようにしたいと思います。
設計
では、どうやって通信するか、ルールを決めましょう。
受け渡す項目の拡張性を考え、HTTP(POST)のJSON形式でやり取りしたいと思います。
プロトコル | HTTP |
メソッド | POST |
データ形式 | JSON |
次に、じゃんけんAPIとやり取りする情報を定義します。
以下がAPI定義書となります。
API定義書
※今回はありませんでしたが、同じ項目が複数発生する場合は
項目型を”Array”で定義し、その出現回数も決まっていればその数値も定義します。
では、じゃんけんAPIのアプリケーションの全体構成と骨組みを考えていきましょう。
フレームワーク設計
じゃんけんAPIを呼び出す為に、じゃんけんClientというアプリケーションを追加しています。
今回はメインではないので、詳しくは説明しませんが、
JavaScriptで、POST送信するHTMLが一個あるようなイメージです。
大まかな流れとしては、クライアント(じゃんけんClient)からHTTPリクエストが送られ、
最初にEndpointで受け取ります。
その後、URIのリソース名を条件に必要なサービスに振り分けられ、業務ロジックが処理されます。
その時に必要に応じて、Repositoryを介してDBへのアクセス(検索、登録、更新、削除)をします。
そして、その結果をEndpointからクライアントに返却します。
重要なのは、アプリケーションが行う処理の流れをブロックに分け、抽象化させること。
つまり、処理の共通的な部分を切り出し、そこをベースとして各固有の処理を後で実装するようにすれば
開発者は「リクエストの受け取り」「サービスの振り分け」「リクエストのデコード/エンコード」
「DBアクセス」のような基本処理部分を意識せずに、固有の処理の実装に集中できるのです!
続いて、図中の下にある技術要素の簡単な説明です。
■Linux
検証環境のOS
■Tomcat9
Webコンテナ
■Spring Boot
ベースがSpring Frameworkなので、DIコンテナはもちろん
Webアプリケーションに必要な機能をプラガブルに追加できる為、開発の柔軟性が高くなります。
また、小中規模のアプリケーションなら簡単に開発できてしまうのがいいところ。
⇒一部のWebコンテナがエンベデッドされてるため、開発環境での検証がスピーディーになります。
そして、Spring Frameworkから進化したところは、プロパティファイル1つで
だいたいが設定できてしまうこと!
(設定ファイルの管理が楽)
■Mybatis
昔からある有名なO/Rマッパー。(旧名:iBatis)
シンプルで学習コストも低いのでおすすめです。
別に用意されている「MyBatis Generator」を使用すれば、DBからテーブル情報を取得し
エンティティクラスや、DAOクラスなどを自動生成してくれます。
そして、Spring Bootからもプラグインとして用意されているので手間要らず!
■Thymeleaf
Clientには、こちらのテンプレートエンジンを使用します。
タグを使用して動的にHTML表示が出来るので、
今回は、これでじゃんけんAPIから返ってきた値を画面に表示したいと思います。
DB設計
今回時間の都合上、ER図は用意できなかったのですが
使用するテーブルは以下になります。
※小ネタですが、テーブルの物理名にMT_XXXやTT_XXXのような接頭字を決めることで
そのテーブルがマスタテーブルなのか、トランザクションテーブルなのか
見分けがつきやすくなります。
【マスタ】
・MT_JANKEN_HAND[じゃんけん出し手マスタ]
⇒「0:グー」「1:チョキ」「2:パー」が登録されている
・MT_JANKEN_COMB[じゃんけん組み合わせマスタ]
⇒じゃんけんの組み合わせ情報が登録されている
・MT_JANKEN_STRATEGY[じゃんけん戦略マスタ]
⇒じゃんけんの戦略情報が登録されている
・MT_JANKEN_STRATEGY_USER[じゃんけん戦略ユーザーマスタ]
⇒ユーザー毎のじゃんけんの戦略情報が登録されている
【トランザクション】
・TT_JANKEN_SCORE[じゃんけん成績テーブル]
⇒クライアントごとにじゃんけんの成績が登録される
各テーブルには
「作成者」「作成日時」「更新者」「更新日付」「行バージョン」
を、共通で持たせるようにします。
「作成者」「作成日時」「更新者」「更新日付」は、
開発フェーズよりも運用フェーズで効果が発揮されます。
障害発生時の調査や、パフォーマンスチューニングを行う際、ログファイル以外に調査対象として
これらの項目があると、処理の切り分け及び原因箇所の特定ができ、問題解決につながる為追加しています。
そして、ここでのポイントは「行バージョン」をテーブルにもたせる事です。
今回、ユーザー毎に設定してある戦略を更新するAPIがあるので
同一レコードを、複数クライアントから更新してしまう恐れがあります。
こういった場合に、データの整合性を保証するのに「楽観ロック」というものがあります。
楽観ロックは、更新対象のレコードが取得時と同じ状態であることを条件に更新することで、
データの整合性を保証する方式です。
取得時と同じ状態であることを判断するために、行バージョンを使用します。
UPDATEの条件に「更新する前に取得したレコードの行バージョンと値が同じもの」という設定をいれ、
失敗(更新件数が0)した場合には、排他制御で異常終了するようにアプリケーションで制御します。
他にも、「悲観ロック」というものもありますが、
今回のように同一ユーザー情報を、別々のクライアントから更新するといった
「あまり発生しないケース」は、楽観ロックでも十分です。
逆に、不特定多数のクライアントから頻繁に同一レコードを操作して、整合性が保証できなくなる場合は、
行ロックをかけ、先にそのレコードを触った人が勝つように「悲観ロック」をかけます。
次に、じゃんけんの処理フローを考えたいと思います。
じゃんけんの処理フロー(アクティビティ図)
以下の情報を元に、後でServiceの処理を実装していきます。
戦略の取得から、出し手算出処理までの実装は「ストラテジーパターン」を採用したいと思います。
(※次回、詳しく説明)
ここまで設計しましたら、次は詳細設計~実装へ進んでいこうと思います。
最後に
今回は、一旦ここまでにします。
次回は、本内容のフレームワーク設計とアクティビティ図をベースに
デザインパターンとあわせた、クラス設計をやっていこうと思います。
お読みいただき、ありがとうございました。