特徴の交差の扱い


11

最近、フィーチャー交差に関するこの記事で説明されているものと同様の問題がますます多く見られます。私は通常、これらの問題を可能な製品構成の形で遭遇するのに対して、私はこれらを実際には異なる製品に帰する傾向があるものの、製品ラインと呼ぶこともあります。

このタイプの問題の基本的な考え方は単純です。製品に機能を追加しますが、他の既存の機能の組み合わせにより、どういうわけか物事は複雑になります。最終的に、QAは、これまで誰も考えていなかった機能のまれな組み合わせの問題を発見し、単純なバグ修正であったはずのものが、大きな設計変更が必要になることさえあります。

この機能の交差問題の側面は、驚くほど複雑です。現在のソフトウェアバージョンにN機能があり、1つの新しい機能を追加するとします。また、各機能をオンまたはオフにすることしかできず、2^(N+1)考慮できる機能の組み合わせがすでにあると言って、説明を簡略化しましょう。表現や検索用語が不足しているため、これらの組み合わせの存在を特徴の交差問題と呼んでいます。(より確立された用語のリファレンスを含む回答のボーナスポイント)。

ここで私が苦労している問題は、開発プロセスの各レベルでこの複雑な問題にどのように対処するかです。明らかなコスト上の理由から、それぞれの組み合わせに個別に対応することは、ユートピア的なところまでは非現実的です。結局のところ、私たちは正当な理由で指数関数的な複雑さのアルゴリズムに近づかないようにしていますが、開発プロセスそのものを指数関数的なサイズのモンスターに変えることは、まったくの失敗につながるはずです。

では、予算を爆発させず、まともな、有用な、専門的に受け入れられる方法で完全な体系的な方法で最良の結果を得るにはどうすればよいでしょうか。

  • 仕様:新しい機能を指定する場合、他のすべての子とうまく機能することをどのように保証しますか?

    既存の各機能を新しい機能と組み合わせて体系的に検査できることがわかりますが、それは他の機能とは切り離されています。一部の機能の複雑な性質を考えると、この分離されたビューはすでに非常に複雑であることが多いため2^(N-1)、他の機能によって引き起こされた要因はもちろん、それ自体が構造化されたアプローチを必要としています。

  • 実装:機能を実装する場合-すべてのケースでコードが適切に相互作用/交差することをどのように保証しますか。

    繰り返しますが、私は純粋な複雑さについて疑問に思っています。2つの交差する機能のエラーの可能性を減らすためのさまざまな手法を知っていますが、妥当な方法で拡張できる手法はありません。ただし、仕様中の優れた戦略により、実装中は問題を回避できると思います。

  • 検証:フィーチャーをテストする場合、このフィーチャーの交差スペースの一部しかテストできないという事実にどのように対処しますか?

    単一の機能を分離してテストしても、エラーのないコードの近くには何も保証されないことを知るのは十分に困難ですが、これを2^-N数分の1に減らすと、何百ものテストがすべての海洋の1滴の水をカバーしていないように見えます。さらに悪いことに、最も問題のあるエラーは、フィーチャの交差に起因するエラーであり、問​​題につながるとは予想されませんが、そのような強い交差が予想されない場合、これらのエラーをどのようにテストしますか?

他の人がこの問題をどのように扱っているかを聞きたいのですが、私は主にこのトピックをより深く分析する文学や記事に興味があります。そのため、個人的に特定の戦略に従う場合、対応するソースを回答に含めるとよいでしょう。


6
賢明に設計されたアプリケーションアーキテクチャは、世界をひっくり返すことなく新機能に対応できます。ここでの経験は素晴らしいレベラーです。そうは言っても、そのようなアーキテクチャーは、最初の試行で正しく実行することが常に容易であるとは限らず、場合によっては難しい調整を行う必要があります。機能と機能を適切にカプセル化し、適切な単体テストでカバーする方法を知っている場合、テストの問題は必ずしもそうであるとは限りません。
Robert Harvey

回答:


6

プログラムの検証は、停止の問題により、最も一般的なケースでは有限時間では不可能であることを数学的にすでに知っています。したがって、この種の問題は新しいものではありません。

実際には、適切に設計されたシステムでもNを超えるように見えますが、優れた設計は、交差するフィーチャの数が2 ^ Nをはるかに下回るようなデカップリングを提供できます。

ソースに関しては、ソフトウェア設計に関するほとんどすべての本またはブログが効果的に2 ^ Nを可能な限り削減しようとしているように見えますが、私があなたと同じ言葉で問題を投げかけたものは知りません行う。

設計がこれにどのように役立つかを示す例として、記事では、レプリケーションとインデックス作成の両方がeTagによってトリガーされたために機能の交差が発生したと述べています。それらのそれぞれの必要性を個別に通知するために別の通信チャネルを利用できれば、イベントの順序をより簡単に制御でき、問題も少なくなったはずです。

またはそうでないかもしれません。RavenDBについて何も知りません。機能が本当に不可解に絡み合っている場合、アーキテクチャは機能の交差の問題を防ぐことができません。また、2 ^ N交差の最悪のケースが実際にある機能が望ましくないことを事前に知ることはできません。しかし、アーキテクチャは、実装の問題により、少なくとも交差点を制限できます。

RavenDBとeTagsについて私が間違っている(そして私は議論のためにそれを使用している-彼らは賢い人々であり、おそらくそれを正しく理解している)としても、アーキテクチャどのように役立つかは明らかです。人々が話すほとんどのパターンは、新機能または変更機能によって必要とされるコード変更の数を減らすことを目的として明示的に設計されています。これは、昔にさかのぼります。たとえば、「設計パターン、再利用可能なオブジェクト指向ソフトウェアの要素」など、「各設計パターンは、アーキテクチャの一部の側面を他の側面から独立して変化させることができるため、システムを特定の種類に対してより堅牢にする変化する"。

私の要点は、実際に何が起こっているかを見ることによって、特徴の交差点のビッグOを実際に理解できるということです。この回答を調査したところ、機能ポイント/開発努力(つまり-生産性)のほとんどの分析では、機能ポイントごとのプロジェクト努力の線形成長よりも少ないか、線形成長をわずかに超えることがわかりました。これは少し意外だと思いました。 これにはかなり読みやすい例がありました。

これ(およびいくつかのコード行ではなく関数ポイントを使用する同様の研究)は、機能の交差が発生せず、問題を引き起こさないことを証明していませんが、実際には壊滅的ではないことは合理的な証拠のようです。


0

これは決して最良の答えではありませんが、私はあなたの質問のポイントと交差するいくつかのことを考えてきたので、私はそれらに言及したいと思いました:

構造サポート

私が見た少しから、機能にバグがあるか、他の機能とうまくかみ合わない場合は、主に、プログラムのコア構造/フレームワークがそれらを管理/調整するために提供するサポートが不十分であることが原因です。より多くの時間を費やしてコアを具体化し、丸めることで、新しい機能の追加が容易になると思います。

私が作業しているアプリケーションで共通しているのは、プログラムの構造が一種のオブジェクトまたはプロセスの1つを処理するように設定されているが、これまでに行った、または実行したい多くの拡張機能があることです。多くの種類の処理に関係しています。これがアプリケーションの設計の最初にさらに考慮されていれば、後でこれらの機能を追加するのに役立ちます。

スレッド化/非同期/イベント駆動型コードを含む複数のXのサポートを追加する場合、これは非常に重要になります。これは、すぐに問題が発生する可能性があるためです。これに関連する多くの問題をデバッグする喜びがありました。

ただし、特にプロトタイプまたは1回限りのプロジェクトの場合、この種の取り組みを前もって正当化することはおそらく難しいでしょう。これらのプロトタイプまたは1回限りのものが、再び、または最終システム(の基礎)として使用され続けたとしても、つまり、支出は長期的に見ればそれだけの価値があったでしょう。

設計

プログラムのコアを設計するとき、トップダウンアプローチから始めることで、物事を扱いやすいチャンクに変えるのに役立ち、問題のあるドメインに頭を回すことができます。その後は、ボトムアップのアプローチを使用する必要があると思います。これは、物事をより小さく、より柔軟にし、後で追加するのに役立つようにするのに役立ちます。(リンクで述べたように、このようにすると、機能の実装が小さくなり、競合/バグが少なくなります。)

システムのコアビルディングブロックに焦点を当て、それらがすべて適切に相互作用することを確認すると、それらを使用して構築されたものもおそらく正常に動作し、システムの他の部分とよりよく統合されます。

新しい機能が追加されたとき、フレームワークの残りの部分を設計したときと同様の方法で設計することができると思います。それを分解してからボトムアップします。機能を実装する際にフレームワークの元のブロックを再利用できる場合、それは間違いなく役立ちます。完了したら、機能から取得した新しいブロックをコアフレームワークの既存のブロックに追加し、元のブロックのセットでテストすることができます。これにより、システムの残りの部分と互換性があり、将来使用できるようになります。同様に機能。

簡素化する!

私は最近の設計でミニマリストのスタンスをとっており、問題を単純化することから始め、次にソリューションを単純化しています。少し時間をかけて、プロジェクトの設計反復を簡略化できるとしたら、後で物事を追加するときに非常に役立ちます。

とにかく、それは私の2cです。

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