複雑さのジャンプをどのように管理しますか?


13

時々プロジェクトに取り組んでいて、突然何かが突然現れて、作品に巨大なスパナを投げ込み、複雑さを大幅に高めることは、まれではあるが一般的な経験のようです。

たとえば、私は他のさまざまなマシンでSOAPサービスと通信するアプリケーションで作業していました。正常に動作するプロトタイプを作成し、その後、通常のフロントエンドを開発し、一般的に、すべてを素晴らしく、非常にシンプルで、簡単にフォローできる方法で実行しました。より広いネットワークでテストを開始し、接続の待ち時間とリモートマシンで計算を実行するのに必要な時間がSOAPサービスへのタイムアウトリクエストになったため、突然ページがタイムアウトするまで、うまくいきました。要求ごとに計算を実行するのではなく、バックグラウンドで段階的に更新できるように、要求を独自のスレッドにスピンアウトし、返されたデータをキャッシュするようにアーキテクチャを変更する必要があることが判明しました。

そのシナリオの詳細はあまり重要ではありません-実際、それは非常に予見可能であり、このタイプの環境用にこのタイプのアプリをたくさん書いた人々はそれを予想したかもしれないので、素晴らしい例ではありません-単純な前提とモデルから始め、突然プロジェクトの開発に複雑さをエスカレートさせることができます。

開発プロセスの後の段階で、またはテストの結果として、多くの場合仕様変更ではなく環境要因の結果として、これらのタイプの機能変更の必要性に対処するための戦略はありますか?可能性はある必ずしもそうではない可能性のある問題を軽減するソリューションを設計することで、同じくらい効果的である可能性が高いが、準備が整っていないソリューションを設計することで、時期尚早な最適化/ YAGNI /オーバーエンジニアリングのリスクを回避することのバランスをどのように取るか起こりうるあらゆる事態?

編集:Crazy Eddieの答えには、「あなたはそれを吸い込んで、新しい複雑さを実装するための最も安価な方法を見つける」ということが含まれています。それで、質問に暗示されている何かを考えさせられましたが、具体的には挙げませんでした。

そのバンプにヒットしたら、必要な変更を組み込みます。プロジェクトをできるだけスケジュールに近づけるが、保守性に影響を与える可能性があることを行いますか、またはアーキテクチャに戻って、保守性が高いかもしれないが開発中にすべてを元に戻すより詳細なレベルでやり直しますか?

回答:


8

これを読んで私の頭に浮かぶのは、アジャイルの格言です。プロジェクトのライフサイクル内で、最もリスクが高く、および/またはあまり理解されていないタスクに最初に取り組みます。すなわち、コンセプトが機能することを証明するために、プロジェクトの作業スケルトンをできるだけ早くまとめようとします。これにより、アーキテクチャが実際の生活環境下で本当にその約束を果たしているかどうかを検出するために、あらゆる種類の残酷なテストを実行できます。また、ソリューションに新しい未知のテクノロジー/プラットフォーム/ツールが含まれている場合は、それも早めに検討してください。

コアアーキテクチャに問題がなければ、個々の機能を追加して追加テストし、必要に応じてリファクタリングし、比較的少ないコストで実現できます。アーキテクチャを変更する必要があることは大きなリスクであり、事前に対処する必要があります。これにより、迅速なフィードバックが得られます。最悪の場合、コンセプト全体がバラバラになった場合、早期にそれを認識し、最小限の損失でプロジェクトを中止できます。


6

あなたの例は、プログラミングの最も挑戦的な側面、すなわち分散コンピューティング並行プログラミングに触れており、それらはより広く使用され、プログラマーの仕事をますます難しくしています。

「通常の」プログラミング(1台のマシン上のシングルスレッド)でさえ、非トリビアルプログラムにとっては非常に複雑であるため、それを上手に使うには大きなスキルと長年の経験が必要ですが、それでも「解決」からはかけ離れています。このレベルの複雑さでさえ、ほとんどが組み合わせ爆発であるため、人間の脳が完全に把握して理解する能力をはるかに超えています。そうでないと考えるのは愚かなことです。

分散コンピューティングと並行プログラミングは、「複雑な」空間のサイズにさらに2つの次元を追加します。これは、「通常の」プログラミングと比較して、少なくとも3次(sp?)(n ^ 3)で成長します。たとえば、対処しなければならないいくつかの新しい問題と誤解について考えてみてください。このスケールで相互接続と副作用を推測することができるという考えでさえ、笑うことができます。

明確な特効薬はありませんが、最大の間違いは、すべてを理解して解決したと考えることです。

他の答えがすでにカバーしているものに加えて、このすべてに対処する方法に関するいくつかのアイデア:

  • 素晴らしい謙虚さ
  • システム/プログラムが不完全、非永続的、不完全であることを受け入れます。
  • エラーに備える
  • 変化を受け入れる
  • 冗長性を計画する
  • 将来の校正について考える
  • 複雑なシステムの振る舞いを生物学(社会学)で調べます(または研究します)
  • 可変状態を避けるために最大限の努力をしてください。ステートレスプロトコル(RESTやHTTPなど)を探します。
  • 関数型プログラミングは痛みの一部を軽減するかもしれません

続けられると思います。非常に興味深い主題:)


複雑なシステムがどのように振る舞うかを生物学(社会学)で調べてください( C'mon)。答えの残りの部分は堅実でしたが、これには、説明した問題に対する周辺アプリケーションがあります。
ジムG.

1
@ジムG.たぶん。生物学はforループの最適化には役立ちませんが、新しい視点、洞察、または(ソフトウェア開発に関する)効果的な抽象化を考えたい場合は、サンドボックスから抜け出すのに役立ちます。生物学(または社会学)はプログラミングとは何の関係もないと主張しますが、OOPまたはデザインパターンがプログラミングとは無関係であると主張するのはほんのわずかです。例:OOPbiology- > Alan Kay-> OOP / Smalltalk。またはデザインパターン:社会学->都市デザイン->クリストファーアレクサンダー->パターン言語->デザインパターン。
マグロブ

@ジムG.続き アラン・ケイ:「オブジェクトは生物細胞やネットワーク上の個々のコンピューターのようなものであり、メッセージとしか通信できない」とウィキペディア:「[デザインパターン]このアイデアは建築家クリストファー・アレキサンダーによって建築の分野[1]およびコンピュータサイエンス」を含む様々な他の分野に適合されている
Maglob

わかった。可変状態やその他のナゲットを避けるために、最大限の努力をてください。私のポイントは、あなたのマネージャーが複雑さを減らすようにあなたに任せたなら、あなたは間違いなくオッカムのカミソリを問題に当てはめて仕事をするだろうということです。あなたや他の誰もが差し迫った問題を助けるために「生物学に目を向ける」とは思わない。
ジムG.

2

@PéterTörökの答えの精神には同意しません。それは、チーム(または個人)がプロジェクトライフサイクルの早い段階で最もリスクの高い項目を必然的に予見できると想定しているためです。たとえば、OPの場合、チーム、背中が壁に突き当たるまで、マルチスレッドソリューションに付随するエスカレートする複雑さを予測できませんでした

OPの質問は良い質問であり、多くのソフトウェア開発会社が抱えている問題を物語っています。

ここに私が問題に対処する方法があります:

  1. フレッド・ブルックスのアドバイスに従い、手術チームのように開発者を組織してください。
  2. 次の両方が可能な賢明で「慈悲深い」マスター外科医を選択します。A)同僚の信頼と尊敬を集めます。およびB)困難な決定をタイムリーに行う。
  3. 開発プロセスのフロントエンドとバックエンドの複雑さを軽減するために、マスター外科医を期待してください。

ポイント#3の詳細:

  1. マスター・サージョンは、最も簡単な解決策を提案するために意識的な努力を払うべきです。長年の有意義な経験は、マスター外科医をそうする立場に置くべきです。
  2. より広範な組織、つまりマスター外科医の上司は、出荷日以降の複雑さを軽減するのに十分な時間とリソースをチームに与える必要があります。これにより、開発チームはコードをタイムリーに出荷し、カイゼンを実行して継続的に複雑さを軽減できます。

OPの場合、IMHOは、実際の状況下でアーキテクチャがどのように(そしてどのように)動作するかを明らかにするために、より早くテストを開始する必要がありました。「マスター外科医」を提案することによって、あなたは基本的にプロジェクトの技術的リスクを予見できる人がいることを暗示しているようです-あなたが反対すると主張する正確なポイント。
ペテルトレック

@PéterTörök:...「マスター外科医」を提案することにより、基本的にプロジェクトの技術的リスクを予測できる人がいることを暗示しているように見えます。いいえ、そうではありません。私はこれらの人々が両方とも言っている:A)そもそも複雑さを完全に避けるのに最適。およびB)コードの出荷後にチームを複雑さから掘り下げるのに最適。
ジムG.

私見私たちは同じことについて話している。「マスター外科医」がおそらく機能する最も簡単なソリューションを選択するのに役立つ経験は、過去のプロジェクトとソリューションの記憶から構築され、どのソリューションが特定のケースで機能した(または機能しなかった)かを知ることです。言い換えれば、(s)彼は特定の問題に適用可能な解決策を調べ、それぞれの潜在的な利点とリスクを評価します。これは、彼/彼女が現在の状況に適したものを選択するのに役立ち、したがって、より危険な経路回避します
ペテルトレック

1
これは、遅くて偉大な馬の調教師であるレイ・ハントからの引用を思い出させます
グレナトロン

1

インターフェイスへのコード

他の機能と連動する新しい機能を作成する場合、すべてが通過するインターフェース(Javaの種類)の形で境界を作成します。この意志

  1. 使用する機能を完全に制御できるようにします
  2. 同じ機能を複数実装することができます。
  3. モジュールは完全に絡み合っているのではなく、薄く接続されているだけなので、全体的な複雑さを抑えてください。

0

簡単な前提とモデルから始めて、プロジェクトの開発に突然複雑さをエスカレートさせることができます

驚かない。

これはソフトウェア開発です。新しいものを発明していない場合は、既存の実証済みのソリューションをダウンロードしています。

中間点はほとんどありません。

新しいものを発明する場合、完全に理解していない機能が少なくとも1つ必要です。(これを完全に理解するには、実際に使用する実装が必要です。これを使用するだけです。)

これを管理する方法は?

  1. 現実的な期待があります。あなたは何か新しいものを発明しています。そこなければなりませんあなたが理解していない部分も。

  2. 現実的な期待があります。初めて正常に動作するように見える場合は、見落としがあります。

  3. 現実的な期待があります。簡単な場合、他の誰かが最初にそれを行っていたので、そのソリューションを簡単にダウンロードできます。

  4. 現実的な期待があります。将来をうまく予測することはできません。


2
待って、あなたが言っているのは、現実的な期待がありますか?
グレナトロン

0

陳腐化を考慮した設計とコード。今日コーディングしたものは、明日切り取って置き換える必要があると仮定します。


0

環境は仕様の一部である必要があります。したがって、環境の変更は仕様の変更です。一方、仕様に含まれていた環境以外の環境にプロトタイプと設計を基づいていた場合、愚かな間違いを犯しました。いずれにせよ、あなたはそれを吸い込み、新しい複雑さを実装する最も安価な方法を見つけます。


0

私の意見では、ほとんどのプログラミングの問題と同様、それは依存します。この問題は、障害が起こるだろう、されていることを忘れてはならないことを、創造的な仕事に非常に固有のものであるとのOKということ。プログラミングは厄介な問題であり、通常、問題を解決するまで、その問題の正しい解決策はわかりません。

ただし、次のようなローカルで特定の要因が多数存在します。

  • このシステムの目標。 それは一度きりのものですか?このシステムを中長期に機能させ続けるつもりですか?

短期的なものについては、実行するだけで十分だと考える価値はないかもしれません。リファクタリングは高価であり、ユーザーに即座に最終的な価値をもたらすものではありません。 しかしながら、絶対的な使い捨てソフトウェア以外に考えることができるケースはほとんどありません。それは、設計を改善する価値がないほど短期間だからです。今すぐ終了するよりも、自分が何をしたかを理解し、迅速に修正できることがはるかに重要です。長期的な場合、最終的に(そしておそらく関係者全員が考えるよりもはるかに早く)成果を上げる可能性が非常に高くなります。「時間をかけて改善する」と言いたくなりますが、それが不可能な場合があります。

  • チームの目標。 それは「今すぐやる、それでもなんでも」ということですか、それとも「正しくやろう」ということですか?

これは、決定に大きな影響を与えるはずです。あなたのチームは、再設計のためのリソースを提供することでこの決定をサポートするか、すぐに解決する必要があります。私の意見では、チームが一貫して間違った方向にあなたを押していることがわかった場合、それは大きな赤旗です。この種のことは、絶え間ない消火が行われ、悪い設計が作成する問題を常に修正しているため、再設計する時間がありません。ただし、「ダクトテープ」を今すぐに修正します(ただし、実際に修正します)。

  • 問題に対するあなたの理解。 以前のソリューションが機能しなかったのはなぜですか?

本当に重要です。エラーまたは問題が何であり、なぜ発生しているのかを考えてください。この種の状況は、欠陥(または欠落)の仮定、制約、および相互作用を見つける絶好の機会です。一般に、現在の問題を解決するのではなく、常に問題をよりよく理解することをお勧めします。これはおそらく、YAGNI /オーバーエンジニアリングに対する最大の防御策です。あなたは十分にあなたの問題を理解した場合は、解決します、それを他の問題をしていません。

最後に、正しい方法で物事を構築してみてください。問題や固有の人為的なエラーについて理解するときに直面するエラーや問題については話していない。「間違いを犯さないで、初めて完璧にしよう」という意味ではありません-それは不可能です。つまり、毎日の作業で複雑さをうまく管理し、壊れたウィンドウを修正し、できるだけシンプルに保ち、コードと思考を常に改善してください。そうすれば、変更がドアをノックした場合(ない場合)、ショットガンの代わりに両手を広げて歓迎できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.