2 ポイント 投稿者 GN⁺ 2023-10-31 | 1件のコメント | WhatsAppで共有
  • 長年の開発経験から繰り返し得られる最大の教訓は、複雑性がコードベースの「永遠の敵」であり、小さな変更が思わぬ場所を壊す状態を生み出すという点である
  • 複雑性を減らす最も強力な道具は、機能や抽象化に「no」と言うことだが、現実的な妥協が必要なときは 80/20 解法で、少ないコードで価値の大半を届ける
  • 設計とテストは、早すぎる抽象化よりも、システムの形が見えてきた後で 良い境界点 を見つけることに重きを置き、単体テストより長く保てる 統合テスト を重視する
  • ツール、型システム、ロギング、デバッガ、API 設計は開発者の認知負荷を減らすべきであり、型システムの大きな実用価値は IDE の自動補完 にある
  • DRY、関心の分離、マイクロサービス、SPA、ジェネリクス、過剰なリファクタリングのように、名前は立派でもコードの理解や保守を難しくする手法は、複雑性への入り口になりうる

複雑性はコードベースにおける最上位のリスク

  • 複雑性 は、最初は理解できていたシステムを突然扱いにくくし、ある場所の変更が無関係に見える別の場所を壊す
  • 複雑性は善意の開発者やプロジェクトマネージャーを通じて入り込むことがあり、ときには自分が持ち込んだ複雑性こそが問題の原因になる
  • 複雑性を解決する万能の「棍棒」はなく、最良の対処は最初から持ち込まないことである

「no」と「ok」: 拒否と現実的な妥協

  • 複雑性を防ぐ最良の武器は「no」である
    • 「その機能は作らない」
    • 「その抽象化は作らない」
  • ただし「no」は良いエンジニアリング上の助言ではあっても、より多い報酬や昇進には不利に働くことがある
  • 現実的に妥協しなければならないときは「ok」と答えたうえで 80/20 solution を探す
    • 欲しい価値の 80% をコードの 20% で実現するやり方
    • すべての飾り機能は持てず、少し見た目が悪いかもしれないが、価値の大半を届けつつ複雑性を低く保てる
  • プロジェクトマネージャーが細かな要求を忘れたり、異動したり、退職したりすることもあるため、ときには 80/20 方式のほうがよい選択になる

設計とコード分解は早すぎると危険

  • プロジェクト初期にはシステムの形はまだ「水」のように曖昧なので、早すぎる分解 を避ける
  • 時間がたつと良い境界点が見えてくる
    • システムの残りとのインターフェースが狭い
    • 少数の関数や抽象化で内部の複雑性を隠せる
  • 抽象化を早く作りすぎると誤った抽象化になりやすいため、待つほうにより重きを置く
  • 初期に大きな抽象化を作りたがる開発者には、UML のような捨てられる成果物を与えたり、明日動くデモを求めたりするやり方が役立つ
  • 初期の プロトタイプ は、実際に動くコードと現実的な制約をより早く見せてくれる

テストは「後でまとめて」ではなく「形が定まりながら一緒に」

  • テストは多くの問題を防いでくれるが、ドメインを理解する前から test first を強制するやり方には反対する
  • プロトタイプの後、コードが固まり始める段階で大半のテストを書くほうを好む
  • 「自分のマシンでは動く」と言ってテストを飛ばす態度は非常に悪い
  • テスト種別ごとの好みははっきりしている
    • unit tests: プロジェクト初期には有用だが、実装変更で壊れやすく、リファクタリングを難しくすることがある
    • end to end: システム全体の動作は見せてくれるが、壊れたときに原因を理解しにくく、頻繁に壊れると無視されやすい
    • integration tests: システムの正しさを見るには十分高く、デバッガで原因を探るには十分低く、最もよい地点に近い
  • 境界点 API が安定したら、その周辺に 統合テスト へ重点的に投資する
  • end-to-end テストは、最も一般的な UI 機能と重要ないくつかの edge case に集中し、小さくよく管理された集合として保つ
  • mocking は本当に必要なときだけ、できれば大きな境界単位でのみ使う
  • バグが見つかった場合は、例外的に先に 回帰テスト で再現してから修正するやり方を好む

Agile、リファクタリング、Chesterton's Fence

  • Agile 自体は最悪ではなく、開発組織の一方式として使えるが、失敗の免責道具のように使う「agile shaman」には警戒すべきである
  • プロトタイプ、良いツール、良い開発者の採用のほうがソフトウェア成功には重要であり、どんなプロセスもすべての問題を解決する silver bullet ではない
  • リファクタリングは、とくにプロジェクト後半でコードが固まってきたときに有用だが、大きなリファクタリングほど失敗の可能性が高い
    • 小さく分けて進める
    • システムが可能な限り動き続ける状態を保つ
    • 各段階が終わってから次の段階へ進む
  • 過剰な抽象化は、リファクタリングの失敗やシステムの失敗につながりうる
    • J2EE は多くのプロジェクトに害を与えた事例である
    • OSGi は複雑性を閉じ込めようとして逆に強めてしまい、何人年ものやり直しが必要になった
  • Chesterton's Fence は、見た目がひどいコードでも、なぜ存在するのか理解する前に削除してはいけないという姿勢につながる
  • 動いているコードは完璧でなくても尊重すべきであり、大きなシステムほどまず理解する時間が必要である

マイクロサービスとツール

  • マイクロサービスは、システムを適切に分けるという難しい問題に ネットワーク呼び出し まで追加する
  • ツールは開発者の生産性と理解力を大きく高める
    • 新しい環境ではツールを学ぶことに時間を使ったほうがよい
    • 2 週間ツールを習得すれば開発速度が 2 倍になることもある
    • ドキュメントがなければ他の開発者に聞いて掘り下げる必要がある
  • IDE の コード補完 は API をすべて記憶しなくてよくしてくれ、Java 開発ではほぼ必須に近い
  • 良いデバッガは非常に重要である
    • 条件付きブレークポイント
    • 式の評価
    • スタック探索
  • 新しい開発者は使えるデバッガを深く学ぶべきであり、それは大学の授業よりもコンピュータについて多くを教えてくれることがある

型システム、式、DRY

  • 型システムの最大の価値は、ドットを打ったときに使える操作の一覧が出る ツール支援 にある
  • 型の正確さも良いが、コード補完と探索のほうがより大きな実用価値を持つ
  • 型システムを過度に抽象的に使う開発者には警戒すべきである
    • ジェネリクスはとくに危険になりうる
    • たいていの場合、コンテナクラス程度に制限するほうを好む
  • 短い条件式を 1 行に詰め込むより、中間変数に意味のある名前を付けて分けるほうが、デバッグにも理解にもよい
  • DRY は良い助言だが、バランスが必要である
    • 単純で明快な重複コードのほうが、複雑なコールバック、クロージャ、オブジェクトモデルより良いことがある
    • 重複排除そのものが複雑性を増やすなら損になりうる

関心の分離、クロージャ、ロギング

  • Separation of Concern は強力な考え方だが、実際には複数のファイルを行き来しながら動作を理解しなければならず、時間の浪費につながることがある
  • 代わりに locality of behavior を好む
    • 「動くもの」の近くにコードを置けば、その対象を見るとき何をしているかがすぐ分かる
  • クロージャはコレクション操作を抽象化するのには向いているが、塩のように少量で十分である
  • JavaScript の「callback hell」は、クロージャを使いすぎた複雑性の例である
  • ロギングは、とくにクラウド配備環境で非常に重要である
    • 主要なロジック分岐ごとにログを残す
    • 複数マシンをまたぐリクエストには request ID を含め、ログをひとまとめにできるようにする
    • 可能ならログレベルを動的に調整する
    • 可能ならユーザーごとにログレベルを調整し、特定ユーザーの問題をデバッグする
  • ロギングライブラリは複雑になりうるが、ロギング基盤をきちんと作る投資は後で大きな見返りをもたらす

並行性、最適化、API

  • 並行性は恐れるに足る領域であり、可能な限り単純なモデルを好む
    • ステートレスな Web リクエストハンドラ
    • 相互依存しないリモート作業キュー
    • 単純な API
  • Web では optimistic concurrency がうまく合うことがある
  • Java の ConcurrentHashMap のような並行データ構造も慎重に使うべきである
  • 最適化は、実際の性能プロファイルで具体的な問題が確認されてから始めるべきである
    • CPU だけを見てはいけない
    • ネットワークアクセスは多くの CPU サイクルに相当するため、可能な限り減らすべきである
    • 入れ子ループを見てすぐ O(n^2) の除去に走ると、複雑性が増すことがある
  • 良い API は、開発者があまり考えなくて済むようにすべきである
    • API の作成者が実装視点やドメイン視点に閉じこもると使いにくくなる
    • 単純なケースには単純な API を、複雑なケースにはより複雑な API を別に提供する 階層化 がよい
    • オブジェクト指向であれば、振る舞いは可能な限りその対象の上にあるべきである
  • Java の stream/collector の例は、ありふれた作業を不必要に回り道させる API として批判される

パース、Visitor Pattern、フロントエンド

  • パーサは recursive descent 方式が面白く美しいと考える
  • parser generator は、生成コードの理解やデバッグが難しく、文法の再帰的性質を隠してしまう
  • 実際の本番用パーサの大半は recursive descent であり、Bob Nystrom の Crafting Interpreters を勧める
  • Visitor pattern は短く「bad」とまとめられる
  • フロントエンドとバックエンドを分離し、SPA ライブラリと GraphQL JSON API を HTTP でつなぐやり方は、複雑性の巣を二つ作るのに近い
  • 単純な Web サイトやフォームをデータベースに入れる作業にまで大きなフロントエンドライブラリを使う流れには警戒すべきである
  • 複雑性を下げるために htmxhyperscript を作った
    • 単純な HTML を保つ
    • 多くの JavaScript を避ける
  • React は仕事の面や一部のアプリケーション類型にはより適しているが、フロントエンドの複雑性への道に入る選択だと見なしている

流行、FOLD、impostor syndrome

  • 開発には流行が多く、とくにフロントエンドでより目立つ
  • 革命的だという新しいアプローチには疑いを持つべきである
    • コンピュータ分野では、すでに多くのアイデアが一度は試されている
    • 悪いアイデアが新しい名前で戻ってくることがある
  • senior 開発者が公の場で「これは複雑すぎて理解しにくい」と言うのはよいことである
  • FOLD は Fear Of Looking Dumb の略で、ばかに見られるのを恐れて複雑さを認められない状態である
    • senior が複雑だと言えば、junior も理解できていないことを認めやすくなる
    • FOLD は、とくに若い開発者にとって、複雑性が力を得る主な源泉である
  • 開発者は、すべてを支配している感覚と何も分かっていない感覚のあいだを行き来し、impostor syndrome は一般的である
  • みなが impostor のように感じているなら、誰も impostor ではなく、若い開発者は挫折や不安があってもキャリアを続けられる

推薦する読み物と結論

1件のコメント

 
GN⁺ 2023-10-31
Hacker Newsの意見
  • 賢い人たちが蛾のように複雑性に引き寄せられるのは不思議だ
    過剰設計したい衝動と戦う方法を学ぶのに何年もかかる
    一度見えるようになると無視するのが難しくなり、今ではコードが過剰設計されているかどうかすぐに分かる
    残念ながらコードの99%ほどは過剰設計されているように見え、開発者が自分の代替不可能性と請求時間を最大化しようとするインセンティブが強く働いている
    完全に機械的で自我がなさそうに見える開発者でも、過剰設計をしばしばやらかす。これは無意識に働くものだ
    多くの開発者は、自分が書くコードの一行一行を意識的に考えているわけではなく、目標を決めたら、その目標に少し近づく最初のコードを吐き出すだけなので、各段階でもっと良い代替案があったことに気づかない

    • 開発者の代替不可能性や請求時間を増やそうとするインセンティブが過剰設計の原因であるケースは、私の経験上ほとんどなかった
    • この問題とはずっと格闘している
      まず、面白いパズルが好きだ。特に商用コードは、きちんと作るとかなり退屈なことが多いので、無意識のうちに実装が面白い機能を押し進めてしまう。ここで面白いというのは、結局すべてを過度に複雑にする機能という意味だ
      次に、何かをプログラミングしている最中は、自分の下すあらゆる選択が当然で必要なものに見える。あとでコードから離れ、新鮮な目で改めて理解しようとして初めて、自分がどれほどひどいものにしたかが見えてくる
      たいていの問題で最も目につく解法はかなり複雑なことが多く、単純な解法をどこで探すべきかは知恵・技術・ドメイン知識がなければ分からない。単純でクリーンな解法は、ほとんどの場合明白ではない
      「私たちは半分自作のメッセージキューを少しずつ実装している。標準のメッセージキューを使おう」、「バグだらけのカスタムバイナリフレーミングプロトコルを作っている。protobuf/msgpackを使おう」、「データを取ってくるためにカスタムRPCプロトコルを作るのではなく、HTTP上のRESTを使おう。そうすれば間にnginxを入れてバックエンドのレスポンスをキャッシュでき、カスタムキャッシュも捨てられる」
    • ある作家の手紙にあった「短く書く時間がなかったので長い手紙になった」というような一文を思い出す
      結局、時間があり、そうするよう報われるなら、完璧で単純で重複のないコードを書ける。しかし大半の場合は、何かをリリースし、それをリリースするために費やした作業量・知性・設計能力で技術力を示すことのほうが報われる
      自然な結論として、あらゆるものが肥大化し、過剰設計された応急処置の塊になり、3〜7年ごとに書き直される構造になる
      データを見たわけではないが、「書き直し半減期」は離職率や平均勤続年数と相関がありそうだ。人々が過剰設計しないようにもっと努力しても、どうせ書き直される可能性は高い
      完璧主義者としては本当に気に障るが、最高に単純な解法をもっと長く考えるより、複雑で過剰設計されたものを作るほうがより報われる場合がある。もっと良い組織もあるのだろうが、9年間ソフトウェアエンジニアとして働いてきて、まだ見つけられていない
      オープンソースプロジェクトは最も良い反例として思い浮かぶが、良いライブラリでもメンテナが変わると書き直されたり、新しいバージョンが出たりする。オープンソースと、HNにいる多くのフルタイムのソフトウェアエンジニアが目にする企業向けの寄せ集めとの間では、金銭的インセンティブが大きく異なる。よく練られた学術論文と、雑に書いた業務メールを比べるようなものだ
    • 私の場合、過剰設計はたいてい逆のところから来る。コードを書くときに考えすぎ、コードベースがどうあるべきかについて先入観を持つことから生じる
      Handmade HeroのCaseyは、自分のプログラミングスタイルを「圧縮ベース」と呼んでいたと記憶している。まずコードを書き、一緒に属するものを段階的に切り分けていくやり方だ
      繰り返しが出たときに抽象化するのであって、意識的に設計して抽象化するのではない。だんだんこのやり方を多く使うようになっている
    • 「コードの99%が過剰設計されているように見える」という結論が99%のような答えを出すなら、これまで学んだことが妥当だとしても、自分が作った思考モデルに問題があるかもしれないとは考えないのか?
      それ自体が必ず間違っているという意味ではないが、他人の仕事の品質を評価することなら、強いバイアスが入っている可能性は高そうだ
  • このサイトが本当に好きで、いつも笑ってしまう。特にいちばん好きな部分はマイクロサービス
    「grugは、大きな脳が最も難しい問題であるシステムを正しく分割する仕事を持ち出し、そこにネットワーク呼び出しまで入れる理由を不思議に思う。grugにはとても混乱して見える」

    • このサイトが好きでよく読んでいる。私の知り合いたちは、grug brainというソフトウェア開発宣言にはもううんざりしていると思う
      「複雑性は非常に、非常に悪い」
      「複雑性とティラノサウルスとの1対1の対決のどちらかを選べと言われたら、grugはティラノサウルスを選ぶ。少なくともgrugにはティラノサウルスが見える」
  • 型に関する部分には不満がある
    grug は、型システムの価値の90%以上はキーボードでドットを押したときに使える候補一覧が魔法のように出てくることにある、と言っているが、うちの会社のジュニアは本番環境で null アクセスが原因で壊れるコードを頻繁にデプロイし、Sentry がそれを教えてくれる
    集中開発期間中は、ジュニア開発者1人あたり1日に検出される null アクセスバグ が1件くらい出る
    静的検査のあるまともな型システムを使えば、IDE が「これ null かもしれないけど本当に大丈夫?」と知らせてくれるので、ものすごく助かるはず
    それに、静的型付けがなくても自動補完は可能
    「大きな脳の型システム呪術師たちは型の正確性こそが型システムの核心だと言うが、grug はそういう呪術師たちがコードを頻繁にはデプロイしないことを見ている。デプロイされていないコードはある意味では正しいのかもしれないが、grug の言う正しさではない」という部分は失礼で不要
    C、PHP、Python、Haskell、型付き Python で主にコードをデプロイしてきたが、型付き言語では本番まで到達するバグの発生率がずっと低い。それが型を好む理由の一つ
    また、リファクタリング がはるかに簡単になる。広く使われているものを変更するとき、コードベース全体で壊れた呼び出し箇所を数秒で信頼性高く確認でき、成長するコードベースを反復的に改善する大きな助けになる

    • その話は間違っているだろうか? 自身が語った経験を見ても、形式的証明を強制する型システムまでは受け入れていないように見える
      代わりに、一部の問題を捕まえ、何より 自動補完の魔法 を提供しつつ、完全な正確性の証明に必要なあらゆる細部に足を取られない、折衷的な型システムを受け入れているということだ
    • 単なる冗談だと思う。たぶん自分はからかわれる側に属する可能性が高いが、そこまで過敏に受け取る必要はないと思う
      彼は C や Java 程度の 静的型付け は問題ない、あるいは良いものと見ていて、Rust や Scala に見られるようなもっと派手なものは時間の無駄だと考えているようだ。私は彼が完全に間違っていると思うが、人生とはそういうものだ
    • 原文は型付き言語に賛成する文章ではないのか? 結局同じ立場のように見えて混乱する
    • ここで言う「呪術師」は、あなたのような人を指しているわけではないと思う
      「大きな脳の型システム呪術師」とは、必ずしもコードを書く人ではなく、たとえばそのテーマで講義を売り、人々を盛り上げる人のことだと理解した
      文章の前半でも Agile について語るときに「呪術師」という表現を使っているが、実際のソフトウェア開発というより講義販売に近いことをしている人はかなり多い
    • 以前「大きな脳の型システム呪術師」と一緒に働いたことがある。むしろこの記事は非常に親切で寛大な分析に近い
      型階層 に執着する人たちと働くのは耐えがたく、正当化はたいてい「もしも」と「しかしそれは sound ではない」の世界にとどまる
      型システムが引き起こす多くの品質低下は、型を十分たくさん入れればバグを完全に防げると信じる人たちから生じるが、それは事実ではない
  • これから数か月以内にみんなが HTMX 列車に乗り込み、多くの若い開発者の頭を揺さぶり、世界中でエネルギーを大きく節約し、多くの人を幸せにする気がする
    そして、この好奇心旺盛な若者たちが htmx.org のリンクをクリックし続けて hyperscript を見つけたら、Dusk till Dawn でヴァンパイアたちが飛び出してくる瞬間のようになるだろう

    • みんなが HTMX 列車に乗るというのは、JavaScript では 無限ループ
      JavaScript の複雑さにうんざりした誰かがシンプルな JavaScript ライブラリを作り、そのシンプルさに人が集まり、あらゆる Web 機能をサポートしなければならなくなってそのライブラリが複雑化し、またその複雑さにうんざりした誰かがシンプルな JavaScript ライブラリを作る
      素の JavaScript から始めて IE5/6 と数年戦い、jQuery がみんなを救い、AngularJS はいまいちだったので飛ばし、React ベータが出ると関数型プログラミングの理想のために気に入った。今ではトランスパイル、ホットリロード、Typescript、重い React ライブラリの山をかき分けている
      Intercooler と HTMX でもいくつかプロジェクトを作った。HTMX は全体として堅実だが、この町を初めて通る列車ではない
    • ああ、Carson Gross は grug brained developer と htmx の作者だったのか
      htmx への本当の批判を見てみたい
      個人的には、Web の大きな継続課題はページをうまく更新する方法を見つけることだったし、私たちはあらゆる試みを続けてきたのだと思う。だから疲労が生まれ、あるアイデアは過激になったり、時間とともに寄せ集めになったりする
      Htmx は grug 的に、より少なく、YAGNI を貫く 反動 のように見える
      未来は不確かだが、signals のような取り組みは今でも聖なる仕事のように見える。多くの方向から多くの試みが行われていて、私たちはこの戦線や他の戦線をまだ開拓している最中だ
      MobX や Svelte などもすでに長い道のりを歩んできた。旅はまだ終わっておらず、複雑性という怪物と絡み続けていることは、たとえ保守的あるいは grug 的な思考がそう見るとしても弱さのしるしというより、単にシンプルなだけのアプローチではなく シンプルで良いもの に到達するための当然の努力だと考えたい
    • その文を見て笑ったあと、実際に確認してみた
      _="on load wait 5s then transition opacity to 0 then remove me"
      ああ、だめだ
      _="on htmx:error(errorInfo) fetch /errors {method:'POST', body:{errorInfo:errorInfo} as JSON} "
      ああ、だめだ!
  • 開発者として30年働いてきたが、初期の頃は傲慢で、自分は他人より賢いと思っていたことを認める。当時の私はあらゆる 複雑性の悪魔 を好む「大きな脳」側だった
    10年後には「Grug brain」開発者に近づき、今では完璧ではないかもしれないと分かっていても、動作する最もシンプルな解決策に集中している。それでも問題ないのは、それが正しいものに近づかせ、反復的な改善を可能にしてくれるからだ
    開発者としてできる最高のことは コードを削除すること だ。今、私たちのところでは2年間維持してきた要件が突然もう要件ではなくなり、多くのコードを引き剥がせると思うと本当にわくわくしている。すべてがよりシンプルになるからだ

    • コードを消すとき、頭の後ろのほうに言葉にしがたい心地よい感覚がある
      まるで空間が解放されるのを体で感じているようだ
  • Grug は1週間前の Philosophy of Software Design の記事のコメントでも出ていて、そのときの議論はかなり良かったと思う。 https://news.ycombinator.com/item?id=38011938
    「grug について、自分もまったく同じ感覚だ。何が単純かについて人々が実際に合意しているとは思わないので、自分の『単純さ』が原始人でも同意する明白なものかのように振る舞うのは、見栄のように感じる」
    単純さは、見つけ出すのが最も複雑なものの一つであることが多い。自分の周囲のすべて、自分がやっていることだけを除いて、複雑だから単純さへと曲げ直すべきだと確信している人をたくさん見てきた。権威にしがみつく、危険なほど弱い態度のように感じる

    • 良い指摘だ。ただし核心は結局、悪い哲学が複雑性を助長することにあると思う
      grug brain の哲学は、絶対に避けられない場合を除き、どんな代償を払っても単純さを選ぶというものだ
      grug から見た大きな脳の哲学は、絶対に避けられない場合を除き、どんな代償を払っても再利用性を選ぶというものだ
      この哲学の問題は、第1世代の設計選択を固定化し、反復的な改善をより難しくする点にある
      単純さを見つけるのが難しいのはその通りだが、単純さを見つける鍵は反復的な改善
    • Grug の記事で特に良い点は、ニュアンスと謙虚さに満ちていることだ。見栄ではない
    • 自分としては、コード行数を測ればいいと思う
      局所最小値は作っているものの複雑さに応じて動くので、かなり賢い複数の見解が同時に正しい余地がある
      完璧な指標ではないが方向性は正しく、ログスケールでは非常によく機能する
  • チェスタトンの柵の概念は数え切れないほど使い、説明してきたが、その名前を知れてよかった
    新人開発者と仕事をしていると本当によく起きることだ。彼らは「古いレガシーのゴミ」を見ると、最初の反応として引き剥がすか、全部捨てて最初から作り直したくなる
    場合によっては実際に試させることも学びになるが、私たちより前にいた人たちが全員まったくの馬鹿だったわけではなく、たいていはそうした理由があったのだと覚えておくとよい
    ときには本当に置き換えるべき汚い古いコードであることもあるが、その場合でも、そのドメインで何かを作るために理解し処理しなければならないあらゆる隅や境界ケースについての、苦労して得られた記録が含まれていることが多い

  • テストの部分が本当に良い。何年もかけて学んできたことと正確に一致している
    バグを見つけるには統合テストが適切なポイントだ
    モックオブジェクトは物事を過度に複雑にしがちで、今でもたまに使いはするが、体系的に使うのは避けている
    単体テストはリファクタリングに対して脆すぎる一方、統合テストはリファクタリングの助けになる

    • 自分の好きな小技は、デモシナリオに沿った統合テストを作っておき、デモ直前に実行することだ。できれば2回実行する
    • 強く反対する。統合テストは、ある程度の規模や複雑度に達するまでは素晴らしく機能するが、その線を越えると本当に悪くなる
      単体テストは作成と保守がより難しいが、失敗したときに理解しデバッグするのがはるかに簡単で、長期的にははるかによく持ちこたえる
      最悪のテストは、他の統合テストが先に実行されたという事実にこっそり依存する統合テストだ。99%は合っていても、何らかの変更で順序が変わった瞬間に壊れる
    • テストについて自分が出した結論はこうだ
      チームに単純なコードがあるなら、テストは大いに役立つ。しかしチームに単純なコードがないなら、たいていはないのだが、テストを書く時間よりもコードを単純にすることに時間を使うほうがよい
    • 多くは何を「単位」と考えるかにかかっていると思う
      葉の関数1つを単位にすると低レベルすぎる場合が多いが、比較的安定したインターフェースを持つより大きなモジュールは、テストするうえで生産的な良い単位になり得る
  • 「複雑性は非常に非常に悪い」
    「複雑性の魂の悪魔に立ち向かう最高の武器は、魔法の言葉『ノー』だ」
    「悲しいが真実:『イエス』を覚えたあとに失敗したら、他の grug のせいにする方法を覚えることが理想的なキャリアアドバイスだ」
    grug の複雑な知恵だ

  • 当時も議論されていた
    The Grug Brained Developer - https://news.ycombinator.com/item?id=31840331 - 2022年6月、コメント374件

    • 複雑性は今なお非常に悪い