web-dev-qa-db-ja.com

潜在的にモノリシックなアプリケーションをいくつかの小さなアプリケーションに分割することは、バグの防止に役立ちますか?

これを尋ねる別の方法は、なぜプログラムはモノリシックになる傾向があるのですか?

Mayaのようなさまざまなワークフローで使用されるアニメーションパッケージのようなものを考えています。

アニメーション機能とモデリング機能が独自の個別のアプリケーションに分割され、個別に開発され、それらの間でファイルが渡される場合、それらの保守は容易ではないでしょうか?

48
dnv

はい。一般に、2つの小さい複雑でないアプリケーションは、1つの大きいアプリケーションよりも保守がはるかに簡単です。

ただし、アプリケーションがすべて連携して目標を達成すると、新しいタイプのバグが発生します。それらを一緒に動作させるためには、メッセージを交換する必要があり、すべてのアプリケーションが完全に機能する場合でも、このorchestrationはさまざまな方法で失敗する可能性があります。 100万個の小さなアプリケーションを使用することには、独自の特別な問題があります。

モノリシックアプリケーションは、単一のアプリケーションに機能を追加するときに最終的に使用するデフォルトのオプションです。各機能を単独で検討する場合、これが最も簡単なアプローチです。全体が大きくなり、「XとYを分ければ、何がうまくいくか」を確認できるのは、全体が大きくなってからです。

94
Ewan

潜在的にモノリシックなアプリケーションをいくつかの小さなアプリケーションに分割することは、バグの防止に役立ちますか

現実にはそれほど簡単なことではありません。

分割しても、そもそもこれらのバグを防ぐのに役立ちません。バグをより早く見つけるのに役立つことがあります。小さな孤立したコンポーネントで構成されるアプリケーションでは、それらのコンポーネントの個別の(「ユニット」のような)テストが可能になる場合があります。これにより、特定のバグの根本原因を特定しやすくなり、より迅速に修正できるようになります。

しかしながら、

  • 外部からモノリシックであるように見えるアプリケーションでさえ、内部で多くの単体テスト可能なコンポーネントで構成されている可能性があるため、単体テストは必ずしも単体アプリにとって難しくありません。

  • ewanがすでに述べたように、いくつかのコンポーネントの相互作用は追加のリスクとバグをもたらします。また、複雑なプロセス間通信を伴うアプリケーションシステムのデバッグは、単一プロセスアプリケーションのデバッグよりもはるかに困難です。

これは、より大きなアプリをコンポーネントに分割できる程度、コンポーネント間のインターフェイスの幅、およびそれらのインターフェイスの使用方法にも大きく依存します。

要するに、これはしばしばトレードオフであり、一般的に「はい」または「いいえ」の答えが正しい場所はありません。

プログラムがモノリシックになる傾向がある理由

彼らですか?あなたの周りを見てください。世界中には膨大な数のWebアプリがあり、私には一見一体ではないようです。プラグインモデルを提供する多数のプログラムも利用できます(AFAIKは、あなたが言及したMayaソフトウェアでも提供しています)。

彼らは維持するのが容易ではないでしょうか

ここでの「より簡単なメンテナンス」は、アプリケーションのさまざまな部分をさまざまなチームがより簡単に開発できるため、より優れた分散ワークロード、明確な焦点のある専門チームなどに起因することがよくあります。

51
Doc Brown

これについては大多数の意見に同意しないといけない。アプリケーションを2つの別々のアプリケーションに分割しても、それ自体でコードの保守や推論が容易になるわけではありません。

コードを2つの実行可能ファイルに分離すると、コードのphysical構造が変更されるだけですが、それは重要ではありません。アプリケーションの複雑さを決定するのは、アプリケーションを構成するさまざまな部分がどのように密結合するかです。これは物理的な特性ではなく、論理の特性です。

さまざまな懸念事項とシンプルなインターフェースを明確に分離したモノリシックアプリケーションを使用できます。他のマイクロサービスの実装の詳細に依存し、他のすべてのサービスと緊密に結合されたマイクロサービスアーキテクチャを使用できます。

確かに、1つの大きなアプリケーションを小さなアプリケーションに分割するプロセスは、各部分の明確なインターフェイスと要件を確立しようとするときに非常に役立ちます。 DDDでは、それはあなたの限界のあるコンテキストを思い付くでしょう。ただし、多数の小さなアプリケーションを作成する場合でも、同じ論理構造を持つ1つの大きなアプリケーションを作成する場合でも、技術的な決定がより重要になります。

38
Voo

分割が完了すると、維持が簡単になります。しかし、それらを分割することは必ずしも容易ではありません。プログラムの一部を再利用可能なライブラリに分割しようとすると、元の開発者が seams がどこにあるべきかを考え損なった場所が明らかになります。アプリケーションの一部がアプリケーションの別の部分に深く達している場合、修正が困難な場合があります。シームをリッピングすると、内部APIをより明確に定義する必要があり、thisは、最終的にコードベースの保守を容易にします。再利用性と保守性は、どちらも明確な縫い目の製品です。

15
StackOverthrow

相関は因果関係ではないことを覚えておくことは重要です。

大きなモノリスを作成し、それをいくつかの小さなパーツに分割すると、良いデザインになる場合とそうでない場合があります。 (それはcan設計を改善しますが、保証されるわけではありません。)

しかし、優れた設計では、大きなモノリスではなく、いくつかの小さな部品としてシステムが構築されることがよくあります。 (モノリスcanは最高のデザインです。それははるかに少ない可能性です。)

小さな部品の方が良いのはなぜですか?理由がわかりやすいからです。正しさについて簡単に推論できる場合は、正しい結果が得られる可能性が高くなります。

C.A.R.を引用するホアレ:

ソフトウェア設計を構築する方法は2つあります。1つは明らかに欠陥がないように単純にする方法で、もう1つはがないように複雑にする方法です。明らか欠陥。

もしそうなら、なぜ誰かが不必要に複雑な、または一体的なソリューションを構築するのでしょうか? Hoareは次の文で答えを提供します。

最初の方法ははるかに困難です。

そして、後で同じソース(1980年のチューリング賞講演):

信頼性の代償は、最大限のシンプルさを追求することです。それは非常に金持ちが支払うのが最も難しい価格です。

13
Daniel Pryden

これは「はい」または「いいえ」の答えのある質問ではありません。問題は、メンテナンスの容易さだけではなく、スキルの効率的な使用に関する問題でもあります。

一般に、適切に作成されたモノリシックアプリケーションは効率的です。プロセス間およびデバイス間の通信は安価ではありません。単一のプロセスを分割すると、効率が低下します。ただし、すべてを単一のプロセッサで実行すると、プロセッサに過負荷がかかり、パフォーマンスが低下する可能性があります。これが基本的なスケーラビリティの問題です。ネットワークが問題に入ると、問題はさらに複雑になります。

単一のサーバー上で単一のプロセスとして効率的に動作できる適切に作成されたモノリシックアプリケーションは、保守が容易で、欠陥がない状態を維持できますが、コーディングとアーキテクチャのスキルを効率的に使用できません。最初のステップは、プロセスを同じプロセスとして実行されるライブラリに分割することですが、凝集と疎結合の規律に従って、独立してコーディングされます。このレベルで良い仕事をすると、保守性が向上し、パフォーマンスにほとんど影響しません。

次の段階は、モノリスを個別のプロセスに分割することです。あなたがトリッキーな領域に入るので、これはより難しいです。競合状態エラーが発生するのは簡単です。通信オーバーヘッドが増加し、「チャットインターフェイス」に注意する必要があります。スケーラビリティの壁を打ち破るので報酬は素晴らしいですが、欠陥の可能性も増加します。マルチプロセスアプリケーションはモジュールレベルで維持するのが簡単ですが、システム全体がより複雑になり、トラブルシューティングが難しくなります。修正は、途方もなく複雑になる場合があります。

プロセスが個別のサーバーまたはクラウドスタイルの実装に分散されると、問題は難しくなり、報酬は大きくなります。スケーラビリティが急上昇します。 (スケーラビリティをもたらさないクラウドの実装を検討している場合は、よく考えてください。)しかし、この段階で発生する問題は、特定して考えるのが非常に難しい場合があります。

6
MarvW

いいえ。保守が容易になるわけではありません。何か問題があれば歓迎します。

なぜ?

  • プログラムは直交しておらず、合理的な範囲で相互の動作を維持する必要があります。これは、共通の理解を意味します。
  • 両方のプログラムの多くのコードは同じです。共通の共有ライブラリを維持していますか、それとも2つの別々のコピーを維持していますか?
  • これで2つの開発チームができました。彼らはどのようにコミュニケーションしていますか?
  • これで、次の2つの製品が必要になります。

    • 共通のUIスタイル、対話メカニズムなど...設計上の問題が発生しました。 (開発チームはどのようにやり取りしていますか?)
    • 下位互換性(モデラーv1をアニメーターv3にインポートできますか?)
    • クラウド/ネットワークの統合(機能の場合)は、2倍の数の製品で更新する必要があります。
  • これで、モデラー、アニメーター、モデラーアニメーターの3つの消費市場ができました。

    • 彼らは優先順位が競合します
    • 彼らは相反するサポートニーズを持つことになります
    • 使用方法が矛盾します
  • モデラーアニメーターは、同じファイルで作業するために2つの別々のアプリケーションを開く必要がありますか?両方の機能を持つ3つ目のアプリケーションはありますか?1つのアプリケーションが他のアプリケーションをロードしますか?
  • 等...

コードレベルが小さいほど、アプリケーションレベルでの保守が容易になると言われていますが、無料のランチを手に入れることはできません。これは、Micro-Service/Any-Modular-Architectureの中心にある同じ問題です。万能薬ではなく、アプリケーションレベルでのメンテナンスの難しさは、オーケストレーションレベルでのメンテナンスの難しさと交換されます。これらの問題は依然として問題であり、もはやコードベースには存在しません。回避するか解決する必要があります。

オーケストレーションレベルで問題を解決する方が簡単で、各アプリケーションレベルで問題を解決する場合は、問題を2つのコードベースに分割して、オーケストレーションの問題に対処することをお勧めします。

そうでない場合は、いいえ、それを行わないでください。アプリケーション自体の内部モジュール性を改善することで、より良いサービスが提供されます。アプリケーションがプラグインとして機能するライブラリを、コードのセクションごとにまとまり、保守しやすいようにプッシュします。結局のところ、モノリスは、図書館のランドスケープのオーケストレーションレイヤーにすぎません。

4
Kain0_0

良い答えはたくさんありましたが、ほぼ完全に分割されているので、帽子もリングに入れます。

ソフトウェアエンジニアとしての私の経験では、これは単純な問題ではないことがわかりました。実際には、アプリケーションのサイズスケール、および目的に依存します。それらを変更するために必要な慣性のために古いアプリケーションは一般的にモノリシックです。これは長い間一般的な慣習であったためです(Mayaはこのカテゴリに該当します)。私は一般的に新しいアプリケーションについて話していると思います。

多かれ少なかれ単一の関心事である十分に小さいアプリケーションでは、多くの個別の部品を維持するために必要なオーバーヘッドは、一般に、分離を持つという実用性を超えます。 1人で保守できる場合は、多くの問題を引き起こすことなく、モノリシックにすることができます。このルールの例外は、便利に(論理的に)分離されている多くの異なる部分(フロントエンド、バックエンド、おそらくその間のデータレイヤー)がある場合です。

非常に大規模な単一の関心のあるアプリケーションでも、それを分割することは私の経験では理にかなっています。他の(時には解決しやすい)バグと引き換えに、可能なバグのクラスのサブセットを減らすという利点があります。一般に、生産性を向上させる孤立したチームで作業することもできます。ただし、最近の多くのアプリケーションはかなり細かく分割されており、場合によっては独自の不利益を被っています。私はチームに所属していて、アプリケーションが非常に多くのマイクロサービスに不必要に分割されているため、相互の通信が停止したときに多くのオーバーヘッドが発生しました。さらに、各パーツが他のパーツとどのように対話するかについての知識をすべて保持する必要があると、連続する分割ごとにはるかに難しくなります。バランスがあり、ここでの答えからわかるように、それを行う方法は非常に明確ではなく、実際には標準がありません。

3
CL40

UIアプリの場合、全体的なバグの量が減る可能性は低いですが、バグミックスのバランスがコミュニケーションによって引き起こされる問題にシフトします。

ユーザー向けのUIアプリケーション/サイトと言えば、ユーザーは非常に忍耐強くなく、短い応答時間を要求します。これにより、通信の遅延がバグになります。その結果、単一のコンポーネントの複雑さが減少するため、潜在的なバグの減少と、プロセス間/マシン間通信の非常に難しいバグとタイミング要件がトレードオフされます。

プログラムが扱うデータの単位が大きい場合(つまり、画像)、プロセス間の遅延は長くなり、排除するのが難しくなります。「10 mb画像に変換を適用」のようなものは、即座に+20 mbのディスク/ネットワークを獲得しますIOインメモリ形式からシリアライザ形式への変換とその逆の2つの変換に加えて。ユーザーからそうするために必要な時間を隠すためにできることは本当にあまりありません。

さらに、すべての通信、特にディスクIOは、アンチウイルス/ファイアウォールチェックの対象になります。これにより、バグの再現がさらに困難になり、遅延がさらに増えることになります。

モノリシックな「プログラム」の分割は、通信の遅延が重要ではない、またはすでに避けられない場合に役立ちます

  • 個々のステップを大幅に改善するために小さな余分な遅延をトレードできる並列化可能な情報の一括処理(既製の1回の使用でカスタムコンポーネントが不要になる場合があります)。小さな個別のステップフットプリントにより、たとえば、高価な単一の機械の代わりに、複数の安価な機械を使用できる場合があります。
  • モノリシックサービスを結合度の低いマイクロサービスに分割する-複数のサービスを1つではなく並行して呼び出すと、遅延が増えることはほとんどありません(個々のサービスが高速で依存関係がない場合は、全体の時間が短縮されることもあります)。
  • ユーザーが長い時間を必要とする操作の移動-複雑な3Dシーン/映画のレンダリング、データに関する複雑なメトリックの計算、...
  • あらゆる種類の「オートコンプリート」、「スペルチェック」、およびその他のオプションの補助機能は、しばしば外部にすることができます-最も明白な例は、入力が常に外部サービス(検索エンジン)に送信されるブラウザのURL自動提案です。

これはデスクトップアプリとWebサイトに適用されることに注意してください。プログラムのユーザー側部分は「モノリシック」になる傾向があります。単一のデータに関連付けられているすべてのユーザー操作コードは通常、単一のプロセスで実行されます(分割することは珍しいことではありません) HTMLページや画像のようにデータ単位で処理しますが、この質問とは関係ありません)。ユーザー入力のある最も基本的なサイトであっても、サーバー側にすることでよりモジュール化し、複雑さやコードの重複を減らすことができる場合でも、クライアント側で検証ロジックが実行されます。

1
Alexei Levenkov

[=] =バグを防止しますか?

防ぐ?まあ、いいえ、そうではありません。

  • 検出バグを助ける
    特に、ご存じなかったすべてのバグは、その混乱全体を小さな部分に分割しようとしたときにのみ発見されました。したがって、ある意味で、これらのバグが本番環境で出現するのを防ぐことができましたが、バグはすでにそこにありました。
  • バグの影響を減らすのに役立ちます
    モノリシックアプリケーションのバグは、システム全体を停止させ、ユーザーがアプリケーションと対話しないようにする可能性があります。そのアプリケーションをコンポーネントに分割した場合、ほとんどのバグは、設計上、コンポーネントの1つにのみ影響します。
  • newバグのシナリオを作成します。
    ユーザーエクスペリエンスを同じにしたい場合は、これらすべてのコンポーネントが通信するためのnewロジックを含める必要があります(REST services、 OSシステムコールを介して、ユーザーのPOVからシームレスに対話できます。
    簡単な例として:モノリシックアプリを使用すると、ユーザーはアプリを離れることなくモデルを作成してアニメーション化できます。アプリをモデリングとアニメーションの2つのコンポーネントに分割します。ここで、ユーザーはモデリングアプリのモデルをファイルにエクスポートし、ファイルを見つけてアニメーションアプリで開く必要があります...正直なところ、一部のユーザーはそうしたくないので、新しいロジックを含める必要がありますファイルをエクスポートするモデリングアプリおよびアニメーションアプリを自動的に起動およびファイルを開きます。そして、この新しいロジックは、非常にシンプルな場合もありますが、データのシリアル化、ファイルへのアクセスとアクセス許可、ユーザーによるアプリのインストールパスの変更などに関して、多くのバグを抱えている可能性があります。
  • リファクタリングを適用するのに最適な言い訳です。
    モノリシックアプリを小さなコンポーネントに分割する場合、システムが最初に設計されたときよりも多くの知識と経験をもって(うまくいけば)分割します。そのおかげで、多くのアプリケーションを適用できますコードをよりクリーン、シンプル、効率的、回復力、安全性を高めるためにリファクタリングします。そして、このリファクタリングは、ある意味で、バグの防止に役立ちます。もちろん、モノリシックアプリに同じリファクタリングを適用して同じバグを防ぐこともできますが、UIの何かに触れてビジネスロジックを壊すことを恐れるほどモノリシックなので、そうではありません¯\ _(ツ) _ /¯

そのため、モノリシックアプリを小さなコンポーネントに分割するだけでバグを防止しているとは言えませんが、実際には、バグをより簡単に防止できるポイントに到達しやすくなっています。

0
walen