やったこと・書いたもの{2020,07}

OSS

github.com ずっと鬱陶しがってたやつ直した。
ぐちゃぐちゃと考えないで、ごくごく単純なやり方で良かったなぁと気づいた・・・・

github.com 以前cake4対応を完了したのをawesome-listに対応してもらったもの。
3.0.1が出てからでいいかなぁ〜とか思ってたけど何もバグ修正や更新が現れないので、そろそろいっか!となり。

勉強会・LT

その他

ウェッブアプリケーションのエラーを無くしていきたいわよねという話

社内に何度か「ね!!エラー減らしてこ!!きっと良いことになるから!!」みたいな話を投稿しておりまして、そのラストに「じゃあ実際どうやって&どう考えて進めていくのかね」という事も認めました。
その内容が「またどっかで使いそう〜」と思ったのでリライトして載っけてみます。

長くなったので記事を分けようかなぁとも思ったのですが・・・

前提: 0次対応というコンセプトについて

エラーはいつ直すか?基本的には「気づいたらすぐ直す」のが最もコストが低いと思っています(なので、そのための土壌を整備しておくべき)。
ソフトウェアがおかしくなるのは、「変更を加えた時」もしくは「変化が生じた時」という事になるはずです。これについては後で改めて言及します。

この「変更を加えた時」において「エラーが起こりやすい」というのは予め認識しているわけですから、「デプロイした直後にはエラーが起きないかをいつもより注視し、発覚したらすぐに修正や回復に取り組む」というのが基本姿勢であると考えています。
これを、インシデント対応の「一次対応/暫定対応」「二次対応/恒久対応」になぞらえて「0次対応/未然対応」という風に個人的には呼称しています。
エラーが既に起こったことが観測された事へのリアクションなのだから「未然」じゃないじゃん、その言い方は詭弁じゃん・・・・と思われるかもしれませんが、「問題が大きくなる前に、ボヤ状態で沈下できた」というイメージです。そのエラーに実際に見舞われてしまったエンドユーザーを思うと重々反省すべきではありますが、もっと大事になってしまうよりかは。。。

ソフトウェア開発において「失敗を恐れない」ことは有効です。また、「まだ起きていないこと」を予測し回避するのは難しいことでもあります。
なので「筋の良い集中力の疎密をデザインする」のは重要です。
逆に、失敗を恐れるあまりに萎縮して、結果として緊張感が過度に高くサイクルを回すのも遅いような状態は望ましいものでもありません。
これらのバランスを取るためのプラクティスとして、「0次対応に力を入れる」という考えに至りました。

「なぜ」やるのか

全ては「サービスの信頼性」の為だと考えています。
前職では、サービスの信頼性について担保できるチームを構築する・スケールしていくために、という観点で「監視の民主化」に取り組んでおりました。

この流れの一環として「アプリケーションのエラーをメチャクチャに減らす」というのに取り組んでいました。
(週単位で、各レポジトリごとのエラー発生箇所数をメトリクスとして「エラーを減らす」に取り組んでいました→後述)

言い換えると、「エラーをゼロにするために、エラーをゼロにしようぜ!」という考え方は当初より持ち合わせておりません。重要なのは、 アプリケーションエラーの管理(アラート)を、モニターとして意味のある状態にできているかどうか というところに絞っています。
「いつも何かエラー通知が飛んできている -> 異変に気づきにくい」よりも「いつもは飛んでないのに、今なんか来た → これは異常が起きてるな?」が良いよね、ということです。
こうした「反応できる」という状態 を作れると、ものすごい価値を生みます。

先述のリンク先記事で触れている資料中では、「対障害のためのアラート」と「対品質のためのアラート」という呼び方をしていました。
前者(変な時にアラート)と後者(すっかりエラーゼロ)だと、前者はある意味で妥協なのですが、しかしコレが出来ればメチャクチャ効果あります。逃げるは恥だが役に立つって言いますしね。

f:id:o0h:20200626183356p:plain

どーゆー流れ

「実際にやっていくとしたらどう進めるか」についてはツラツラと考えている内容でもあるのですが、それを示します

  1. エラー管理ツールの整備
    • 「絶対に使いたい要件」を満たすようにツールの設定をする
  2. 棚卸し: 既存エラーのうち「要らないエラー」を無視できるようにする
    • サービス提供上の問題がないエラーは「ノイズ」とみなし、気にしなくて良いようにする
  3. 残ったエラーを個別に潰していく
    • 発生頻度が高い × 修正難度が低い、の組み合わせが最優先
  4. ここまで行くと「監視に便利」になる :tada:

エラー管理はどういう物が良いかな

適切にツールひいてはエラーと付き合っていくには、 付き合わない相手 を決めることが重要です。
要するに「対処する必要があるやつ」だけ流れてくればOK。
そして、対処する必要があるやつは「すぐ分かるようにしてくれ」という気持ちがあります。

そのためには、以下の内容が適切に扱えるものが望ましいと個人的には考えています。

  1. 「新規エラー」を教えてくれる
  2. 「多頻度で発生しているエラー」を教えてくれる
  3. 「沈静化しているエラー」を考慮してくれる

順を追ってみていきます

新規エラーについて

「今までになかったけど新しいエラーが起きたよ」というのは、アプリケーションエンジニア的には非常に重要な情報です。
サービスで何かしら「異変」が起きるのは、 概ね「変更をした」もしくは「変化があった」とき だと言えます。

  1. 人為的に開発者が変更を加えた時
    • 実装内容の不足・ミス
    • オペレーションのミス
  2. 外発的要因
    • アクセスの急増、負荷上昇
    • 攻撃に起因するもの
    • (クラウドの場合)マネージド領域の異変

もし「何か起きた」のがデプロイ直後なのであれば、コード周りのミスがあるか、データないしインフラ等の不備が考えられるでしょう。

この時に「すぐ気付いてすぐ潰す」ことができれば、利用者に対してのダメージを最小限に抑えらます。それと同時に「なんとなく心当たりがある」ことによって、改修コストも著しく下がります。

なので、 「新規エラー」を教えてくれる ようなツールが良いと考えています。 もちろん、その際に「同じと思われるエラーをグループ化してくれる」のも重要な要素です (例えば、「URLや呼び出し元クラスが違うけど、エラーを引き起こしてるのはモデルクラスの修正ミス」だった場合、stack traceが違っても「同じモデルのエラー」として扱って欲しい)

頻出エラーについて

いわゆる「準正常系」もしくは「runtime的にエラーの完全回避が免れない」ものとは、どうしても出てきます。
例えば「ファイル出力を伴う処理で、リクエストのタイミングによってはalready_file_existsな感じのエラーが起きる」とかそういうやつです。

アプリケーション内部の持つロジックとしてそれを回避できるように整えるのも重要ですが、もし「ユーザーに対しての不利益がない」という確証があれば、そのエラー自体はあまり痛くないかも知れません。
数日に1回はやっぱり起きちゃうよね〜なんて見て見ぬ振りをするのも選択肢の1つです。

が、これがもし「直近30分で100回も発生している」となったらどうでしょうか?
これは「エラー自体はよくあるやつ」で看過できないような、重大な異常のサインとなります。

なので、 「多頻度で発生しているエラー」を教えてくれる とオペレーションフレンドリーな設定が可能になります。
「新規」がopen/closeなフラグによる監視だとしたら、「頻度」はfrequnecyをみるものです。
「あれ、やっぱり変だね」を際立たせる手段は非常に有り難い存在となります。

しきい値として「どのくらいの頻度になったら」は、エラーの質やプロダクトの性質・品質によって変わります。
方針としては、「おかしな量」のしきい値を厳しくすると「けたたましいアラート」になりますので、なるべく緩めにしたいところです。
例えば「10回起きたら異常」と「100回起きたら異常」というのでは全く性質が異なってくる、というのは想像できると思います。他方で、「10回起きたら異常」と「1回でも起きたらヤバい(ユーザーないしデータが被害を被っている)」の違いは何でしょうか?こうした「n回許容できるエラー」については、様々な要素を加味した上での判断が求められます。

定量的に監視したい」ものについては、「そこのコードが悪くないが、他箇所のコードやミドルウェア以下の技術要素等との組み合わせがおかしいもの」とも考えられます。
ここで不安感を過大評価しすぎると「すぐに拾いたい」方向に傾きがちですが、「すぐに拾うべき」ものは極力「1回も発生を許さない」と分類し、実装において解消されるべきだと考えます。
「ユーザ視点での監視」を意識し、「監視のアセスメントを行う」ことで適切な閾値を発見していく・洗練していくことが重要です。

沈静化しているエラーについて

開発を行っていると、そのソフトウェアは日々変化していってるため「いつの間にか何も問題がなくなっている」という事は多々あります。他の箇所の修正で直ったとか、そもそもコードが消されたとかいったものです。

こうした「(明示的に解消を記録してないが)沈静化している」エラーについてはしっかり浄化されていく必要があります。

なので、 「しばらく経ったけどもう大丈夫そう」というエラーはactiveでないと見なしてくれる と日々の運用におけるノイズが減ります。そうすることで、「今起きていること」についてだけ知ることが出来るわけです。本質的なこと、本当にやるべきことにフォーカスしましょう。
設定したインターバル中に1回も起きなかったら自然消滅する、みたいなのが良いですね。

「どのくらいのインターバルをおけばいいか」は、対象となるPJのリリース頻度やチームとしてエラーの解消をどの位こまめに行えているかに依りそうです。

自分が過去にいたチームで行った設定を例に取ると、「3日間なにもなかったら自動でクローズ」です。
これは比較的短い単位で「またアラートが飛んでくるようになる」という事を意味します。一見すると「問題が解決したとみなすハードルが低い」ので「運用をゆるふわにする」ような印象を持つかも知れませんが、体感としては逆の事態が起ることになります。
これをもし、1週間や10日というインターバルにしたのであれば、「(エラー管理ツール上はactiveなままだけど)再発のアラートはあんまり飛んでこない」という事になります。

どうやって気づくか: push通知(アラート)と組み合わせて考える

アラートは「何かが起きた時に気付かせてくれる」ようにしたいです。
ここまでに整理した3点について要件を纏めると、

  1. 「新しいエラー」が起きたら通知してくれる
  2. 既存エラーを「明らかにおかしな量」検知したら教えてくれる
  3. 解決済みのエラーが「再発」したら教えてくれる

といった条件が浮かんできます。
これらをSlackに飛ばせると良さそう。

また、「頻出」エラーについては、その他のトリガーよりも少し警戒レベルを上げて発報する・・・という手段を検討して見る価値はあるかも知れませんね。(発報先のチャンネルを変える、メンションの対象範囲を変えるなど)

あるいは、しきい値を複数用意してnotice/warnを出し分けるのも良いアイディアです。
もし利用しているツール単体ではそうした繊細な管理が難しそうであれば、CloudWatchのカスタムログにoutgoingしてCloudWatch Alarmに管理させる〜なんて手もあると思います。もしくは、インシデント管理全体のデザインから見直して「ツールを組み合わせる」ことも考えられます。個人的なオススメはPagerDutyです。

これらの「1,3: 発発生したらアウト(要対応)」のものを「定性的なエラー: 内容に対する監視を行っている」、「2: 頻度を見て通常の状態から逸脱が見られる」ものを「定量的なエラー: 動向について監視を行っている」とみなすことも出来るかと思います。

「定性的な監視対象のものが、定量的な観点でも異常と言える」ものは緊急事態が発生している可能性が高いです。
例えば「データベース接続エラー(めったに起きるものではない!)が1分で100回も起きる」のは緊急度が高いですし、これはインフラに対してアプリケーション観点で統合的に監視していると考えることも出来ます。アプリの範疇を超えたモニタリングの責任を負わせるのか?と捉えると違和感を覚えるかも知れません。が、気づくキッカケはどこでも良いのです、とにかくヤバいことだけ伝われば後は人が対処できる・・・
あるいは、もっと単純に「未定義変数の呼び出しが行われている」といった「そこまで緊急的なものではないかも」というものでも、「3分で500回も起きた」ならば、それはユーザーの利用頻度が高い・リクエストが集まっている箇所でのダメージが考えられるので、対応すべき確率が高くなるはずです。

蛇足: アラートは少ないほうが良い

「FYIの通知」と「誰かを叩き起こすためのアラート」という考え方は基調に据えるべき重要な指摘だと思っています。
それにしたって、「要対応レベルではあるけど即死級ではなさそう」なものであっても「1週間に1個だけ飛んでくる」という話であれば、きっと真面目に対応することも可能になるでしょう。これが「毎日100個」となると大変です。

「そもそもアラートが鳴らないようにする」ことを徹底しておけば、「たまに飛んできたエラーにじっくり向き合う」ことも現実的になるはずで、自ずと「Informationの質が上がる」ことに繋がるのではないかと考えています。

「要らないエラー」を捨てる = 情報を断舎離する

「ユーザーの操作が前提条件を満たしていない」「想定の範囲内ではあるが(=正しく制御された結果として)、内部的にuncaught exceptionを使ってユーザーの操作を停止させている」みたいな場合に、実装的にはエラーじゃないが表現として例外になり、エラー管理ツール上に登録される みたいなものが発生してくると思います。

「既にエラー管理ツールに可視化されている内容を金輪際シカトする!!」のは、割とドキドキする作業ですが、経験上、ここを徹底できると物凄く捗るな〜というのを個人的には心得ています。

例えばcakephp/app では、「PageNotFound Unauthorized などの例外はガッツリ管理する必要はない」といった設定を示しています。
https://github.com/cakephp/app/blob/3d543a0a9ae03ac299bc2b1c222fe08570a9bf7f/config/app.php#L174

これらの例外は、確かに「ユーザーの要求通りの結果を返答していない」という点でエラーではありますが、実装者側ではなくユーザーの操作に起因するところも大きいですし、「どーしようもないじゃ〜ん!」って感じです。
なので、「ログ(=エラー管理ツールへの登録)は要らない」というのは納得しやすいのではないでしょうか。

ただし、これらもうまく付き合えば異常を顕すシグナルとして利用できます。「めっちゃ変な動きをしているね!」を拾える工夫は可能でしょうか?
そのために別のツールで「定量的に監視する」というアイディアが生まれます。

例えば「ユーザーの送信データがバリデーションに引っかかってエラーになった」というのは、単発であれば「ユーザーの入力ミス」で済ませるのが自然です。

しかし、これが「1分間に100回発生した」らどうでしょうか。もしくは「新しいコードをリリースした途端に10%増えた」だと、看過する訳には行きません。
こうした場合、 「validation ruleが間違っている」かも知れません。もしくは「バージョン管理をclient側との上手く協調できていなかった」という事も考えられます。「UIが著しく使いにくくなった」という事もあります。

あるいは、HTTP Responseコードをインプットにしたモニタリングも効果があると思います。
Cloud WatchだとデフォルトではELBのステータスコードの内訳がざっくりしている(4xx/5xx)ので、別途ログを集計する手立てが必要になるかも知れません。少なくとも、400/401/403/406/413/500/502/503/504辺りは欲しいかも。

何にせよユーザー体験の悪化が発生しているシグナルになるので、ここでちゃんと対応していくのがサービス信頼性につながります。
ということで、「別観点」を組み合わせた監視をすることは個人的におすすめです。

また、そういった「セーフティネット」を敷くことによって、「大胆に削ぎ落とせる」ようになるのも狙いの1つです。
もし「単純に無視するようにするだけ」だと、「何も気づけ無いのは怖い」という不安がつきまとってしまいます。ここで踏み込めないでいると、結局「エラー管理ツールにノイズが増える」状態や「恒常的に発生し続けて、activeなままのエラーが増える」ことになります。
これは、「今すぐ対応すべきものが列挙されている」という理想状態に対して大きな妨げになります。
そうならないよう、「無視させる、が、拾うことも出来る」という手段を用意しておくのは重要です。

定量監視どーやってたん?

定量監視とはいうものの、「1発なら無視できるものの頻発したら退っ引きならねぇ」みたいな類なので、「どこで」「どうして」というのが極めて重要になります。
そこで、「何か起きた」時に「ちゃんと内容をドリルダウンして観察できる」のも重要です。

ということで、

  1. エラーの「記録」に2系統を用意する
    • 定性的に見たいものはアプリケーションエラー管理ツール(※利用していたのはSentry)に飛ばす
    • 定量的に見るだけでいいものはログツール(※利用していたのはPapertrail)に飛ばす
  2. アラートも2系統になる
    • エラー管理ツールに入ってきたものはそこから通知する
    • ログツールに飛ばしたものはCloudWatch(カスタムメトリクス)経由でAlarmを使う

みたいな使い分けをして、監視に柔軟性をもたせて、「なにを見たいかな」ベースで適所適材!どっかで網羅!!という事が実現できれば良いかなと思っています。

具体的には、

  1. 割と細かい粒度に独自例外クラスを定義して
    • 抽象クラス(ないしInterface等)で「定量監視用」というのを分かるようにして
  2. 「普通の例外」「定量的に追えば良い例外」に応じたエラーハンドリングを用意して
    • 後者はPapertrail(->CloudWatch)にだけ記録される
    • Papertrailでは、例外クラス名ごとに個別にsearchを保存して、CloudWatchに毎分exportしていました
  3. CloudWatch上で、例外クラス名ごとにカスタムメトリクスを設置
  4. CloudWatch Alarmで個別にしきい値を設定し、Slack等に通知可能にする

という方法で実現しています。
エラー内容やStacktraceなどは、Papertrail上で確認することになります。

あとは地道に対処していくよ

ここまで進めると、残っているのは「サービスの提供品質上、潰して行く必要がある」ものです。なので、とにかく片っ端から潰していきましょう。
重要度(もたらすダメージ)が大きい × 頻度の高いもの × 簡単に直せそうなもの、という掛け算で優先順位を付けていくのが良いと思います

実際どこまでやるんよ?

さて「恒久的にエラーを0にするぜ!!」というのはもしかしたら難しい目標かも知れません。
それでは、何をモチベーションにエラー潰しをやっていけばいいでしょうか?これは、「良い感じにやる気の出るしコミットしたら跳ね返ってくるKPIを設ける」という他ありません。

私がいたチームの場合は、 週次の定点観測を行い、レポジトリ×領域(backend or frontend)ごとにactive状態のままのエラーの数(種類数)を追う というようにメトリクスを決めました。1
※ 「種類数」 = 「unique error数」みたいな感じです

以下のような理由からです。

  1. 1週間のエラーの「発生件数」については、コントロールがしにくい
    • 「1リクエストだけで複数回起る」ものがあると一気に失点が増えます
    • ループの中でnotice起きてる、とか
  2. 1週間のエラーの「発生種類数」については、開発者に負のモチベーションを与えかねない
    • 実現したいのは「信頼できるサービス」であり、これには「しっかりと改修・改善され続ける」という性質も含まれるはずです
    • なので「リリース恐怖症」を誘発してしまうのは、本望ではありません
    • もし「エラーが起きたらアウト」にすると、罰がおもすぎるのです
  3. 1週間のエラーの「アクティブな種類数」なら、エラーを直すことにもモチベーションを与える
    • ごめん!バグった!→すぐ直したわ!!→よ〜〜し、ならOK!
    • また「発生件数は多いが、重要度が低い」というものに対して、誤った優先順設定を行ってしまうリスクを下げる意図もあります

こうしたトラッキングを行いながら、「着実に一歩ずつ進めていく」ような流れを作る事ができました。
・・・「一歩ずつ」とはいうものの、要らないエラーを捨てたときには一晩にして目覚ましくエラーが減ったりしますが 👻

安心感のある開発、いいですよね〜〜!

ということで、こうやって「エラーを綺麗にしていく」ことが叶うと嬉しくなっちゃいますよね〜〜と個人的には考えています。
ココに上げた「エラー管理ツールの要件」は比較的ミニマムな要求だと思っていて、他にも「コメントがしやすい/markdown等の記法が使える」「ソース管理ツール(GitHub)との連携が高機能」「エラーの検索が使いやすい」「簡易的な統計が使える」「アラートの管理が柔軟(一時的なsuspend、指定条件による自動的なunsuspendなど)」などなど、使い心地に直結する要素は多々あると思います。また、「提供されているSDKがしっかりしている、もしくはSDKに頼らずとも使いこなせるくらいシンプルで柔軟である」などの観点も欠かせません・・・

個人的にはSentryがこの辺りの要求を満たしてくれていたと感じているので、結構オススメできるサービスです。
「どういう風にエラーを管理していくか(平常時のボトムラインをどう設定するか、どのくらいエラーに向き合い対処するか)」「エラー対処のためのワークフローをどう組むか」といった、 チームでどう動くか/どういう意識合わせをするか 次第です。
別に「いつもエラー垂れ流しでも構わんよ」というのであれば、あまりエラー管理ツールに拘らなくてもも良いでしょう。実査に、基本姿勢は「何かあったら対応しよう」に過ぎないはずで、この「何かあったら」の基準について色々な考え方があるよね〜という感じです。

実態に即した・身の丈にあった・それでいて理想を掲げてアプローチできるような!!そんな「あるべき姿勢」というものを、まず定義してみよ〜というのが全てのスタートになるのかな、と思います。


  1. コレ自体はGASのスケジュールトリガでSentry API叩けば容易に実現できたし、票&折れ線グラフで示せて快適だった

リーダーが主人公の組織

ということで、下書き放出です。

最近なにかと、チームってなんじゃらほいとかいった事を考えている。
・・・かつて自分と一緒に働いたことのある人からしてみたら、「お前が何を」「どの口で」と思われそうだけど。膝に矢を受けてしまうことは誰にでもある。

主人公とは、例えば漫画や小説でいうところの「内面や心理の描写が行われる」みたいな存在か。*1
そして「物語を進める」という役割でもあると思う。もちろん、外的な要因や周囲の人物に巻き込まれ、触発され、転がり落ちるように進んでいく事も多いが。が、「傍観者」や「モブ」とは異なり、仮に主体性がそこに内在しなくても、世界は彼(女)を中心に進むーといったような。

では、現実的なビジネス等の場面で、チームにおける「主人公である」とはどんな状態なのか?
まず最初に「その人物が何を思い、どういう動機で動いているのか」というのは意識される必要があるなと感じる。
漫画なら回想シーンが入ったりする。人は原体験に突き動かされる生き物だ。なので、過去にどんな事があって今に至っているのか・・・というのが見えてくると、途端に「憎めなく」なったりもする。そして、それと合わせて現在進行系の理想や「もっとこうなりたいんだ・・!」という覚醒の語りが描かれるのである。
こうして、サブキャラや脇役が、これまでのただの演出上の装置から 物語を突き動かす側 へと変わる。 彼/彼女が何かを言った時に、以後は「意味のある発言」になるだろう。共感すら得られるかもしれない。
無味乾燥な、形式的な「いま何を考えているか」から何歩も踏み込んだ「なぜそういう考えに至るのか」という次元で協調をしてけるとチームというのは有機的につながり活発な主体となると思っている。そのために、主人公的な独白は意味のあるものなのではないか、と。

さて掲題。
自分としては「リーダーが主人公になる」といいうのはアンチパターンなのでは、という考えも持っている。必要なことだし、そのポジションに至るに足る理由があってそうなっていると思うので、おかしな話ではあるのだが・・・
そもそも「権威」がある時点で、その人の一挙手一投足、発言の一言一言に「存在感」が出てしまうと思う。それに対峙しなければいけないのはチームメンバーである。
また、実際に「的を得ている」「正しい」ような発言が多いのだろう。

だからこそ、リーダーこそ「主人公」であってはいけないのではないか?と思うのだ。
例えば、外から見て「あのチームって最近なにしてるの?リーダーの○○さんが頑張っているのは知っているけど」「へぇ、あっちのチームはそんな新機能だしたんだ!流石だねぇ、○○(リーダー)さん!」となっている状態・・これは不健全なのでは、と。

何でそんな風に考えるんだろう、って思うと「1番自分が頑張るタイプのリーダー」の姿を見たからかなぁ。。
確かに広く深い知識を持っている。現状の課題を認識している。その人が、「徹夜して抜本的な改善を成し遂げました」というのを何度も見ていたら・・?
スタンドプレー、とまで言うと言葉が強いが、やっぱり「他の人は何をしているのかな」というのが見えづらい気がする。
まぁ、コレは「傍から見ていて」の話なのだけど。実際に輪の中にいたら状況は違って、「頼れる兄貴」な側面のほうが強いのかも知れない。

しかし、「全部をその人が決めている」ような雰囲気を(勝手ながら)感じてしまい、「他のメンバーは『チーム』という一人格に対して与すことが出来ているのだろうか」などと思った。
課題を見つける、方針を決める、成果も上げる。 コレが一箇所に集中した場合、経験も機会も自主性もその人に集まってしまうと思う。
そうすると、自ずと得られる体験にはどんどん乖離が生じる。
そして、自分も過去に「やっちまった」側での心当たりがあるのだが、そういう場合は往々にして

「だって、他の人が誰もやらないじゃん。こんなに課題はあるし、やって良い自由もあるのに」

と思っている事が多いのではないか。
そうした”中心人物”を周りから見ると、「自由がるのは分かる、課題も感じる、でも自分は○○さんほど上手く出来ない」とかって精神的に怯んでしまうような状況になってしまいそうで。。

ここに矛盾があるのだ。
そのリーダーも、メンバーの成長を望んでいると思う。その方が自分のためにもなる。単に実務量や負荷分散という物理的な面もあるが、それ以上に「対等にやり合える仲間」が居るのは楽しい。自分のためにもなる。
しかし、その「成長」の可能性を、ともすれば自分で奪ってしまっている・・・・

「できる」から「機会」があり、そこでようやく「自分が主人公」になれる。理想的な流れ。
しかし実際は、「先に主人公になってもらう」ことが必要なのではないか。
チームをリードしている自分が、チーム全体の成長性に対するブロッカーになってしまっている・・・という可能性はないか。

そんな訳で、誰もを「主人公」にするチームが、信頼とそれを糧にした再成長を望めるのではないか?なんて事をモヤモヤと考えたのでdump。

自分としては、

  • やっぱり「皆が主人公」になって、物語を紡いで、そこから共感を得たりキャラクターを理解できた方が楽しく働けそう
  • 自身に対しては、「強権」をいつのまにか持っちゃっていないか・・?は意識していきたい

という感じ。

*1:必ずしも作品の主人公とイコールの関係ではないけど、いわゆる「○○回」というものにおいて、その瞬間の主人公はサブキャラクターにまで移る。山王戦いいよね・・

「依存性逆転の原則」は人間にも適用できないか、という思考実験

SOLID原則のD、「Dependency inversion principle」だが個人的にはClean Architectureを読んで理解が深まったように感じている。単体のクラス設計にとどまらず、パッケージ単位で見たらどうなる?という話も含まれるが、「どのくらいズームイン/ズームアウトしようと、依存の流れをどうしたいかという意思は同じだろう」と思う。

ざっくりいうと「お前がどう使われたいかはお前自身がハッキリ定めておけよ!!」という。 これは「組織」というパッケージだったり、「個人」という単体コンポーネントだったりにも適用できるのではないか?などと思った。

表面的に考えると、「人は組織に所属する」ということで、これは集約ないしコンポジットと考える。所有もしくは部分と言う関係だ。「人: 組織の一部」。 また、「組織は人に依存する」ということになる。
組織全体での期待が、具体的には「他の個人」からの依存という形で現れたり、単に「組織-役割-個人」という関係性の中に規定されていたりする。

パッケージの外部に「私はこういう約束を満たします」というのをInterfaceとして定義して、外の奴らはそのInterface=取り決めに従ってメッセージを送りあえ、というのがClean Architectureで語られている「良いやり方」だった。これによって、処理の流れと依存の方向性が逆転する = 依存性逆転を実現できる。
結果として、「不要不急の変更に(内部構造まで)振り回されることがない」、抽象度を高めた状態になれる。
多くの人と関わったり背負う責務の幅が広くなるほど、被依存が生じる = 安定度が高くなる。・・・「安定度が高くなる」と言うが、要するに「安定していなければ困るという度合いが高まる」、"不安定" "多動的"であってくれるなよという祈りが捧げられる。安定度が高いなら抽象度を同じくらいにまで高めなければならない。抽象度を高めるには、「意味のある」「明確な」Interfaceの設置だ。それが正に外部との接触面となり、他人とのやり取りの「出入り口」となる。

組織と個人の間では、責任と期待によってメッセージングされるものだと思っている。組織は人に責任を与えることで語りかけ、人は組織に期待を持って語りかける。「対組織とのやりとり」はそのまま「対・組織にいる誰か他の個人とのやりとり」と置き換えることも出来る。 往々にして、自分の属する組織≒環境に対しては「こうあって欲しい」という期待を抱くものだ。そして、その期待が満たされて嬉しかったり、不足があれば「裏切られた!!」とすら感じたりする。・・・これは、ひじょ〜〜に不安定である。
全てが上手くいけばいいのだが、「裏切られるかも」というリスクがある以上は、これをどうにか避けるための戦略が必要になると考えている。そうすることで、自身の存在を安定させられる。

ここで、掲題の通り「では、俺が依存するのではなくて、俺にどう依存するかはコチラの表明によって決定させてしまえばいい」と考える。これにより「使役先の振る舞いから自分の存在を保護できる」というものである。
依存性をどうコントロールするか?というと、インターフェイスの設置 = 「約束事」「取り決め」の公開だ。
「自分はこういう存在である、こういう事ができる、こういう風にしたいと思っているしその役割を果たさせてくれ」という「こう期待されたい」の期待値を、十分にexportしていく・・・・という取り組みは、「依存性の逆転」をもたらすことができないか?

環境による「裏切り」は、ひとたび起きてしまうと重大なダメージなると感じていて、自身の選択を嘆き続けるような日々をもたらす。
それを避けるために、なるべくコントローラブルにしていきたいものだ。
単純な話、積極的に「自分はこういう風にやっていくぞ、頼んだ!!」という合意をとっていくことで、他者との関わり方をしなやかにしていきたいと考える。

素人になりたい

「自分はプログラマとしてやれてきただろうか」というと、それはそうだろうなと思う。実際、そうやって税金を払い続けてこられているのだし。
ただ、それでも満足はしておらず貪欲さは持ち合わせており、「もっと周りに影響を与えるようなプログラマになりたい」「深い思考と美しい説得力を持ちたい」などと思っていたりする。自分の中での「ちゃんとやれている」を持ちたい。

どういう状態になれれば、この先も生存していけそうか?というのを考えて現時点で浮かんでいる大まかな方針は2点。
なお、これらは「今後も未来永劫変わることのない黄金律だ」というものではない。今までの長期スパンでの経験や直近数ヶ月足らずに見聞きした自身の経験・・・そういったものを足場として導出した「仮説」に過ぎない。常に検証と批判に晒し続け、適宜アップデートしていくこと。

  1. インプットとアウトプットの量を増やす主体は自分である。他人に甘えたり依存していると限界がある
  2. 自分のやる気が落ち込むのは周りとの折り合いが悪い時。他人を障害点とするのを避けるために、自己とチームのために動く

ここ数年を振り返ると、敢えて強烈な言葉で叩きつけるならば、「凄く傲慢で天狗になっていたな」と思う。
それは環境がそうさせた部分もある。 自分より上手くPHPを書く人間がいなかった という思いが、自分の中の権威を増長させてフラストレーションを爆発させた。
もちろん、世界にはまだ、遥かに先を行く人や強靭な知識体力を持つ人がいる。世界、といっても何も遠い大陸のことを想起しているのではない。同じ言葉を喋り同じタイムゾーンで暮らし、同じ電車を乗る人の中にですらそれは居る。

なのに自分は何をこんな所で停留しているんだろう、そんなおかしな話があるのか?という想いから、居る環境を変えた。
実際、新しい職場では何度も衝撃を受けた。思ったとおりだ、凄い人がいる。そういう人たちと同じチームに受け入れられたのは、自分にとって誇りだと思っている。
感嘆したのは彼らの「案の定」の知的で深い思考だ。なんでも知ってる、随分とかっこいいものを作る。それができる強力な力を持つ。
が、それにも増し、何よりショックだったのは、その人達は「とんでもなく勉強している」ということだった。暇があれば本を読んでいるのか?いや、暇でなくても本を読んでいそうだ。しかもそれを咀嚼し、体系化しているのか?
恐らく、常に課題や疑問を持ち続け、そこに対しての解を自力で探求し続けているように見えた。単純に言うと「気になった本があったら読んでみよう」だ。学ぶことに対して手をこまねいたりしない。

なるほどな、自分は「何かを考えている」ようで、全然その足元にも及んでいないな、と思った。ここまでやれてきたつもりだったのに、ショックだった。
技術や研鑽の話で、「一生懸命やる」という事は、した試しもあるし出来る自信もある。「プログラマとして雇われ、たくさん働いたことがある」というのが自分にとってのそれ。把握できている(手元に記録が残っている)だけでも月に380時間ちょいほど働いたこともあるし、恐らく400時間を超えている時もあると思う。
それは鎖自慢・・と確かに大差ないが、ただ「我武者羅にやったことがある」というのは自分の力を養成するのに間違いなく与した。それによって身についた実践知は今を作っている。良い未来を持ってきてくれた。

そうやって、会社や職場が「自分を伸ばしてくれた」と思っている。
別に何かを講義してくれたり指導してくれたという話ではなく、壊れたピッチングマシーンのごとくただただボールを放ってくれた。永遠に打席に立つことを繰り返してきた。
そういう経験があるから、自分が凄い人になるには、「凄い珠が飛びかっていそうな環境」に行くのが正解だろうと考えた。それが、自分の選ぶべき道だと。

しかし蓋を開けてみれば、「どんな球が飛んできているかは関係なく、凄い人は凄い」のだ。
別に過去に書いた話が間違っていて、嘘だったとは思っていない。「プログラミングやエンジニアリングについての向上心があり、それをプロダクトに反映できる事」も「 一緒に働くメンバーや社内にいる人から技術的な刺激を得られる事」も重要だ。
ただ、自分より凄い人が居る環境に行けば「その空気を吸うだけで僕は高く跳べると思っていた」ような面はあったかも知れない。
確かに、そういう人らがグランド・デザインから関わっていて思想が毛細血管のごとく隅々まで張り巡らせている・・・という場に立てれば、普通に仕事をしているだけでも得るものは多いかも知れない。だが、「凄い人がいる」 = 「その人達の思想や思考が浸透している」ではないのだな、と知った。
問題は、「そうではなかった」のに、ちゃんと武器を持ち強みを磨いている人がいるということだ。その力こそ、自分の成長を保証するものではないか・・?

改めて、「みんな素人」という言葉の意味を知った気がする。
この数年、「CakePHPを上手く使える」という自負が、いつのまにか自身の殻となり首を絞めていたなぁと思った。「俺はもう素人ではない」という傲慢さだ。
選んだ会社のスタックがCakePHPだったからこそ、「自分は全然通じる」と「それだけでは物足りない」と「会社から与えられたものに規定されていては駄目だ」というのを味わえた。
職場環境や自チームの力が、自身の成長の天井になっていると考えて転職した先で、自分の天井を破れていないのいは自分のせいだと思い知らされる・・という結末になったのは何とも皮肉ではあるけれど。

どうやって自分を伸ばすか・・・やっぱり「素人になり切れるか」ということだ、と感じている。
自分は実践から学ぶ。高校も大学も座学のほとんどには退屈していたが、受験勉強とかレポート作成とかの「独学」のターンになった瞬間に、これは自分のフィールドだと感じた。そもそも、プログラミングを始めて企業から雇われるに至るまで、それには「野良プログラマ」としてやってきたのが自分の成長の源泉だった。
自分は実践から学ぶ、そうである以上は手を動かし続けることを自身に課さなければならない。座学や与えられただけの教義には感動できないのだから。ただ「未熟なことをやるのが怖い、恥ずかしい」?なら「プロ」なんてやめてしまえ、素人に戻れる方が遥かに逞しい。

前職で終盤には上司になった人の話が、今読み返してみると凄く良いと感じた。
30代から始めるwebフロントエンド入門 - Speaker Deck
あるいは、初めて読んだ時から強烈に感銘を受けた記事。
移住することにしました | NEW GAME @kunit

かつて野良プログラマだった何でも出来る(出来ない)自分との差分として、今だからこそ一言だけ加えれば、「須らく必要なことだけ学ぶ」というのを改めたほう良い。その態度は、「今やれているから、そんなに必死に学ばなくていい」を連れてきたと思っている。歩幅の大きな一歩を進めようとする時に、頭を使う必要はあるが賢くあろうとする必要はない。
自分が目の当たりにした「凄い人」の「凄さ」は、学びの姿勢にあった。圧倒的にインプットしているし、そうやって考えるべき視点・考え方を取り入れ更新し続けているからこそ、彼らには今の凄みがある。
もちろん、他のタイプでドンドン道を歩み行く人もいるとは思うが・・・ただ、1つ言えるのは、「凄い人にあって自分にないもの」が見えたなら、自分の天井を打ち破れる可能性がある。今はその事に気づいてワクワクしている。自分は実践から学ぶ。なので、こんな面白そうな事実に気づいたからには、試してみたい。

「素人」になることの最大のメリットは、学ぶことに対してオープンになれることだと思っている。
今更これをやってみて、またLv.100まで持っていくにはどんな果てしない時間がかかるんだろう・・とか。既にこんな武器を持っているのに、こっちをやってみても、自分が提供できる価値ってのはそこじゃないよな・・とか。
「使い物になりそうなことをやる」「もっといえば、プロなのだから、自分の持ちうる価値を最大化する方が良いし求められている」なんて考え方が、新しい世界を阻害する。学ぶとは本来、かっこ悪さや恥を恐れない姿勢なのだ。
「凄い人になるには凄いインプットを食い尽くすことだ」と気付いたのだ、そのためには素人になる必要がある。謙虚に向き合う必要がある。

なんか、色んな意味でやり直しだな〜・・・と感じている。
「チームを良くする」みたいなのをやり切れず、逃げてきたはずだったんだけど、今ならそれもやってみたい気はするなぁ。

自分は常に無知であるというスタンス

散々言い尽くされて陳腐化している事かもしれないが、「自分は無知である」と自覚していることは謙虚な振る舞いに繋がるかも知れない。

まず普段の生活において、自分より上手い人・詳しい人に対しては「丁寧に接する」というのは違和感ないと思う*1
例えば部活など、先輩に対して横柄な態度を取らないようにするのは「目上だから」というのを差し置いても、自然と心から「教わりたい」と感じる部分もあるのではないか。

もし自身がプロフェッショナルとして扱っている分野でも、往々にして「無知である」ことは重要だと考える。無知の知というのに繋がるかも知れない。

例えば、利用している言語やフレームワークについて、知れば知るほど「主語がデカい」ような批判はしなくなる。
1つのWeb FWだけを使っただけで「MVCはファットモデルになりがち、だからイケてない」というのは、もしソレが客観性を持って真実にかすってはいれど、「芯を食っている」という事にはならないかも知れない。
「○○がダメだ」と言った場合は「自分が○○について理解していて、使いこなしている」という事に胸を張れるか?そう思うと、必ず不安はつきまとうのではないか。その結果、「こういう使い方をしたいので、こういう書き方をしているが、そうするとああいうアンチパターンを誘発する」など、情報の解像度を高めるようになりそう。
多くの場合、欲しているのは個々人の要求(これは自身の中にしか無い)とその実現方法である。「Aという機能を使うこと」自体ではないだろう。なので、もし「無知である」ことを自覚していれば、「描いているユースケースに対して、そもそもAを使うのが適切なのか?」というところを疑ってみるところから始まる。結果的に、「Aを悪者にする」ようなコミュニケーションを行うことがなくなる。

謙虚さとは「自らより他者から学ぶことを是としている」という姿勢だと思う。
そのためには「他者と極力正確なコミュニケーションを取るようにする」という必要性が生まれる。客観的な、独りよがりではない発話だ。相手の存在を意識した客観 = フェアであるということ。

どれだけ「フェアになれるか」は重要な能力だと思うので、私はどんな時でも「無知である」ということを始発点としていたい。

*1:接する相手に態度を変えるな!!という話は別としてね

「エリック・エヴァンスのドメイン駆動設計」と「ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本」を読んだ

読み終えたんす

元々、Clean Architectureを読んだ後に読むぞ〜〜!と思っていた本として、エリック・エヴァンスのドメイン駆動設計を想定しており。
ってことでReal World HTTPの後に(発売日を迎えてホヤホヤのモダン・ソフトウェアエンジニアリングを間にはさみつつ)、週末を中心に読み進めてたら5/23-6/16・・・と1ヵ月弱、なかなか苦戦しながら読み終えた。*1

また、「まずこの本を読んで、多分難しくて理解度が低いだろうから、間を置かずに次はコレを読もう」と決めていたのが 「ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本」。

ひるがえってコチラは、昨日読み始めてサクサクと進み。今日には終わったので、とても読みやすかった印象。
「こんなに日本語の本を読むのが遅くて大丈夫なのか自分。。」と凹みかけていたので、リハビリではないけど、読める本はちゃんと読めるんだな良かった!とも思った。

ということで、一段落したので #phpgenba のエピソードを復習しながら読書メモをまとめてみる。*2 php-genba.shin1x1.com

読んで見る順番としては個人的にはこれで良かった

最初にDDD本を読んだよ

最近は「まず原典にあたる」のが正しいスタンスかな〜という風に感じており、それもあって"まずは1番難しそうな"本から取り掛かった。
ということで、「エリック・エヴァンスのドメイン駆動設計」だ(長いので、以下「DDD本」)。

恐らく、「原典」が最初にあり(もしくはターニングポイントとなるくらいの爆発力をもたらしており)、その後に出た「解説書」「攻略本」というのは、その著者の大いなる編集力によって情報が微分&クローズアップしているものでは?と思っている。

当然ながら、その様な後発本が出るのは「オリジナルが難解だから」という何よりの証左だとは思うし、初手でそこに当たるのは高コストだなという風に感じる。

なので、目的としては「理解して血肉とする」や「高解像度なインプットを得る」という風に設定せずに、「地図を広げる」というところを意識している。具体的な道筋やどこにどんな建物が立っているか?までを正しく理解できる事は望まず、「なにをどこまで取り扱っているか、どのくらい風呂敷が広がっているか」の感覚を得られればOK〜というもの。
重要な概念はその登場頻度によって「感じる」ことができるし、朧げでも話の流れを追ったり逆に1発で理解できる箇所もあるかも知れない。そうやって、頭の中に薄いINDEXを作るようなイメージ。
(ちなみに、これによって出来ることの1つとして「索引を眺めるだけでも目に入る単語が増える」し「気になったページを読みに帰ることが出来る」というものがある。何となく、1回とりあえずクリアしたRPGのような感覚がある。行きたい町に好き勝手に戻れたり、取り逃したアイテムを回収しにダンジョンに戻ったりね)

これが、自分が「まず1回は原典を読んでみよう」というモチベーションを持っている理由だ。

実際に、今まで何となく耳にしたような言葉たちは「単語の定義としては」レベルで言えば説明を得ることが出来た。
ドメインモデル、ユビキタス、境界づけられたコンテキスト、値オブジェクトやエンティティ、知識の蒸留・・・これらに「耳馴染み」が出来た。

読み切るのに相応の時間を費やしたことになる。
が、ここ最近は「インプットに掛ける時間・量を大事にしていこう」と決めているので、多少コストが高かろうと意味の有りそうな順番を求めて読む本を決めていこう・・というのが自分の中では重要。

次にDDD入門を読んだよ

(実はかなり最初に買ってたんですよ)

その一方で、追っかけて読んだ「ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本」(長いので、以下「DDD入門」)については、やはり「物足りなさ」を感じるかなというのは正直な所。

が、決して「だから良い本ではなかった」というものではなく、寧ろ目的を履き違えなければ「見事な本だった!!」という感想。

何が「物足りなかった」かといえば、「ちゃんと削ぎ落としてる」という部分だ。
DDD本の難しさの1つはその抽象さにあるように感じており、それは「組織の形とコミュニケーション、コミュニケーションと実装、アジャイル開発やイテレーション」というとても広大な範囲を扱っている事に良く現れているように思う。・・これをワンストップで解決しようという「DDD」のコンセプトはやっぱマジやべぇな、となるのだが。

一方で、DDD入門はこの「難しさ」に立ち向かった。自分の感覚では、極めて「コードに近い位置」に軸足を置きながら話してくれているのがこの本の「優しさ*3」だ。
DDD本は「どうモデリングしていくか」という点に常に脳みそのリソースを30%以上喰われている感覚があったが、DDD入門は基本的に「どういうコードになるのか」に終始しているのではないか。

本書中で「ボトムアップドメイン駆動設計」という概念に触れており、まさに「"具体"や"卑近"から、着実に一歩ずつ積み上げていく」という読書体験に近い。

本書のアプローチもまたボトムアップです。ドメイン駆動設計の構成する要素のうち、もっとも根底にあるものからひとつひとつ解説してきました。そして、その解説自体も、トップダウンにそれが何であるかを紹介するのではなく、必ずそこにある問題を提示し、紐解く作業を添えています。本書はドメイン駆動設計のパターンを伝えると同時に、その実践の手本として、新たな知識との向き合い方を伝えているのです。ある知識を得るために、前提となる知識が必要となることは多くあります。なるほど知識は連鎖するものです。ボトムアップに知識を積み上げていけば、必ずや理解へ到達することでしょう。

成瀬 允宣. ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 (Japanese Edition) (Kindle の位置No.5427-5432). Kindle 版.

あるいは、「はじめに」から引用すると「モデリングはいったんさておき」というスタンスだ。

そこで本書はモデリングについてはいったん棚上げにして、具体的なコードをベースにパターンを集中的に解説し、全体を通して最終的なコードを提示します。どこかへ行こうとするとき、目的地がわからないということはとても不安を覚えます。本書が提示するコードは明確な形をもった目的地としてあなたの道しるべになるものです。

成瀬 允宣. ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 (Japanese Edition) (Kindle の位置No.49-52). Kindle 版.

DDD入門はどんな本でした?

まずは「読みやすい」本だなぁ〜(ありがたい〜〜〜!!!!)という感想。
他方で、全く未学習の状態からこの一冊で「DDDは何かという肌感を掴めるか」というと少し不足があるかも知れない。

「なぜDDDをするのか」という部分、第1章で取り扱っている内容が「軽い」かも?と思ってしまった。・・・これはDDD本を先に読んだから、かも知れないけれど。
そういう意味では性急に「本題」に入ってしまっているのか?とも。それによって「抽象的でわけが分かりにくい話」を掻っ捌けているので、一冊の本としてのバランスは良いなぁ〜と感じているのだけど。
その辺りは、何か別の文献(web上に「DDD入門」みたいなものがあるかも知れない。探してみると。)で補ってからこの本に入る、という準備が出来るといいのかな〜

視点を変えて、「どういう人が読むといいか」「読むことでどういうことが期待できるか」という点。

前者については、自分のように「DDD本をとりあえず読んでは見たものの」もしくは「読もうとしたけど挫折した人」などはまさに。その他には、「DDDというものに向き合う必要が出てきている、が、いまいち理解できていない・・・」という人など。 難しい単語たちを優しく説明してくれてるのは間違いないので。

後者の方に関して言えば、「とりあえずDDDで書かれたコードを読めるようになる」というゴールが近いように思う。「自身が先導してDDDを導入したり土台のデザインをする訳ではないが、チームとしてDDDを採用しているメンバー」などはドンピシャなのではないだろうか。明日から働きやすくなるんじゃない・・・?って気がする。

例えば目次を見てみると、この本が「いかに具体的・現場的な問題を取り扱っているか」という意志が匂ってくるのではないか。
特に端的に顕れている(と感じる)前半部分の章立てを引用する。

  1. ドメイン駆動設計とは
  2. システム固有の値を表現する「値オブジェクト」
  3. ライフサイクルのあるオブジェクト「エンティティ」
  4. 不自然さを解決する「ドメインサービス」
  5. データにまつわる処理を分離する「リポジトリ
  6. ユースケースを実現する「アプリケーションサービス」
  7. 柔軟性をもたらす依存関係のコントロール

すごくないですか、「モデリング」や「コミュニケーション」から焦点を外したDDDの解説は、こんなにも足早に実装的な話に入れる・・・・DDD本だと「値オブジェクト」「エンティティ」を主題として取り扱うのは、第2部:第5章「ソフトウェアで表現されたモデル」まで時間を要しているというのに!

このアプローチの違いから、「自分自身が率先してDDDをやっていくという立場」には不足でも「DDDを採用している現場のいちメンバー」に薦めるには充分に有用性があるな〜と感じる次第。ゼロからデザインをするのは厳しかったとしても、他の人のコードを読みとったりソコに乗っかってコードを書いたりはできそう、という印象。

良い塩梅だったなぁ〜〜〜と思った。

読了後に読んだ筆者の「あとがき」を見ると「どういう本か」は伝わってくる気がする。

nrslib.com

あとはなんだろう、コードがC#だけどソコは自分的には全く問題なかった。
変に擬似コードを使うよりは(実世界のコードだし)洗練されているから良いし、本書に出てくるサンプル程度であれば言語の癖みたいなのも感じることはなく「オブジェクト指向だと大体こういう雰囲気じゃんね」というノリで読めたという感じ。

DDD本は難しかったネ^^

読むのに骨が折れた!読みにくくない??そうでもないのかな・・

やはりDDDに関しての肌感みたいなのを持っていない状態で挑戦するには強敵だな、と。
とはいえ、これで世の中にあるドメインが〜とかユビキタス言語って〜みたいな議論に付いていける土壌を耕せたと思えば、非常に価値があるコストだったと感じている。スタート地点に立てたはず・・・

もちろん、全くわからない!!何もわからない!!と終始叫びながら900ページ弱を読んだわけではないので、新しい知識もそれなりに入ってきたつもり。

  • 今まで「ドメインモデルを隔離するって一体なに??」という状態だったのが、言わんとしている事が分かった気がする
    • Clean Architecture(もとい、フレームワークやインフラ層を「些細なこと」として扱うような態度)での「本当に守りたいものは何か」を記述していくとこうなるのか、という感じ
    • これらについては、徹底的な(実装パターンとしての)DDDを採用しなかったとしても、着眼点として持っておくことは出来そうに感じた
      • 例えば仕様の隔離や誰がどんな責務を持つか、制御の流れをどうするか?など
      • DDDというかOOPで達成されるべきことについて、自分の中での練度が上がったかも知れない(勘違いの可能性もある^^)
  • 先行して概念だけ(何となく)知っていた「ユビキタス言語」、それ自体とても便利そうなもの〜という認識だったが、「ここまで徹底的にやるのか」といった感じで、確かにそうすると抜群に効果が出そうだな・・・という気がした
    • 例えば何かのIssueやPRのdescriptionを埋める時、もしくはインラインコメントを書いたりレビューをしたりする際の思考態度が変わる
  • アナリシスパターン is 何・・・
    • これはまた何か本を読んで知識を蓄えた方が良いのだろうか
    • もしくは、これに限らず「どう分析してモデリングしていくか」みたいな技法は知りたいと感じる。アナリスト的な機能なのかな、と思うが。
      • それらを無くして「どういう風にしたら良い設計たり得るか」については語れないのでは、、、、、という気がした
  • しなやかな設計 はメチャクチャ良い概念、好きぃって思った

↓ 好きだなぁと思った箇所。リファクタについて

  1. 困った時のリファクタリングをする際に、原因がコアドメインかコアと補助的要素との関係を含むものかどうかを調べる。そうであれば、歯を食いしばって、まずそれを修正すること。
  2. 自由にリファクタリングする余裕がある場合、最初に集中すべきなのは、コアドメインのより適切な括り出し、コアの隔離の改善、補助的なサブドメインから不純物を取り除くことによる汎用サブドメイン化である。

Eric Evans. エリック・エヴァンスのドメイン駆動設計 (Japanese Edition) (Kindle の位置No.8807-8810). Kindle 版.

(DDDに限らず)往々にして、「リファクタをすべきか、そのままでいいか」「どうしたら成功するか」みたいなのは判断が難しい所。
カッとなってやった!!!という時にコードを書く瞬発力は上がると思っているが、気分駆動でやった問題は精度の面でブレが怖い。「時間取ってリファクタしてみたけど結局なにも良くなってないじゃん」というのは良くあるし、「よく出来ると思ったけど挫折した」も同等かソレ以上にあること。
なので「何故やるべきか」の尺度はあるに越したこと無いよね〜!と感じる。

アーキテクチャは方針」であるのだから、設計思想やパターンに密接に関わっているDDDの目指すものが、自ずと「リファクタリングかくあるべき」と語り始めるのはとても自然なことだなぁと感じる。

この後どうする?

まだまだ「薄く広く、全体的なINDEXを作ってみた状態」だと思っている。なので、この後には「脳みそのシナプスをつなげる」「より具体-抽象を結びつけながら、自身の持つ解像度を上げていく」ことが必要だという感じ。
とはいえ、概念的な部分についてはDDD本が一通り抑えてくれているだろうな・・という信頼はあるので、あとは「馴染んでいく」という部分だ。

DDD本が難しかったのは「もう少し具体例・実践例を知りたい」という所があり、あと「会計がさも分かりやすそうな例として取り上げられてるけどあんまり馴染みがなくて・・」「流通もゴメンナサイ・・・」という気がしたので、より実践的な話に触れてみたいと感じている。

ということで、これを読んで見る。

実践ドメイン駆動設計

実践ドメイン駆動設計

高いなぁ買うの日和ってたんだけど。2冊読み終わった勢いでポチったので・・・・・

なんとなく「1度読んだ本」はその後も行き来してパラパラと開きやすい気がするので、実践DDDを読みながらリファレンスとしてエリック・エヴァンス先生にもお話を伺いに行こうかな。

あとは、少し自分でも手を動かしてみたいよな〜。MVC&ActiveRecordなFWとも組み合わせられるかな?
CakePHP4を用いてDDDの実践、みたいなのをやってみたい気はする。

例えばshin1x1さんのサンプルを見た時、とても「cake的じゃない」と感じた記憶があるのだが、今見たらもう少し深く理解できそうかも知れない。
(とはいえ、今のところはやっぱり「折角cakeでやる旨味」みたいなものが薄そうかな〜という印象は持っている。コレが喰わず嫌いでしかないのか?は確かめてみたい。)

github.com

あとでよむ

少し復習してみましょう、くらいのノリで読みたい nrslib.com

*1:別のこの間の週末を全てこの一冊に費やしていたわけではなく、並行して読み進めている本があったり、趣味コードを書いたり諸々もあったんですよ!!という言い訳

*2:当日は会場で聞いていたが、壁の裏から漏れ聞こえてくるうずらさんの存在感が凄かったのを思い出す度に笑ってしまう

*3:「易」ではなくて