一般社団法人 全国個人事業主支援協会

COLUMN コラム

こんにちは、篠原です。
今回はごく基本的な内容になりますが、ご紹介します。

バリデーション

Webアプリケーションでは、画面上からリクエストされた入力内容は常にチェックし、
アプリケーションを正しく動作させるとともに、不正データの混入を防止することが求められます。
このチェック処理のことをバリデーションと呼んでいますが、単純に
①アプリケーション上、不正な文字種を入力させない
という内容だけではなく、
②ある状態になっていたら入力内容を許容しない
など、何らかの”状態”によってバリデーションのOK/NGが異なるケースもあります。
(特定の組み合わせを選択させない、既に実行済みの処理は再実行させない、など)

実際に報告が挙がったのは、

とある画面入力の1回目と2回目で、内容変更をしても結果が変わらなくなり、何度操作しても正しく実行されなくなった
というものでした。

その原因は、クラス内でユーザーごとのバリデーション結果をキャッシュする作りになっていたためでした…!

Singletonパターン

コーディングにおけるSingletonパターンとは、アプリケーション上でインスタンスが1つしか存在しないようにクラス設計を行うデザインパターンのことです。
詳しい説明は割愛しますが、WebアプリケーションでのController(Action)クラスやServiceクラスなど、
フレームワークでDIするクラスもこのパターンに当てはまります。

こうしたクラスに、ユーザーごとの計算結果など、常に変化する”状態”を保持させてはいけません。

先ほどのバリデーションの話に戻すと、
②のように、入力内容の正当性が他のデータ状態に依存する場合、最新のデータ状態で判定する必要があります。

Webアプリケーション内部の状態管理は、DBやサーバーセッションなど、しかるべきストレージに保持し、そちらに適宜アクセスして行います。
また、その情報はSingletonなクラスのフィールドとせず、適宜呼び出すメソッドの引数に追加して情報を持ち回り、異なるリクエスト間で使い回すような設計にしてはなりません。

おそらく、まずい設計になった動機は、
データ取得のためのDBアクセスが頻繁に発生して、パフォーマンスのボトルネックになることを懸念した
ということだと推測しています。
重い処理をキャッシュして速くしようとする考え方自体はオーソドックスなものですが、
入力内容のバリデーションは常に一定した基準で判定を行うべきで、このケースではDBアクセスを安易に削減するアプローチをとるべきではありませんでした。

まとめ

Singletonなクラスには、状態に関する情報を保持させないような設計にしましょう!

もし、WebアプリケーションのDB面で高速化が必要なのだとすれば、
・1リクエストあたりのDBアクセス回数を減らす
・リクエストの回数を少なくなるようにする
・クエリやDB自体をチューニングする
・もともとのデータ設計を見直す
などが正しいアプローチになるでしょう。
もちろん、データ設計を後から大きく変更することは、はばかられるケースがほとんどですが…。

次回はDBのパフォーマンスにまつわる事例について、書いていきたいと思います。

The following two tabs change content below.

篠原 透

2015年より企業SEとして勤務し、Javaを中心とした業務系Webアプリケーションの設計・開発・運用を経験。2019年2月に独立し、個人事業主となる。

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア