ホームページ ウェブフロントエンド jsチュートリアル ソフトウェアの複雑さとの終わりのない戦い

ソフトウェアの複雑さとの終わりのない戦い

Jul 27, 2024 am 07:48 AM

The Never Ending Battle Against Software Complexity

複雑性とは何ですか?

最近、「ソフトウェア設計の哲学」を読み終えました。第 2 章では、ソフトウェアの複雑さのトピックが検討されています。 

書籍「A Philosophy of Software Design」では、複雑さを実際的に次のように定義しています。

「複雑さとは、理解や変更を困難にするソフトウェア システムの構造に関連するものです。」

言い換えれば、複雑さにはさまざまな形があり、必ずしもパフォーマンスと関係があるわけではありません。コードはパフォーマンスが高くても複雑である可能性があります

この記事では、この本からいくつかの重要な定義と洞察を共有したいと思います。しかしその前に、おそらくあなたがすでに経験したことがある一般的な状況を想像してみましょう…


短いホラーストーリー

皆さんの多くがおそらく経験した、あるいはこれから経験するであろうホラーストーリーに飛び込んでみましょう。

  1. それはシンプルな CRUD タスク管理アプリから始まりました。コードはクリーンでモジュール化されており、メンテナンスが簡単でした。開発チームは満足しており、システムは最初のクライアントに対して完璧に機能しました。

  2. 問題は、営業チームがカレンダーの統合、電子メール通知、優れたレポート生成機能を備えていると主張して、システムを大企業に販売したときに始まりました。販売が完了したため、これらの機能を迅速に実装する必要がありました。

  3. カレンダーの統合: チームは Google カレンダーと Outlook を統合する必要がありました。さまざまな開発者がソリューションを実装したため、一貫性のないアプローチが発生しました。

  4. メール通知: 次にメール通知が追加されました。ある開発者は特定のライブラリを使用し、別の開発者はカスタム ソリューションを作成しました。アプローチが混在しているため、コードがわかりにくくなっています。

  5. レポート ジェネレーター: レポート ジェネレーターでは、開発者は PDF、Excel エクスポート、対話型ダッシュボードなどのさまざまなテクノロジを使用しました。統一されたアプローチの欠如により、メンテナンスは悪夢のようなものになりました。

  6. 複雑さの増大: 各機能は個別に迅速に開発されたため、機能間の依存関係が生じていました。開発者は、すべてを機能させるために「クイックフィックス」の作成を開始し、システムの複雑さと結合を増大させました。

ソフトウェア開発は単独で行われるわけではありません。さまざまな内的および外的要因が影響します。私たちは皆、このような状況にこれまでに経験したことがありますし、これからも同様です。


終わりの始まり

その後、問題が始まりました:

  1. システムの一部の変更は、予期せず他の部分に影響を与えました。
  2. 小さな変更には他の多くのファイルの修正が必要となり、見積もりが困難になりました。
  3. コードは月を追うごとに理解しにくくなり、多くの場合試行錯誤によって修正されました。
  4. 生産性が低下し、誰もがメンテナンス作業を恐れていました。
  5. 「リファクタリングが必要だ」という避けられない要求
  6. 特定のタスクは特定の開発者のみが処理できます (クラシック)
  7. 時間の経過とともに、かつては美しく書かれ、十分に文書化されたソフトウェアは、廃墟と化しました。

症状に名前を付ける

私たちが現在複雑なシステムを持っていることは明らかです。

ここで、この複雑さを「分析」して、簡単に特定して緩和できるようにしましょう。

「緩和」とは次のことを意味します:

「重度、深刻、または痛みを軽くする; 軽減する。」

コードには複雑さがつきものであることが多いと思います。本質的に複雑なものもあります。開発者としてのあなたの役割は、コンピューターが効率的に実行できるコードを作成するだけでなく、将来の開発者 (将来の自分自身を含む) が作業できるコードを作成することでもあります。

「複雑さを制御することは、コンピューター プログラミングの本質です。」

— ブライアン・カーニハン

前述の本の著者は、複雑さは通常 3 つの方法で現れると述べています。

変化の増幅

一見単純な変更に多くの異なる場所での修正が必要な場合、変更の拡大が発生します。

たとえば、プロダクト所有者が「優先度」または「完了日」フィールドを要求し、エンティティが密結合している場合、いくつの変更を加える必要がありますか?

認知的負荷

認知負荷とは、開発者がタスクを完了するために必要な知識と時間を指します。

次のシナリオを想像してください。新しい開発者がチームに加わり、レポート ジェネレーターのバグを修正するよう割り当てられました。このタスクを完了するには、開発者は次のことを行う必要がありました:

  • さまざまなカレンダーの統合 (Google と Outlook) を理解します。
  • 電子メール通知に対する独特のアプローチを理解します。
  • レポート ジェネレーターの断片化されたコードをナビゲートし、PDF、Excel、ダッシュボードを処理します。
  • これらの多様なテクノロジーとスタイルを統合して、バグを見つけて修正します。

これは古典的な「推定不可能」シナリオであり、タスクに 1 ポイントまたは 8 ポイントがかかる可能性があります。D20 をロールして、それに応じて対応する方がよいでしょう。

未知の未知

未知の未知とは、自分が何を知らないのかが分からないことです。

これは複雑さの最悪の現れです。変更してはいけないものを変更してしまい、すべてが壊れてしまう可能性があるからです。

例: 開発者は、その関数に依存するレポート ジェネレーターに影響を与えることを知らずに、電子メール送信コードを変更して新しい通知を追加しました。これはクライアントに重大な問題を引き起こし、新たな複雑性の最悪の形態を例示しました。

複雑さの原因

ホラーストーリーと 3 つの主な症状を見たところで、複雑さの原因を見てみましょう。

1. 依存関係

依存関係はソフトウェアにとって不可欠であり、完全に排除することはできません。これらにより、システムのさまざまな部分が相互作用し、連携して機能することが可能になります。ただし、依存関係を適切に管理しないと、複雑さが大幅に増加する可能性があります。

意味:

コードを単独で理解または変更できない場合に依存関係が存在し、関連するコードの検討または変更が必要になります。

依存関係の種類:

  • 直接: モジュール A はモジュール B に直接依存します。
  • 推移: モジュール A はモジュール B に依存し、モジュール B はモジュール C に依存します。
  • 循環: モジュール A、B、C は循環的に相互依存しています。

2. あいまいさ

不明瞭さは、重要な情報が明らかでない場合に発生します。これにより、コードベースが理解しにくくなり、認知負荷が増大し、未知のリスクが増大する可能性があります。

意味:

不明瞭さは、重要な情報が明確ではないときに発生します。

曖昧さの例:

  • 不適切な名前付け: 名前が不明瞭な変数と関数。
  • 隠れた副作用: 予期しないアクションを実行するメソッド。
  • グローバル状態: グローバル変数の過剰使用。
  • 深い継承: 動作はクラス階層の多くのレベルに広がります。

覚えておいてください: 複雑さは段階的に増加します

  • 単一の「エラー」や間違った決定によって複雑さが引き起こされることはほとんどありません。
  • 複雑さは、時間の経過とともに間違った決定や依存関係によって「ゆっくりと」蓄積されます。

段階的に行われるため、「今回だけなら問題ない」と考えてしまいがちです。しかし、蓄積されると、1 つまたは 2 つの依存関係を修正するだけでは大きな違いは生じません。

「ソフトウェア エンジニアリングではすべてがトレードオフです。」
— 著者は覚えていません

結論

複雑さを回避する方法について、おそらくインターネットですでに見たルール、戦略、フレームワークをたくさん書くことができます: SOLID、デザイン パターン、YAGNI、KISS など。

ただし、これらすべてを 1 つの指針に統一することはできます (「The Pragmatic Programmer」で説明されているように): 「実装しているものは簡単に変更できますか?」 答えがノーの場合は、おそらく複雑さが増していると思われます。

コードを簡単に変更できるようにすることで、メンテナンスが簡素化され、開発者の認知的負荷が軽減され、システムの適応性が高まり、エラーが発生しにくくなります。

ありがとうございます!

以上がソフトウェアの複雑さとの終わりのない戦いの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

C/CからJavaScriptへ:すべてがどのように機能するか C/CからJavaScriptへ:すべてがどのように機能するか Apr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptとWeb:コア機能とユースケース JavaScriptとWeb:コア機能とユースケース Apr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScript in Action:実際の例とプロジェクト JavaScript in Action:実際の例とプロジェクト Apr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptエンジンの理解:実装の詳細 JavaScriptエンジンの理解:実装の詳細 Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:コミュニティ、ライブラリ、リソース Python vs. JavaScript:コミュニティ、ライブラリ、リソース Apr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

Python vs. JavaScript:開発環境とツール Python vs. JavaScript:開発環境とツール Apr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

JavaScript通訳者とコンパイラにおけるC/Cの役割 JavaScript通訳者とコンパイラにおけるC/Cの役割 Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

See all articles