良い設計の標準化やプログラミング能力の底上げに対する気持ちを残しておく
#2022年振り返り #設計 #設計原則 #プログラミング #標準化
from : WIP: 2022年振り返り
エンジニアリングの本質は問題定義能力
→問題解決の引き出しは多いに越したことはない
治療的哲学
自分より高次元のことは理解できない
理解、分解、再構築
オーナーシップを発揮するには対象を把握し、知識を得ることから始まる
こういう考えからPofEAAやazure、アーキテクチャ、デザインパターン、パタン・ランゲージをひたすらインプットしてた
後にパターンと呼ばれることになる解決策を考えだした開発者の考え方、価値観を学ぶ
GUIのデータアーキテクチャと状態管理の変遷
これ進研ゼミでみたことあるやつだ!みたいなのがよくあって意思決定のトレードオフを提唱するのに役にはたった
思考家の価値は、「視点」と「選択肢」を提示すること
専門家の価値はドメインとレンジをつなぐ関数のパターン化と選択肢の具象化
この積み重ねによって得られたもの
技術の螺旋がわかるようになってきた
この話題ループしてるなとか、自転車置場の議論だなとか
感情フィルターが育ったとも言える
技術投資の損益分岐点みたいなラインが肌感でわかるようになってきた
ソフトウェア設計の損益分岐点の共通項を見出す
大体の設計手法やパターンも意味や具体的なコード例が頭の中で浮かんでくる
良いプログラムの理解が進んだ
良いコードとは何か
設計, 設計原則, プログラミング, エンジニアリング
UNIXの哲学やA Philosophy of Software DesignのShallow Module, Deep Moduleあたりから示唆を得られた
いま持っている気持ちが冷めない内に書き残しておこうと思う
---
良いプログラムの現時点での結論
やはり関数設計が全てだなと思う
関数の命名、入出力の明示化、冪等性
次点で代数的データ型(ADT)
条件分岐ではなく、 パターンマッチングにする
すべてのコードは書いた瞬間負債になりうるというメンタルモデルが大事で、関数単位で捨てやすさを念頭に考える
データとロジックは近い位置にまとめる
いいデータ構造はいいアルゴリズムを生む
コンポーサブル
super simple codeを目指したい
最初が一項目だったとしても関心の成長軸を作っておき、変化の際に既存の構造を変更せずに"追加"で対処できる構成を目指す
その積み重ねがドメインを堅牢にする
全ては大なり小なりの判断の積み重ねによって行われている
良い判断を繰り返すことが、良い開発を進めることになる
それが良い判断かは後からじゃないとわからないし、ドッグフーディングし続けることでしかわからない
処理のまとまりの捉え方も人によって変わるし、結局属人化は避けられないだろうなーと思う。
オブジェクトの捉え方の違い
「読みやすく書け」というのは実践的なガイドにならない
Reactだったり普段お世話になってるOSSのコードリーディングをしてみても、コードにブレはある
でも根っこの部分で関心が分離されているのでお互いに影響はないように作られてたりする
副作用は最初と最後に寄せる
副作用とドメインを切り離す
日本のアーキテクチャは基本的に「誰でもコードを書けるような」に寄せがち
ドメインと問題空間と解決空間を構造化するスキルが大事
サブドメイン分割の勘所は、知識や経験に大きく左右される
無形資産そのもの
チームの生産性や保守性をあげたい、という目的や属人化の排除で実装を標準化(共通化)したいといった試みをよく見るが(自分も過去に何度か依頼された経験がある)が、その判断のトレードオフをよく理解していないと実運用に乗せるのは難しいんじゃないかなと思う
制度を作ると、結局そこから逸脱できなくなるのが嫌だ、ルールがなければ自分で考え、自分で意思決定できるでしょ
まず、一般的不協和音を乗り越える必要があって、パタン・ランゲージを介したコミュニケーションの難易度が高い
文化が違うと使う言葉も異なるので会話が噛み合わない
純粋性や不変性などのイデオロギーを「とりあえず完成させる」ことよりも重視すると、レビューで死ぬ
ここでの副作用ってなに、冪等性ってなにみたいな定義から議論する時間などない
コードレビューコメントが付きすぎてる理由
型付けをサボるようなことはしないが、その味付け具合をチームでちゃんと共有できるとはおもえない
原則を理解していないジュニアも腹落ちしないままメンタルモデルとコードが乖離していく
仕組み化する前にはまず、仕組み化できるものか、していいものかの分析も大事で、そのアプローチの仕方を間違えると効果が薄い
何なら、デメリットの方が高くつくこともある
構造化スキルは数年の経験の上に成り立つ高度な技術であり、属技能性が高い
属人性は低い方がよいが、属"技能"性はそうではない
自分の特性無視してアクセル踏んでもキャパが広がるわけじゃない
「知識の書かれたものが手元にある」ということと「知識を活用できること」は別
「パターンを知ること」と「コンテキストに適合する形を見つけだすこと」は全くの別物
道具を持ってることと理解して動かすことは似て非なるもの
情報を記憶して整理することと整頓して必要な時に引き出せるようにすることの関心は別物
ゴールが曖昧なまま突き進んでも本質的ではない
ソフトウェア開発における「生産性」とは
技術力というより知識の有無と試行錯誤してきた経験とエラーに対する粘り強さとオーナーシップ
共通化と抽象化
機能の共通化は諸刃の剣
柔軟性と複雑さのトレードオフ
明確で完璧な仕組みは柔軟性に欠け、創造性を測れない
保守容易性を上げることが必ずしも柔軟性をもたらさない
システムに柔軟性を持たせ過ぎてしまうと複雑さが増大して破綻してしまう
プログラムが生まれるまでそれなりの試行錯誤があったはずで、それは成果物には現れない
要件定義や仕様理解を通して開発者なりのメンタルモデルをベースを作って、トライアンドエラーを繰り返しながら理想系に向けて育つものだと思う
失敗も成功も共有しあいながら、同じ時間軸の中で最適な粒度を見つける
フロントはモーダルUI、モードレスUI、インラクションの性質などのデザインの側面で暗黙的に設計手法は決まってくる
前提条件や過程を無視したレイヤードアーキテクチャやDDDを導入して失敗してきた事例もいくつか見てきた
SPAでのレイヤードアーキテクチャの考察と不確実性へのマインドセット
ハードシングスを引き起こしたHype Driven Development(HDD)
コードに内在する性質だけに着目すると、外部環境に対する適応度の考慮が不足してしまう
構造や仕組みで解決などは固有のルールを閉じ込めているだけで根本解決ではない
要件がデカいとどうリファクタリングしても別に実装が小さくなるわけではない
その裏のルールを知る必要はあるし、一般的に学習ハードルはもっと高くなり、むしろ生産性が高いとは逆方向に向かう
生産性が高い = 重要なことだけにフォーカスしている
例えば、通知はドメインサービスなのか、アプリケーションサービスなのかは視点次第
モデリングのコツは、「視点」を創造すること
全てのモノゴトはその時点での観測者の環境や立場に相対的である
視点に”正しい”の定義もないし、逆説的に”間違い”もない
その抽象化は正しいか
複雑なシステムでは、すべての要素が正しくても障害が起きる
ドメインかアプリケーションか分類することが無駄というわけではない
手段に囚われすぎて設計に必要なメンタルモデルを育てるという超大事な過程を忘れると本末転倒となるということ
つまり、コンテクストと形を適合させることが全て
これは要件を細かく定義して渡す、というよりかは、ざっくり雰囲気でなげて、対話の中でアウトプットを洗練させることでしか育たない
だから、設計は生成的にならざるを得ない
一般的にいい設計、いいプログラミングをするためにはより抽象度の高い前工程に入っていって、問題定義の段階で整理整頓しておく必要がある
というのが、最初のエンジニアリングの本質は問題定義能力に繋がる
後工程は悪いものを受け取らない責務があるということを忘れてならない
カバレッジや標準化が目的になりすぎると、キャンベル(グッドハート)の法則が発動する
もっと手段の先にあるbeing(状態)に重きをおくべきだろう