Clean Architecture まとめ – 4

第4章 構造化プログラミング 証明 有害宣言 機能分割 正式に証明できない 救済のための科学 テスト 内容 構造化プログラミングとは、goto文を有害なものとしてなくし、その代わりに if/then/else や do/while/until などの「順次」「分岐」「反復」の制御を実現したプログラミングのこと。 構造化プログラミングは、Edger Wyde Dijikstra(読めない)が、数学の証明とプログラミングを結びつけることによってプログラムが正しいことを証明できるようにしようとして提唱したもの。goto文をなくすことによって機能を正しく小さく分割できるようになった。それによって問題が小さく分解され、正しいプログラムの証明ができるようになってきたかのように見えた。しかし、結局は数学的証明はできなかった。 わかったことは、プログラミングは数学的な証明はできないこと。プログラミングは正しいことを証明する数学ではなく、正しくないことを証明する科学(反証可能)であること。科学は、どんなに実証しても常に「正しくないこと」の可能性が常に残っているが、それが目的のために十分正しいと判断されれば使われるもの。これは、バグによって正しくないことの証明はできるが、それを修正したとしてもなんらかの「正しくないこと」の可能性が常に残っていることを意味する。テストでは「正しくない」ことを「証明できなければ」、目的のために十分正しいとみなすという理屈で正しさを担保する。 アーキテクチャは正しく機能分割されていることがベストプラクティスと考えられている。なので、構造化プログラミングの観点でアーキテクチャにとって重要なのは、反証可能な単位で正しく機能分割しプログラムを作成することである。 学びを活かすアイディア・行動 特になし

Clean Architecture まとめ – 3

3 パラダイムの概要 構造化プログラミング オブジェクト指向プログラミング 関数型プログラミング 考えるべきこと 内容 プログラミングには、構造化プログラミング、オブジェクト指向プログラミング、関数型プログラミングの3つのパラダイムがあり、これらは良いアーキテクチャを作るための3つの関心事に関連しているため、概要を紹介する。 アーキテクチャの3つの関心事と3つのパラダイムの関連 コンポーネントの分離: オブジェクト指向プログラミング データ管理: 関数型プログラミング 機能: 構造化プログラミング 3つのパラダイムの要約 構造化プログラミング直接的な制御の移行に規律を課すものである。goto文の代わりに if/then/else や do/while/until に置き換えられた。 オブジェクト指向プログラミング間接的な制御の移行に規律を課すものである。参照を階層的に制御できることを発見し、各階層のローカル変数やインスタンスなどの概念が生まれ、ポリモーフィズムの発見にもつながった。 関数型プログラミング代入に規律を課すものである。ラムダ計算という不変性を概念にした計算により、代入文がない。 これら3つのパラダイムはできることが増やしたのではなく、「すべきでないこと」を伝えている。それは、「goto文」「関数ポインタ」「代入」の3つ。これら3つのすべきでないことを、規律を課すことによってできなくした。 学びを活かすアイディア・行動 今の所特になし

Clean Architecture まとめ – 2

2. 2つの価値のお話 内容 ソフトウェアの2つの価値ソフトウェアには2つの価値があり、1つは「振る舞い」(機能)で、1つは「構造」(アーキテクチャ)である。 この2つのどちらもかけてはならないが、開発者もマネージャーもアーキテクチャより振る舞いに価値があるという認識を持っていることがある。これは間違った態度。 アーキテクチャの価値はソフトウェアが「ソフト」(簡単に変更できるかどうか)であるかどうかで決まる。 この価値の重要性を、極端な例で比べてみる。 完全に動くが、全く変更できないため、将来的には価値がなくなる 今は動かないが、簡単に変更できるため、将来的にも価値がある この例だと極端で、全く変更できないソフトウェアなど存在しない。しかし、コスト面で事実上、全く変更できないといってよいものは多々ある。つまり、低コストで変更ができることは価値がある。 2つの価値を緊急重要のマトリクスで考える「振る舞い」と「アーキテクチャ」をアイゼンハワー大統領の緊急重要のマトリクスにあてはめて考えてみる。 緊急、且つ重要 重要だが、緊急でない 緊急だが、重要でない 緊急でも重要でもない 振る舞いの領域は1と3で、アーキテクチャの領域は1と2である。エンジニアたちの中でも、振る舞いの3を1に格上げしてしまい、アーキテクチャをおろそかにしてしまうことがある。 しかし、ソフトウェアエンジニアは、これを適切に判断しアーキテクチャがおろそかになりそうであれば、それを防ぐことも仕事だ。ソフトウェアエンジニアもステークホルダーの一部ということを忘れてはならない。 学びを活かすアイディア・行動 今の所とくになし

Clean Architecture まとめ – 1

設計とアーキテクチャ 目的は? ソフトウェアアーキテクチャの目的は以下であると説明。 ソフトウェアアーキテクチャの目的は、求められるシステムを構築・保守する人材を最小限に抑えること システムは拡張・変更のコストを抑える重要な鍵はアーキテクチャにある。保守・運用コストがかかりすぎてしまう原因は、汚いコードにあり、そうなってしまうのはアーキテクチャが良くないからだ。 本書は柔軟なソフトウェアを作るためのアーキテクチャを設計するための原則を紹介する。 アーキテクチャとは?設計とは? アーキテクチャとは、大枠から細部に至るまでの構造で、大枠と詳細との厳密な境界の明確な基準はない。設計とは、大枠から細部に至るまでの決定の連続のことで、こちらも大枠と詳細の境界の明確な基準はない。 一般的には、アーキテクチャとは上位レベルの構造を指し、下位レベルの詳細と切り離して捉えられていたり、設計は細部の決定をすることと捉えられていることがあるが、それは開発手法やフェーズを踏まえた場合に発生している考え方であって、実際はそれが一般的な基準となる考え方になるわけではない。 ケーススタディ 人材をリリースごとに増やす。図1-1 人が増えているにも関わらず、リリースが進むごとに生産性が下がっていく。図1-2。図1-4。 しかし、人は増えているからリリースが進むごとにコード行あたりのコストも爆増し、開発者に払う給料も爆増。図1-3、図1-5 何が間違ったのか? 開発者は、後でクリーンにできると自信過剰になり、市場に出すことを急いだ。しかし、実際には後でクリーンにすることはない。市場、競合他社のプレッシャーがあるから。そしてコードはどんどん汚くなり、生産性は落ちていく。 あとでクリーンにできるから先に出すという考え方は、汚いコードは長期的には生産性が下がるが、短期的には上がるという考え方が起因している。しかし、この考え方は間違っていて、実際には短期的にも長期的にも遅いのが正しい。(TDDで進めたプロダクトとそうでないプロダクトで検証。)だから、あとでクリーンできるという考え方は根本から変えないといけない。 うさぎとかめは良い教訓を教えてくれる。 遅くとも着実なものが競争に勝つ 競争は短期的ではない。強いものが勝つわけでもない。 急げば急ぐほど遅くなる 学びを活かすアイディア・行動 今の所特になし

レガシーコードからの脱却 まとめ – 9.8.2

9.8.2 保守しやすいコードを書く7つの戦略 内容 コードの共同所有を取り入れるコードの共同所有とは誰でもどのコードでも変更してよいことを意味する。チーム全員が同じコーディング規約を持つことで、誰が書いてもスタイルは保たれ扱いやすくなる。同じドメインモデル、開発プラクティス、用語を揃えることで更に良くなる。 リファクタリングを熱心に行うすでに動いているものであっても、状況に応じてリファクタリングはしていくと良い。リファクタリングは保守性につながる。 常時ペアで進めるペアプログラミングは知識共有の一番はやい方法。設計、開発、リファクタリング、デバッグ、テストでは常時ペアを組み、共有された知識で、コードの一貫性を保つ。 頻繁にコードレビューするペアを組んでいたとしても、ペアを組んでいない人がコードを見てフィードバックする機会になる。 ほかの開発者のやり方を学ぶ自分の外側にある知識を学びつつ自分も成長させる。 ソフトウェア開発を学ぶプロの専門家は継続的な学習が必要。ソフトウェア開発者もしかり。 コードを読み書きして、コーディングの練習をする作家スティーブン・キングは「作家になるために必ずしなければならないことが2つある。たくさん読み、たくさん書くことだ」と言った。ソフトウェア開発者も同じで、たくさん読み、たくさん書くこと。 学び 保守性を高める戦略 学びを活かすアイディア・行動 ペアプロ、コーディング規約作り

レガシーコードからの脱却 まとめ – 9.8 – 9.8.1

9.8 実践しよう 9.8.1 コード品質を上げる7つの戦略 内容 品質の定義を明確にする高品質のコードを作るには、高品質のコードとは何かを明確に定義しなければならない。高品質なコードとは少なくとも、理解しやすく拡張が簡単でなければならない。 品質のためのプラクティスを共有するたとえば、機能開発を重要視することで、それぞれのメソッドの凝集性を高くするなど。 完璧主義を手放す完璧なものは作れない。完璧でなくても明確な受け入れ基準を持てば、それを叶えるための最善は尽くせる。 トレードオフを理解する状況に応じたトレードオフを理解することで、完璧でなくてもニーズに応えられるかどうかを判断することができる。 「やり方」を隠す読み手は、どうやって実装されているかを気にすることなく欲しい物がなんなのかがわかるようになる。 良い名前をつけるソフトウェア自身が一番のドキュメントであることを理解し、それが何なのか、何をしてくれるものかをわかる名前をつける。略称を使う必要はなく、長さを気にする必要もない。説明的、肯定的、能動的、呼び出し側がどのように変化するのかが分かる名前をつける。 コードをテスト可能に保つ観測可能なコードとコード品質は相関関係がある。テスト可能なようにコードを書こう。 学び 品質を高める戦略。 学びを活かすアイディア・行動 今の所特になし

レガシーコードからの脱却 まとめ – 9.6

9.6 コード品質が私たちを導いてくれる 9.7 明日のベロシティのために今日品質を上げる 内容 「CLEAN」コードはテストのしやすさで測ることができる。 凝集性に問題がある場合、あるクラスのテストをたくさん書くことになる。 疎結合に問題がある場合、関係ない依存関係がたくさんあることになる。 カプセル化に問題がある場合、テストが実装に依存していることになる。 断定性に問題がある場合、テスト結果がテストオブジェクト以外から得られることになる。 冗長性に問題がある場合、あちこちで同じテストを書くことになる。 また、これらの品質は1つを上げるとその他の品質も上がっていく。 ケント・ベックは著書「テスト駆動開発」でコードの重複(冗長性)にだけ気をつければ、全体の品質は上がるとしているし、著者も凝集性にフォーカスするのを好んでいる。 これらはテストで測れるわけだから、テストを書いて進めるテストファースト開発をすることがおすすめ。 学び CLEANコードかどうかはテストでわかる。 フォーカスする品質は1つか2つでも効果がある。 学びを活かすアイディア・行動 今のところ特になし

レガシーコードからの脱却 まとめ – 9.4 – 9.5

9.4 高品質なコードは断定的である 内容 自分自身のことは自分自身で管理する。これをしないと凝集性が薄くなり、依存し合うコードが生まれやすい。そうなると複雑性が増し、保守しづらくなり、壊れやすくなる。 9.5 高品質なコードは冗長でない 内容 同じことを繰り返さない。保守の難易度が上がるから。 ただし、ミッションクリティカル(人命に関わるような)な場合で、その方が安全と判断するような、「意図的な重複」は良い。 良くないのは「意図しない重複」。 学び 「断定的」に関して、まだ理解が薄いので学習が必要 学びを活かすアイディア・行動 今の所特になし

レガシーコードからの脱却 まとめ – 9.3

9.3 高品質なコードはカプセル化されている 内容 カプセル化とはインターフェース(やりたいこと)と実装(どうやるか)を切り離すこと。 開発者はアウトサイドインとインサイドアウトの方法でカプセル化をする。これらの呼び名は著者がそう呼んでいるもので、 アウトサイドインプログラミングドメインを全体的に捉え、ユーザーのニーズとなる体験をベースに設計していく方法。 インサイドアウトプログラミング問題を小さく分解し、それらを組み合わせて1つのソリューションを作る方法。 開発者はこの両方の観点を持って開発に臨むべきだが、先に必要なのはアウトサイドインの方。インサイドアウトから始めると、全体を俯瞰せずに実装を進めることができるため、ドメインを全体視した場合の持つべきふるまいや役割と乖離する可能性があり、そういったモジュールは結果的に壊れやすいため。だからユーザーの体験に基づいて設計し、その実現方法はインサイドアウトの観点で進めるとよい。 基本的に、モジュールを使う側の視点で設計されたインターフェースはpublicで、それ以外はprivate、必要に応じて protected 、package というようなアクセスレベルで調整すると良い。 学び カプセル化の仕方はいろいろあるが、まずユーザーに届ける体験をベースに考えて、ユーザーが何をしたいのか、何を得たいのかをインターフェースにすし、具体的な実装は別で隠すという方法を基本的な考えに持つと良い。 学びを活かすアイディア・行動 今の所特になし

レガシーコードからの脱却 まとめ – 9.2

9.2 高品質なコードは疎結合である 内容 疎結合とは、部品と部品の結合部につなぎ目を入れて、お互いが直接干渉しない状態のこと。その逆は密結合。 これによってそれぞれを変更したときにお互いが影響しないため変更しやすくなる。テストするときはモックを使ってテストができる。JavaやC#ではインターフェースを使って実現できる。 ただし、なんでもかんでも疎結合にすればよいというわけではない。例えば、GUIに終了ボタンとボタン押下時の終了アクションがあり、要件的にその2つは必ずセットになっていないとおかしい場合、必ずしも疎結合でなければならないとは思えない。 つまり、疎結合であってほしいところと疎結合で、密結合であってほしいところは密結合であってほしい。 これを「意図による結合と不慮の結合」という言い方を著者はしている。疎結合が良くて密結合が悪いのではなく、それぞれあるべき結合度をコントロールできているかが重要。 特に、多くのことを行うAPIが不慮の結合になってしまうケースが見受けられる。こういう場合は内部で複数のAPIを呼び出すように実装することで、複雑性をそれぞれのAPIに任せることができ、結果的に疎結合にもなり凝集性も高くなる。また、性能や別の制約によってコード品質を下げてしまう場合があまりにも多いが、これは本当にしょうがない場合だけにするべき。 学び 結合度と凝集性は少し似ている。 学びを活かすアイディア・行動 GUIとプレゼンテーションロジックの結合度を考える