長岡花火の過ごし方
目次
概要
長岡花火に2019年と今年の2度参戦したので、得た気付き・学びをTips化する。
全体の流れ
- 長岡花火のチケットの予約
- 長岡花火のチケット抽選結果発表
- ホテルの予約
- レンタカー・駐車場の予約
- 参戦
詳細
長岡花火のチケットの予約
- 公式サイトからチケットを予約する。
- 公式転売サイトが有るため、複数人で応募し、チケットが余ってしまった場合でも安心。
- 結論、A会場側の大手大橋と長生橋の間のベンチ席が無難そう。
長岡花火のチケット抽選結果発表
- 【参考】チケット当選戦績(2023年):
- A会場_マス席:2/2枚落選。
- A会場_ベンチ席:2/2枚当選。
ホテルの予約
- 筆者は抽選結果発表よりも前(6月頭時点)にホテルを探していたが付近のホテルはほぼ全て埋まっていた事と、直前までキャンセル料無料なホテルも有るため、可能であれば抽選結果発表前から予約する事を強くお勧めする。
レンタカー・駐車場の予約
- 花火大会の行き帰り(前日・翌日含む)に道中のプチ旅行も楽しみたい場合はレンタカーを借りると思うが、ホテルから花火会場まで離れている場合は会場近くの駐車場の予約が必要。
- 筆者は軒先パータキングを利用して駐車場を予約したが、駐車場によって値段や予約開始日がバラバラ。
さいわいプラザA
とさいわいプラザB
という駐車場が、安くて比較的近くて良かった。
参戦
- 関東圏から車で行く場合、当日の早朝に出発すれば、長岡着いてからランチ食べて会場向かうくらいの余裕は有り、充分間に合う。(事故等で大渋滞にハマった場合は例外かも)
- ランチ:
- 有名なへぎ蕎麦屋に行ってみたが13時過ぎで100人待ちだった。
- 代わりに行ったラーメン屋は結構美味かったのでお勧め。
- どこのお店もだいたい14時閉店のお店が多いため、当日困らないようにいくつか候補を見つけておくのが良さそう。
- 屋台は、長岡駅から大手大橋までの大通り(国道351線)沿いに多く出店されている。
- 休憩所:
- 早めに会場に着いた際、開演まで席で待っていると日なたでしんどい。ここは日陰になっているのと、すぐ近くに屋台が有るので、レジャーシートを敷いて開演まで待つのに最適。(2,3時間前に着かないと空いてないかも)
- 会場のトイレは意外と空いている。
- 花火会場ではスマホ通信がほぼ出来ないため、公式アプリのインストールや、花火プログラムのダウンロード等は事前に済ませておくべし。
オススメの持ち物
- 虫除けスプレー
- 会場には、見た事無い大きさのコオロギがはびこっていた。(虫除けスプレーで効果有るかは不明)
- 簡易トイレ
- 高速で大渋滞にハマってしまった時の為に念の為。
- ウェットシート
- 汗かくし、屋台で飲み食いするので、必需品。
- 日焼け止め
- レジャーシート・クッション
- 席種にも依るが、2h近く地べたに座るタイプの席の場合は重宝する。ケツ痛い。
- キャップ・サングラス・汗拭きタオル
【Appendix】行き帰りのプチ旅行
【WIP】お小遣い管理アプリの企画に向けて
目次
概要
お小遣い管理アプリの企画に向け、事前に整理・考察すべき情報を以下に纏める。
整理が必要そうな情報
- 小遣い管理の課題とその根拠。
- 課題解決できるサービスの概要・要件。
- 競合サービスや類似サービスの調査。
- サービスの実現方式。
- サービスによるマネタイズ構造。
【整理】小遣い管理の課題とその根拠
仮設
自分の経験や今の日本の時代性を基に、下記のような状況・課題が有ると予想。
要因背景 | 要因 | 課題・需要 |
---|---|---|
共働き時代 | 晩御飯代等を渡される鍵っ子の増加。 → お小遣いの額や重要度の増加。 |
お小遣い管理の需要増。 |
デジタルネイティブ・スマホネイティブ世代 | 子供がいつでもどこでも何でも購入可能な状況。 → 浪費リスクの増加。 |
お小遣い利用の監視の需要増。 |
グローバル化 | 購入可能な商品の多様性・複雑性の向上。 → 不適切商品(年齢制限や違法商品等)の購入リスクの増加。 |
子供の消費活動の制御の需要・必要性増。 |
実値調査
(要追記)
【整理】課題解決できるサービスの概要・要件
まず、サービスの特性上、親・子それぞれ下記が非常に重要となりそう。
- 親:子供への送金自体は既存サービスで実現できるため、本サービスをわざわざ導入する利点・ウマミをしっかり訴求する事。
- 親が抱えている課題感の的確な把握と的確なサービスデザインが必要。
- 子供:親に消費活動を監視・管理されるという特性上、サービスに対するダサさや抵抗感を限り無く0に近付ける事。
- サービスブランディングやUX/UIデザインの工夫が必要。
【整理】競合サービスや類似サービスの調査
Gitについて
目次
概要
Gitの基本ついて社内勉強会で発表することになったので、説明に使えるメモを下記に纏める。
Gitとは
何者?
- 分散型バージョン管理システム。
- バージョン管理が可能。
- 分散型なので、複数人開発に最適。
- リーナスさんがLinux開発時のバージョン管理の為に作った。
そもそもバージョン管理とは?
ファイルの変更履歴を保存・管理する事。
GitやSubversionが代表的なバージョン管理システム。
バージョン管理する事で下記のような事が可能。
- 過去バージョンに戻す。
- いつ誰かどんな変更を実施したのか把握。
どんな課題を解決する為のモノ?
下記サイトのGitが生まれた理由
を参照。
【絶対理解できる】Gitとは?特徴やできることまとめ! | 侍エンジニアブログ
基本用語(イメージつきやすい言葉でのザックリ解説なので、詳細・正確な解説は別サイトをご確認ください。)
- リポジトリ:
- GitのCommitが管理されている領域。
- リモートリポジトリ:
- ローカルリポジトリ:
- 皆のローカル環境上に構築されたリポジトリ。
- ブランチ:
- Merge:
- ブランチとブランチを統合する事。
全体像
Gitの操作と、その時起こっている事
上記全体像
の画像内の開発着手中
と開発後
の部分にフォーカスし、流れに沿って一部操作について纏める。
なお、共有資材への反映_MergeRequest
以外、下記全てローカルリポジトリ上での操作です。
①開発用ブランチ作成
mainブランチ等から、自分の開発用のブランチを作成する。
git checkout -b <ブランチ名>
②開発
先ほど作成した自分のブランチ上でコーディングやDoc修正等を実施する。
修正内容は、Git内のワークツリー
という場所上で行われる。そのため、ファイルを保存してもGit(ローカルリポジトリ)にはまだ反映されない。
③開発内容の保存_ステージング
自分の内容をローカルリポジトリに反映する為にこの後Commitを行なうが、Commit対象のファイルを宣言し、対象ファイルをワークツリー
からインデックス
に反映する。
この操作をステージング
と呼ぶ。
git add <ファイル名>
④開発内容の保存_Commit
先ほどステージング
したファイルをローカルリポジトリに反映する。
この操作をCommit
と呼ぶ。
git commit -m "<コミットメッセージ>"
【参考】⑤バグ改修
新規ファイルを実装中に既存ファイルのバグを見つけたので、バグ改修。
【参考】⑥バグ改修の保存_ステージング
新規実装とバグ改修のCommitは分けたい。そのため、バグ改修ファイルのみを指定してadd。
git add <ファイル名>
【参考】⑦バグ改修の保存_Commit
バグ改修ファイルのみCommit。
git commit -m "<コミットメッセージ>"
⑧リモートリポジトリ(共有資材)への反映_push
先ほどローカルリポジトリに保存した開発内容を、リモートリポジトリ(共有資材)へ反映する。
git push origin <ブランチ名>
⑨リモートリポジトリ(共有資材)のmain資材への反映_MergeRequest(PullRequest)
mainブランチ等へ、自分の開発用ブランチの開発内容を反映する為に、mainブランチへのMergeRequestを作成する。
その後、RV権者によるRVが完了したらmainブランチへMergeされる流れ。
【参考】コマンドメモ
- git ls-files
- ステージにaddされているファイルを確認。
- git log --stat
- 各Commitでどのファイルが修正されたかも併せてCommitLogを表示する。
- git log --graph
- ブランチツリーをグラフィカルに表示する。
【参考】rebaseについて
- rebaseを使うウマミは大きく下記2つ。
- Commit履歴が綺麗にできる。(ブランチがなるべく1本の流れになるようにできる)
- 切り出し元ブランチ(mainブランチ等)のCommitを切り出しブランチ(featブランチ等)に取り込める。
- rebaseは、ブランチ切り出し元(mainブランチ等)に対して、切り出しブランチ(featブランチ等)のCommitのCherry-pickを繰り返す事で実現されている。
- そのため、featブランチにmainブランチのCommitを取り込む際、Mergeを実施するとConflictの解消は1度で良いが、rebaseを実施した場合はcherry-pickの回数分だけConflict解消が必要となる。
- rebaseすると、featブランチ上のCommitハッシュ値が変わるので、同featブランチを複数人で使用している場合は、他開発者がPushできなくなってしまう等の迷惑がかかる。
- featブランチにmainブランチのCommitを取り込む際、Mergeではなくrebaseを使用するのは、下記基準を全て満たしている場合にした方が良さそう。
- Conflict解消の手間よりもCommit履歴の綺麗さを優先したい。
- 対象のfeatブランチを他開発者が使用していない。
参考文献
DB_正規化について
目次
概要
リレーショナルデータベース(RDB)の正規化について学習したので、以下に纏める。
また、説明上、図が必要な場面も有るため、今回はブログ上につらつら記載する形式ではなく、スライド形式で説明を記載する。
説明資料(SpeakerDeck)
参考文献
所感
- 性能(パフォーマンス)を重視し正規化を実施し過ぎない方針も有るとの事だが、正規化の実施具合が実際にどれくらい性能に影響するのか要学習。(もちろん、カラムの数やリレーションの持ち方等によって一概に定義できないと思うが)
- 今回学習したのはRDBにおける正規化だが、Firestoreの様なレコードやテーブルという概念が無いNoSQLなDBでは、同じような品質(DBの整合担保性)向上作業をどの様に実施するのか気になるので、要学習。
Springについて_「SpringFramework超入門〜やさしくわかるWebアプリ開発〜」を読んで
目次
- 目次
- 概要
- SpringFrameworkとは
- アプリケーションのレイヤ化
- DispatcherServlet
- リクエストハンドラメソッド
- サニタイズ
- Thymeleaf(タイムリーフ)
- Viewからのリクエストパラメータの受け取り方
- POJO
- バリデーションチェック
- form-backing bean(Formクラス)
- プレースホルダ
- ジェネリッククラス
- トランザクション
- application.properties
- Flash Scope(フラッシュスコープ)
- アノテーション
- リダイレクト
- 【メモ】クライアントに同画面を返却する場合でも、Formの状態によって処理の走らせ方を変える
- 所感
概要
Springについて学ぶ為にSpringFramework超入門〜やさしくわかるWebアプリ開発〜
*1を読んだので、重要そうなポイントを以下に纏める。
SpringFrameworkとは
Javaアプリケーション開発におけるフレームワーク。単に「Spring」とも呼ばれる。
開発が楽になる様々な機能を提供してくれていて、機能毎に下記の様なプロジェクトが存在する。
SpringBoot
Springアプリケーションを煩雑な設定をせず迅速に作成する為の機能を提供している。
Springが多機能になりすぎて、逆に開発をスタートする際のコストが大きくなってしまったという課題を解決してくれる。
Springプロジェクト
Spring MVC
Webアプリを簡単に作成する為の機能を提供。
Spring Data
データアクセスの為の機能を提供。
Spring Batch
バッチ処理機能を提供。
Spring Security
認証・認可の機能を提供。
Springコア
Spring DI
依存性注入の機能を提供。
Spring AOP
アスペクト指向プログラミングの機能を提供。
アプリケーションのレイヤ化
アプリケーションを理解・管理しやすくする為に、アプリケーション全体をひと纏まりとして捉えるのではなく、役割によってレイヤ化する。
DDD(ドメイン駆動開発)で定義されているレイヤは下記3層。また、各レイヤは複数のコンポーネントを包括する。
- Application層
- Domain層
- Infrastructure層
Application層とInfrastructure層はDomain層に依存して良いが、Domain層は他2層から疎な状態で、再利用可能でなくてはならない。
つまり、Domain層に変更が加わった際に他2層に変更が生じても良いが、他2層に変更が生じた際にDomain層に変更が生じてはいけない。
Application層
クライアントとの入出力となるUIを提供したり、リクエストを基にドメイン層を呼び出すなど、アプリケーションを構築する為のレイヤ。
この層はなるべく薄く保たれるべきなので、ビジネスルールを含んではいけない。
包括するコンポーネントは下記の通り。
Controller
クライアントからのRequestを受け取り、Domain層の適したServiceを呼び出す。
処理結果をViewに返却する。
View
クライアントへのUIを提供する。
Form
クライアントとController間でやり取りするデータを格納する入れ物。
具体的には、HTMLのformタグ内のデータを格納。(「Form」という名前の由来は恐らくこれ。)
Domain層がApplication層に依存しない為に、Application層→Domain層にデータを引き渡す際は、Formのまま渡すのではなく、Domain層のDomain Objectに変換してから引き渡すべき。また、その変換処理はApplication層(Controller)で行う。
Domain層
アプリケーションのコアとなるビジネスルール(業務処理)を担当し、Entityに対するサービス処理を提供するレイヤ。
包括するコンポーネントは下記の通り。
Service
業務処理を提供する。
Domain Object
- 業務処理を行う中で発生する管理すべきデータの入れ物となるクラス。
- その1種である
Entity
は、DBとアプリがデータをやり取り(アプリ→DB
,DB→アプリ
)する際の、データの入れ物となるクラス。- Application層のFormに格納されていたデータがEntityに格納される。
DAO,DTOデザインパターン
のDTO
がこれに当たる。- フィールドとアクセッサ(ゲッター,セッター)で構成され、クラス名はDBテーブル名と同じ名前にする。
- DBテーブルの1レコードが1クラスに対応し、クラスが保有する各フィールドが対象レコードの各フィールド(各カラムの値)に対応する。
Repository(リポジトリ)
- DBとアプリがデータをやり取り(
アプリ→DB
,DB→アプリ
)する際に、DBへのCRUD処理機能を提供するインターフェース。 - 実体はInfrastructure層の
RepositoryImpl
で実装するため、 どのようなデータアクセスが行われているかについての情報は持たない。DAO,DTOデザインパターン
のDAO
がこれに当たる。
Infrastructure層
Domain Object(Entityなど)にCRUD処理(永続化)を提供するレイヤ。
包括するコンポーネントは下記の通り。
RepositoryImpl
- Domain層のRepositoryインターフェースを実装したクラスで、実際のCRUD処理を提供する。
- 必ず、インターフェースを定義したうえで実装する。
- 使用する側(Domain層)のクラスが、クラス依存ではなくインターフェース依存でRepositoryを利用できるようにし、依存性を低くする為。
Repository
インターフェースがCrudRepository
クラス(Springが提供)を継承する事で、自動的にCRUDメソッドが利用可能になる。
O/R Mapper
にSpringDataJDBCを使用する場合は、実装したRepository(インターフェース)から自動生成されるため、実装不要。
O/R Mapper
DispatcherServlet
フロントコントローラ
と呼ばれ、クライアントからの全てのリクエストを受信してくれる。フロントコントローラパターン
と呼ばれる、デザインパターンの1種。
- リクエストを受信した後に、リクエストURLを基に然るべき
リクエストハンドラメソッド
を呼び出す。
リクエストハンドラメソッド
- MVCの
Controller
の中に定義されるメソッドで、クライアントからのリクエストを処理する。 - リクエストURLとリクエストメソッド(
GET
orPOST
)をアノテーションで記載する事で、リクエスト毎に正しいリクエストハンドラメソッド
を呼び出せる。 - 戻り値として、クライアントに返却すべき
View
の名前をDispatcherServlet
にreturnする事で、DispatcherServlet
はその名前に応じたView
に、HTMLを生成させクライアントに返却させる。
サニタイズ
- 危険なコードやデータを変換や除去する事で、無力化する処理。
- 例えば、Webサイトの入力フォームに悪意あるコード等が入力された際に、無力化する。
Thymeleaf(タイムリーフ)
SpringMCV
フレームワークにて推奨されている、動的にView
を生成する為のテンプレートエンジン。- HTMLベースのテンプレと、動的データをバインド(組み合わせる)してViewを構成する。
- JavaのWebアプリの
View
としてはJSP
がよく利用されるが、JSP
ファイルはWebブラウザが読み込めないため、開発段階でWebブラウザにてViewを表示して明示確認できないという課題が有る。 - 一方で、
Thymeleaf
はHTMLベースのため、ファイルをWebブラウザ上で明示確認しながら開発を進める事ができる。- そのため、UI(View)デザイナーとの分業が簡単になる。
Viewからのリクエストパラメータの受け取り方
@RequestParam
アノテーションを使う方法とForm
クラスを用いる方法の2種類有る。
@RequestParamアノテーションを利用する方法
- リクエストハンドラメソッドの引数に
@RequestParam
アノテーションを付与する事で、リクエストパラメータを引数として受け取る事ができる。View
のname
(入力項目名)と同じ引数名を宣言する。
- リクエストパラメータが増えるほど引数も増えるので、冗長になってしまう可能性が有る。
Formクラスを利用する方法
- Formは、リクエストパラメータを格納する為のクラス。
- リクエストパラメータを纏めて引き渡す事ができるので、パラメータ数が増えても冗長にならない。
POJO
で実装する。View
のリクエストパラメータのname
と、Form
クラスの変数名を同一名にする事で、リクエストパラメータが自動でForm
クラスのフィールドに格納される。- リクエストパラメータはフィールドの型に自動変換される。
POJO
Plain Old Java Object
の略。- 「ポジョ」と読むらしい。
java.lang.Object
を継承して、それ以外何も継承していない、シンプルなJavaクラスの事。java.lang.Object
は、全てのJavaクラスが暗黙的に自動で継承しているので、つまりは、明示的には何も継承していないクラスの事。
バリデーションチェック
大きく、単項目チェック
と相関項目チェック
の2つに分かれる。
単項目チェック
相関項目チェック
- 複数の入力項目(フィールド)に対して同時に行う入力チェックの事。
- 例えば、左の入力項目が奇数、かつ、右側の入力項目が偶数、の様なモノ。
- 自分で新たなアノテーションを作成するか、
Validator
インターフェースを実装するかの2択。
form-backing bean(Formクラス)
- バリデーションを行う際に必要となる、HTMLの
form
タグにバインドするForm
クラスのインスタンスの事。 @ModelAttribute
アノテーションを付与したメソッドでform-backing bean
を作成する。@ModelAttribute
アノテーションが付与されたメソッドは、そのクラス(Controller)のリクエストハンドラメソッドの実行前に呼ばれ、returnするform-backing bean(Formオブジェクト)
はmodel.addAttribute(form)
相当の処理が実行され、Model(ControllerからViewに渡される、表示データ等が格納されるオブジェクト)
に格納される。- Modelに格納される際、デフォルトではリクエストスコープで格納されるので、クライアントへのResponse後に自動削除される。
プレースホルダ
実際の内容(値)を後から挿入する為に、とりあえず仮に確保した場所の事。
ジェネリッククラス
クラスを定義する際に、クラス名の右側に
と記載されたクラスの事。 T
は「型パラメータ」と呼ばれる。<>
内の文字はT
でなくても良いらしい。class GenericClass<T> { private T data; public void setData(T value) { this.data = value; } public T getData() { return data; } }
クラスを利用する際に、
T
の部分に型を指定すると、クラス内のT
が指定した型に置き換わる。型は参照型(クラスやインターフェースなど)しか指定できず、基本型(intなど)を指定してしまうとコンパイルエラーになる。
下記例では、
String
型に置き換わる。GenericClass<String> genericClass = new GenericClass<String>;
トランザクション
複数の処理をひと纏まりにしたモノで、トランザクションが完了した際に、処理が全て成功していれば保存(コミット)、1つでも失敗していればトランザクションで行った処理を全て巻き戻す(ロールバック)する。
トランザクションの開始と修了の範囲を「トランザクション境界」と呼び、Domain層(MVCモデルにおけるModel)の入り口であるService(ServiceImplクラス)の中で定義する。
トランザクションを管理したいクラスやメソッドに@Transactional
アノテーションを付与すれば、トランザクションが自動で管理される。
application.properties
SpringBootプロジェクトにおいて、例えばDBへの接続情報等の環境設定を行う為のファイル。
Flash Scope(フラッシュスコープ)
1回のリダイレクトの間のみ有効なスコープ。
アノテーション
Springでは、「@」に続いて特定のキーワードを記載する形式でソースコードにアノテーション(注釈)を記載する事で、Springが標準で提供している何かしらの機能を対象のソースコードに付与する事ができる。
例えば、AOP(アスペクト思考プログラミング)を実現する際や、DIを実現する際などに使用する。
本書で勉強する際に頻出度が高かった一部のアノテーションをいかにメモる。
全体を通して使われるモノ
@Autowired
DI(依存性の注入)を担うアノテーションで、自動生成したインスタンスを、アノテーションを付与した変数に自動代入(注入)してくれる。これを行う事で、「new」キーワードによるインスタンス生成を記載しなくてよくなるため、newされる側のクラスに対する依存性が下がる。
Controllerクラスで使われるモノ
@Controller
クラスに付与することで、Spirngのコンポーネントとして認識される。
@RequestMappng
クラスやクラス内のメソッドに付与する事で、リクエストURLに対してどのメソッドの処理を実行するかのマッピングを行える。
アノテーションの第一引数にURLキーワード、第二引数にHTTPリクエストのメソッドを記載する。
@GetMapping
GETリクエストを処理する@RequestMappngの簡略アノテーション(「@RequestMapping」の第二引数に「Get」を指定した場合と同じ)。
@PostMapping
POSTリクエストを処理する@RequestMappngの簡略アノテーション(「@RequestMapping」の第二引数に「Post」を指定した場合と同じ)。
@ModelAttribute
メソッドか引数に付与する事で、それぞれ違った効果を発揮する。
メソッドに付与した場合は、リクエストハンドラメソッドが呼び出される前に、そのメソッドが呼ばれ、メソッドの戻り値がリクエストスコープでModelに格納される。form-backing bean
の初期化処理等に利用される。
引数に付与した場合は、リクエストハンドラメソッドが呼び出される前に、その引数に
リダイレクト
クライアントからの任意のReqに対応するリクエストハンドラメソッドでクライアントへのResの画面名をreturnする代わりに、他のリクエストハンドラメソッドに処理を引き継ぐ為に、他リクエストハンドラメソッドが対応するURLをreturnする事で、仮想的なReqを投げるイメージ。
例えば、本書のQuizアプリの中では、下記の様に使用していた。
// クイズを1件登録。 @PostMapping("/insert") // 「@Validated」アノテーションで「QuizForm」オブジェクトをバリチェックした結果が「BindingResult」インターフェースに格納される。 public String insert(@Validated QuizForm quizForm, BindingResult bindingResult, Model model, RedirectAttributes redirectAttributes) { // Formの中身をEntityに詰め替える。 Quiz quiz = makeQuiz(quizForm); // バリチェック。 if(!bindingResult.hasErrors()) { service.insertQuiz(quiz); redirectAttributes.addFlashAttribute("complete", "登録が完了しました。"); return "redirect:/quiz"; }else { // バリチェックがエラーになった場合は、一覧表示処理を呼ぶ。 return showList(quizForm, model); } }
上記は、クイズを登録する際のリクエストハンドラメソッドだが、11行目が該当箇所。
画面名をreturnせず、/quiz
というURLに対するReqが飛んで来た時と同じ処理を後続で走らせている。
【メモ】クライアントに同画面を返却する場合でも、Formの状態によって処理の走らせ方を変える
クライアントに同じ画面を返却する場合でも、Modelに詰めてるFormをどういう状態で返却したいかに応じて処理の走らせ方を変えている事に気付いたので、以下にメモを残す。
対象部分のソースは下記。
@Controller @RequestMapping("/quiz") public class QuizController { @Autowired QuizService service; // 「form-backing bean」の初期化。 // 「ModelAttribute」アノテーションを付与する事で、リクエストハンドラメソッドが実行される前に毎回このメソッドが実行される。 // returnされるFormクラスは、model.addAttribute(form)相当の処理が実行され、「quizForm」という名前でModelに追加される。 // 今回は、Formインスタンス内のラジオボタンの初期値設定のみ行っている。Formインスタンス内の他フィールドについては、後続処理の中で設定する。 @ModelAttribute public QuizForm setUpForm() { QuizForm form = new QuizForm(); // ラジオボタンの初期値設定。 form.setAnswer(true); return form; } // クイズの一覧を表示する。 @GetMapping public String showList(QuizForm quizForm, Model model) { // 新規登録設定。 quizForm.setNewQuiz(true); // クイズの一覧を取得する。 Iterable<Quiz> list = service.selectAll(); // 表示用「Model」への格納。 model.addAttribute("list", list); model.addAttribute("title", "登録用フォーム"); // クライアントに返却するView名(HTMLのファイル名)をreturnする。 return "crud"; } // クイズを1件登録。 @PostMapping("/insert") // 「@Validated」アノテーションで「QuizForm」オブジェクトをバリチェックした結果が「BindingResult」インターフェースに格納される。 public String insert(@Validated QuizForm quizForm, BindingResult bindingResult, Model model, RedirectAttributes redirectAttributes) { // Formの中身をEntityに詰め替える。 Quiz quiz = makeQuiz(quizForm); // バリチェック。 if(!bindingResult.hasErrors()) { service.insertQuiz(quiz); redirectAttributes.addFlashAttribute("complete", "登録が完了しました。"); return "redirect:/quiz"; }else { // バリチェックがエラーになった場合は、一覧表示処理を呼ぶ。 return showList(quizForm, model); } } }
ユーザがクイズ登録機能を利用した際に、入力したクイズデータがバリデーションチェックを通るか弾かれるかによって、処理の走らせ方を変えている。
具体的には、41行目と44行目。
処理の走り方の違い
それぞれどういう処理の走らせ方をしているか、簡単に記載する。
①バリチェックが通った時の処理
- 41行目で
/quiz
というURLに対してリダイレクト。 - 12行目の
setUpForm()
メソッドが呼ばれる。 - リクエストハンドラメソッドとして、20行目の
showList(QuizForm quizForm, Model model)
メソッドが呼ばれる。
②バリチェックで弾かれた時の処理
- 44行目で、Formオブジェクトを引数として渡して
showList(QuizForm quizForm, Model model)
メソッドを呼ぶ。 - 20行目の
showList(QuizForm quizForm, Model model)
メソッドが走る。
①と②の具体的な違い
具体的には、①と②では下記2点が大きく異なる。
- Formオブジェクトを初期化する、12行目の
setUpForm()
メソッドが呼ばれるかどうか。- ①では呼ぶが、②では呼ばない。
- クライアントに返却するView名をreturnする20行目の
showList(QuizForm quizForm, Model model)
メソッドに、Formオブジェクトを渡せるか渡せないか。- ①では渡せないが、②では渡せる。
処理の走らせ方を変えた意図
結論から言うと、Resした後のUIに、先ほどユーザが入力したデータを表示させたいかどうかによって①と②を使い分けているのだと理解した。
バリチェックが通った時は、UI上のクイズデータ入力フォーム等を初期状態(空文字等)にしておきたいので、先ほどユーザが入力したデータをResに含める必要が無い。つまり、Formオブジェクトは初期化されていてほしいという事。
一方で、バリチェックに弾かれた時は、UI上のクイズデータ入力フォーム等には、先ほどユーザが入力したデータを表示しておきたいので、Formオブジェクトは初期化してはいけないし、先程のReqで受け取ったFormオブジェクトをそのまま持ち回りたい(引数としてshowList(QuizForm quizForm, Model model)
メソッドに渡したい)という事。
所感
学習プロセス
目次
概要
学習プロセスを備忘録として以下にメモっておく。
学習を断続的、かつ、複数内容平行で行っているため、良いプロセスを発見してもその都度忘れてしまうため。
プロセス
- 書籍は紙媒体ではなくKindle版を購入する。
- いつでもどこでも読めるうえに、サンプルソース等のコピペも容易なため。
- 大切だと思う内容や、理解する為に利用したメモを、手元のmdファイルに保存しておく。
- 書籍の学習が終わったら、手順2の内容をはてなブログに載せる。
- 記事内検索で後で見返せるので、便利。
- ググって簡単に腑に落ちない内容を自分で理解しやすいように書き砕いていたり、サンプルソースで理解しているモノは、見返せる優位性が高いため。
- 理解が足りない内容も書き留めておく。
- 質問等で理解が深まった内容や、マサカリ頂いた内容を元に、はてなブログを更新する。
以上。
ProductBacklogの優先順位の決め方_WSJF
目次
- 目次
- 概要
- 【復習】ProductBacklog(PBL)とは?
- 【大前提】なぜ優先順位を決める必要が有るのか?
- CoD(Cost of Delay)とは?
- 純粋にCoDがより大きいモノから早くリリースすれば良いのか?
- WSJF(Weighted Shortest Job First)とは?
- 参考文献
- 所感
概要
ProductBacklogの優先順位を決める際の考え方やフレームワークはいくつか存在する。
そこで今回は、その中でも主流なWSJF
について纏める。
【復習】ProductBacklog(PBL)とは?
- ScrumにおいてPOが作成,管理するモノ。
- ProductBacklogItem(PBI)のリスト。
- PBIには、ユーザーストーリー形式で要件が記載されている。
【大前提】なぜ優先順位を決める必要が有るのか?
- プロダクトはユーザに使ってもらって始めて価値を発揮するため、てきとうな順番で機能を実現してユーザに届けるのではなく、より価値有るものがより先(早く)にユーザに届くように考える必要が有る。
- 例えば、毎月300万円の価値が有るプロダクトのリリースを3ヶ月遅らせる事で生じる損失は、900万円(300万円 × 3ヶ月)。
- 一方で、毎月50万円の価値が有るプロダクトの場合、150万円(150万円 × 3ヶ月)。
- 上記の様な考え方を
CoD
と言う。
- また、下記2つの観点で仮説度が大きいモノは、より早くリリースし、仮説検証を行う方が良い。
- 技術的実現性(フィージビリティ)
- ビジネス的需要性,収益性(ユーザに受け入れられるか?売れるか?)
CoD(Cost of Delay)とは?
- デリバリーを遅らせたせいで損するコスト(実現できなかった価値)の事で、「遅延コスト」と呼ばれる。
- 下記の3つの要素から成る。
- ユーザ,ビジネス価値
- ユーザやビジネスに提供する価値。
- ユーザに提供できる価値や、我々の収益に与える価値が大きなPBIは、なるべく早くリリースすべき。
- 緊急性(時間的制約)
- ユーザ,ビジネス価値は、時間が経過すると小さくなる。
- 決まったデッドラインが存在したり、競合との競争性が有るPBIは、なるべく早くリリースすべき。
- リスク低減
- フィージビリティーリスク(技術的実現性)やユーザ,ビジネス価値リスク(本当に需要が有るのか等)を早期に発見,解決する為に、仮説性が高いPBIはなるべく早くリリースするべき。
- ユーザ,ビジネス価値
純粋にCoDがより大きいモノから早くリリースすれば良いのか?
- 答えは「No」。
- Q:下記の様な場合において、どの様な順番で着手(実現)すべきか?
- A:1、2、3の順に着手(実現)するのが、トータルで得られる価値が1番大きい。
- つまり、
CoD
だけではなく、作業時間(JobDuration)
も考慮して、PBLの優先順位を決める必要が有る。- この考え方に基づいて優先順位付けを行うフレームワークが
WSJF
。
- この考え方に基づいて優先順位付けを行うフレームワークが
WSJF(Weighted Shortest Job First)とは?
- SAFe(Scaled Agile framework)で用いられているフレームワーク。
- 「重み付けされた最短の作業から着手する」という考え方。
- 簡単に言うと、「コスパ良いタスクから着手しよう」という考え方。
- PBI毎に下記式を計算し、値が大きい順に優先順位を付ける。
WSJF = CoD / JobDuration
CoD
とJobDuration
の見積もりには、相対
見積もりを用いる。- どちらの概念も、定量的に見積もり,評価する事が難しいため。
- Sprintをこなす毎に、相対見積もりの感覚値や考え方を振り返ってブラッシュアップしていく事が大切。
参考文献
- SAFe_Weighted Shortest Job First
- プロダクト・マネジメントの要諦 The Rules of the Game of Product Management
- 遅延コスト回避中心のPBIライフサイクルマネジメント
- WSJF (重み付けされた最短の作業から着手)という手法を使い始める
- 遅延コストとは何か?
所感
CoD
3要素を相対見積りする際の考え方や基準が非常に重要そう、かつ、難しそうなので、既に優先順位付け,リリースしたPBIとそのビジネス的実績を基にFBを繰り返していく事が非常に重要と考える。