この記事は予備原稿です。
Resultパターン(仮称)は、もともとバリデーターを実装するときに、バリデーションの成功と失敗をクラスで表現するために考案したものですが、処理結果に「成功」と「失敗」があるロジックに広く応用が効くモデルであることが確認でき、共有したら有益だろうと考えたため、Qiita原稿にし共有する予定です。
原稿作成にあたって、Resultパターン(仮称)をモデリングしていきますが、本稿はその過程と頂いた質問をツイートを元にまとめたものです。
これをベースにもっと単純化する #phper_oop pic.twitter.com/BOuU3NTPh3
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
Resultパターン(仮称)のモデルバージョン1ができた!進捗、ダメです…… #phper_oop pic.twitter.com/wWuHjeuabY
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
Resultパターン(仮称)すこし進捗した😊
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
バージョン2はFailure Reasoning(失敗の理由付け)ができるようになったモデル #phper_oop pic.twitter.com/hD4M3jRGcc
|。・ω・) 。o (カンニング中…… #phper_oop pic.twitter.com/ztyxC4I9oV
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
Resultパターン(仮称)v3までできた。SuccessのときActionが作った値をクライアントが取得できるようになったモデル。あと10分しかないぞ。 #phper_oop pic.twitter.com/dWr9b6LfrS
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
SuccessクラスのgetFailureReasonは例外を投げる以外にないよな……。ScalaのEitherもthrowしているからいいかな #phper_oop pic.twitter.com/oAEWSRia84
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
Resultパターン(仮称)が解決する問題は、
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
・結果がtrue/falseで暗黙的→意味のある型で表現
・PHPの戻り値型宣言はUnion型がないため型表明にできない→できる
・想定内なのに例外を使わざるを得ない→例外を使わなくて済む
> 想定内なのに例外を使わざるを得ない→例外を使わなくて済む
— hiro (@hirodragon112) 2018年11月14日
これだけでもありがたみが深い。
例内処理(想定内)で例外投げてるコード見るとげんなりします。。
PHPだったらclassにしたいですが、TypeScriptなら成功時の型をinterfaceで型宣言した上でオブジェクトリテラルにするのがスマートな気がしますね
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
TypeScriptでResultパターン(仮称)を実装したらジェネリクスやUnion型が使えるからもっと再利用性の高いパターンになると思う。PHPはそれらが無いから、似たようなコードを量産するのが現実論っていうジレンマはあるね。
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
Resultパターン(仮称)、PHPではGenericsがなくてデザインパターンのモデルを再利用しにくいと書いたけど、Genericsがある言語ならデザインパターンのモデルは二度と実装しなくてもいいくらい汎用的にできる。 pic.twitter.com/93p6adJYcv
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月14日
ResultパターンでRuntimeExceptionとLogicExceptionどっちを投げるか悩んでたが、RuntimeExceptionはコードを修正しても100%解決するわけでないとき、LogicExceptionはバグが原因なのでコードを修正したら100%直るやつという認識に至った。こちらの記事におせわになりましたhttps://t.co/27knMUjEnr
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月15日
Resultパターンのv3はLogicExceptionを投げるように修正っと。 pic.twitter.com/FBDjwvEQGv
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月15日
Resultパターンを値のバリデーションに応用したシンプルなモデルを作りました。他にも応用例を考えていきます。 pic.twitter.com/524AtmxJTz
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月17日
Astah Professionalを使っています。StarUMLはUIが素敵なので使っていましたが、canvasの広さに上限があり大きな図を描くのに限界を感じたため、Astah Professionalに戻ってきました😅https://t.co/5rwi7CN312
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月17日
Resultパターン(仮称)を認証ロジックに適応したモデルです。メールアドレスとパスワードで認証に成功したらアクセストークンがもらえるような認証を想定しました。 pic.twitter.com/mWRUwh7iYc
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月17日
Resultパターンの大事な主目的をひとつ忘れていた。それは、プログラマにエラーへの注意を向けさせること。例外はcatchが任意なのに対し、Resultパターンは成功時の値を取り出す前に、処理結果がそもそも成功なのか失敗なのかを確認する必要があるため、エラーハンドリングへの注意が働きやすくなる。
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月20日
PEAR::isError($result)の再来だ。Resultパターンを作りたくなる気持ちはめっちゃわかるんだけど、戻り値をfalseで返すとエラーメッセージが取れないって理由だけだったりするから、staticに呼び出せるMessageManager::addError()みたいなの作っても解決できると思う。嫌いな人はいるだろうけど。 https://t.co/XPIqY5IErE
— ひとフリ (@hitofuri140) 2018年11月20日
Resultパターンはエラー情報を格納するためのパターンと思われがちですが、このパターンの目的は、成功時の値を取り出すためには、エラーハンドリングをちゃんとしないといけないところにあります。それが例外や後付で呼び出せるエラーチェック関数とは設計理念が異なるところですね😊
— suin❄️PHPでオブジェクト指向 (@suin) 2018年11月20日