「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > ソフトウェアの複雑さとの終わりのない戦い

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

2024 年 8 月 18 日に公開
ブラウズ:240

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. 依存関係

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

意味:

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

依存関係の種類:

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

2. あいまいさ

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

意味:

不明瞭さは、重要な情報が明白でない場合に発生します。

曖昧さの例:

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

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

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

段階的に進めていくものなので、「一度だけなら大丈夫」と思われがちです。しかし、蓄積されると、1 つまたは 2 つの依存関係を修正するだけでは大きな違いは生じません。

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

結論

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

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

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

ありがとう!

リリースステートメント この記事は次の場所に転載されています: https://dev.to/juniorklawa/the-never-ending-battle-against-software-complexity-46k1?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3