はじめに
WidgetやMVVMのViewModelで定義するメソッドの命名は二つのパターンがあると思っています。
- 処理を名前にするパターン
- イベントを名前にするパターン
アイテム作成するボタンを押下した時に呼ぶメソッドの場合それぞれ以下になります。
- 処理を名前にするパターン: createItem()
- イベントを名前にするパターン: onItemCreatePressed()
結論からいうと、イベントを名前にするパターンの方が好ましいとわかりました。
その理由を記事にしたいと思います。
イベント名の方が良い理由
ViewModel側とWidget側で分けて考えていきます。
ViewModelのメソッド名:なぜ「処理名」ではなく「イベント名」なのか?
最大の理由は、UI層とViewModel層の「関心の分離」をきれいに保つためです。
UIは「何が起きたか」を伝えるだけでいい
UIの役割は、表示とユーザーの操作を検知することです。
-
イベント名の場合: UIは「保存ボタンが押されたよ(
onItemCreatePressed)」とViewModelに報告するだけ。その後、実際にデータをバリデーションして、アイテム作成APIを呼ぶ…といった具体的な「処理」を決めるのはViewModelの仕事になります -
処理名の場合: UIが「アイテムを作れ(
createItem)」とViewModelに命令することになります。これは、UIが「このボタンを押したら、この処理が走るべきだ」というビジネスロジックの領域に踏み込んでしまっている状態です
複数のことをしたくなった時に破綻しない
例えば、ボタンを押したときに「アイテムを作成する」だけでなく、「アナリティクスにログを送る」「キーボードを閉じる」という処理も追加したくなったとします。
-
処理名(
createItem())にしていた場合:
UI側でviewModel.createItem()とviewModel.sendAnalytics()を両方呼ぶか、あるいはcreateItem()という名前のメソッドの中でこっそりログ送信も行うことになり、名前と中身が一致しなくなります。 -
イベント名(
onItemCreatePressed())にしていた場合:
UI側は何も変更せず、ViewModelの中でcreateItem()やsendAnalytics()を順に呼び出すだけで済みます。UIは裏で何が起きているかを知る必要がありません。
Widget(UI)側のプライベートメソッドもイベント名にすべきか
ボタン押下時の処理をWidget側でプライベートメソッド(_foo)に切り出すときも、やはり _onXxx(イベント名)や _handleXxx(ハンドラー名) にするのがベストです。
複数のことをしたくなった時に破綻しない
ボタンを押したとき、ViewModelを呼び出すだけでなく、以下のような「UI独自の処理」を行いたいケースがよくあります。
- フォーカスを外してキーボードを閉じる
- 入力エラーのトースト(アラート)を出す
- 画面を閉じる(Popする)
メソッド名が _createItem() だと、その中で「キーボードを閉じる」といったUIの操作を行うのは不自然になります。
さらなる疑問:Button などのコンポーネント名は含めるべきか?
さらに疑問が湧いていきて、コンポーネント名は含めるかどうか疑問に思いました。
例えば、_onSaveButtonPressed と _onSavePressed はどちらが良いか判断に迷います。
結論としては、Button を含めない _onSavePressedがよさそうです。
デザイン変更に強い
アプリを作っていると、「やっぱりボタンじゃなくて、右上の『アイコン』に変えよう」とか「テキストリンクにしよう」といったUIの変更がよく発生します。
-
_onSavePressedにしていると、アイコン(IconButton)やリスト(ListTile)に変更された際、メソッド名と実際のUIがズレてしまいます -
_onSavePressedにしておけば、見た目がボタンでもアイコンでも、ユーザーが「保存(Save)をタップした」という事実に変わりはないので、UIがどう変わってもメソッド名を変える必要がありません
おわりに
細かい部分ですが、ルールがあると、判断に迷うことが減り、コードも統一されます。
もし、まだルールが統一されていない場合は参考にしてください