疎結合設計を作成するためにどれだけの労力を費やす必要がありますか?


10

現在、デザインパターンについて学習しています。

ほとんどの人はこれらのパターンが優れたツールであることに同意するだろうと思いますが、すべての答えとしてではなく、適度に使用する必要があります。これらを使いすぎると、アプリケーションが過度に複雑になり、ほとんどメリットがありません。パターンは、それらが最良のソリューションになるか、優れたソリューションの作成に役立つ場合にのみ使用する必要があります(同意しますか?)。

これを考慮して:

私が読んでいる本(Head First Design Patterns)は、疎結合の重要性を強調しています。この疎結合は、「実装ではなくインターフェイスへのプログラム」や「変化するものをカプセル化する」などの原則に従って達成されます。

基本的に、これまでに学んだほとんどのパターンは、デザインを疎結合にして、より柔軟にするために存在します。

疎結合の重要性と利点を理解しています。

しかし、私の質問は、疎結合で柔軟な設計を作成するために実際にどれだけの労力を費やすべきかということです。

設計パターンに反対する人々は、これらのパターンを使用するコストが利益を上回ることが多いと言います。いくつかのパターンを使用して疎結合設計を作成することに多くの時間を費やしますが、実際には、疎結合、「実装ではなくインターフェイスへのプログラミング」、およびこれらの原則のすべては、実際にはそれほど重要ではない可能性があります。

私が知りたいのは、抽象化とデザインの追加レベルを作成するために実際にどのくらいの努力を払うべきかということです。これは、アプリケーションが疎結合、インターフェイスへのプログラム機能などのオブジェクト指向の原則に従うことを許可するためだけです。それは本当に価値がありますかそれ?これにはどのくらいの努力が必要ですか?


ケントベックなど、一生懸命に努力する人もいます。
Niing

回答:


14

致命的な答え:あなたがそれをすればするほど、それはより少ない努力です。

基本的に、疎結合コードを構築することはそれほど難しくありません。一方、疎結合の観点から考えるように心を訓練することはそうです。そして、まあ、私はそれが完全に価値があると信じています。

過去20年間でほとんどの人が推奨してきたように、ソフトウェア開発に反復的なアプローチを使用する仕事をするとします。イテレーション1で美しく機能するものを構築します。イテレーション2では、その上に構築し、いくつかの新しい機能を追加し、イテレーション1の概念に収まらない場合に1つまたは2つの要素を少し曲げます。 。イテレーション3が登場し、基本的なアーキテクチャを再考するために必要な要件がわかります。どのようにしてコードを切り離し、元のコードに戻さずに再構築しますか?

これが起こります。たくさん。プロジェクトが遅れて実行されるか、後の反復で実行する必要があることを実行するのが怖くなりすぎます。最良のケースでは、泥の大きなボールを取得します。疎結合や単一責任の原則などは、これらの問題を大幅に軽減します。だからこそ、SOLIDの原則は大いに宣伝されています。

そして、ベルトの下に疎結合のデザインがいくつかあると、自然にそれが始まります。パターンとは、人々がそれらのために機能したことを発見したものであるため、それらを文書化しました。これらは、時間とともに自然に生まれる便利なツールです。


5

必要な労力は、常に十分とは言えません。より良い方法は、ペイオフ率への努力だと思います。しかし、見返りが何であるかを理解することは、常に簡単でエラーのないわけではありません。

柔軟性を高めるパターンについて覚えておくべきことは、パターンを配置するのにいくらかの労力がかかることであり、パターンが必要な理由を正確に理解できない場合、コードが複雑になる可能性がありますが、使用することはありません。柔軟性が決して変わらない場合、それはそこにもありません。

常に(または合理的に可能な限りそれに近く)行う必要がある1つのことがあります。ソフトウェアの個々のコンポーネント(OOPのオブジェクト、関数型プログラミングまたは手続き型プログラミングの関数)をブラックボックスにすることです。ブラックボックスは、内部(実装)がわからない、または気にしないものです。

それがどのように機能するのかわからない、または気にしない場合は、インターフェイス以外のものを使用するつもりはないので、インターフェイスを変更せずに実装が変更された場合、ブラックボックスの内部のみが問題になります。影響を受ける可能性があります。また、プログラム全体の詳細をすべて頭に置いておく必要がないため、プログラムについて考えるのも簡単になります。 正当に忘れることができる詳細が多ければ多いほど、重要な詳細のためにあなたの頭の中にもっと多くの余地があります。

デザインパターンに対する反対意見を誤解していると思います。私はそれらのファンではありませんが、インターフェイスへの疎結合とプログラミングの原則が非常に好きです。彼らに対する私の最も強い反対は、それらがそれらの背後にある原則の理解を促進するのではなく、むしろ詳細の暗記を奨励するパッケージ化されたソリューションとして提示されることです。それらを研究しないことをお勧めするつもりはありませんが、研究するときは、それらの背後にある原則を理解することが特定のパターンの詳細よりも重要であることを覚えておいてください。

デザインパターンに対する異論の1つは、それらが「自明」である、または「その名前ではなく、聞いた前にそれらを使用していた」ことです。人々がそれらの異論を唱えることができる理由、またはデザインパターンの創始者がそもそもそれを思い付くことができる理由は、彼らが彼らの背後にある原則を理解したからです。

ブラックボックスを使用すると、コードがまともな方法で整理され、通常、コストは(もしあれば)それほど高くありません。どこでもそれらを使用してください。抽象化の層を追加したり、物事を複雑にしたりするデザインパターンやその他の手法を使用すると、コストがかかります。彼らがきれいか、きちんとしたか、賢いという理由だけでそれらを使用しないでください。それらが問題に適合し、費用が利益を得るために支払う価値があるときにそれらを使用します。


4

あなたの質問はデザインパターンとの疎結合と同等であるように見えますが、それらは本当に別々ですが、関連するものです。

疎結合はプログラミングの基本的な関心事です。マシンコードからシンボリック言語に移行するとすぐに、プログラムはその実行と疎結合になりました。等。

OO自体は、基本的に疎結合コンポーネントを作成するためのモデルです。カプセル化は、オブジェクトの内部を他のオブジェクトと疎結合にします。関数の実行は他の関数の実行と極端に結合しているため、関数型プログラミングはさらにそうかもしれません。

ほぼ定義により、行う設計には疎結合が含まれます。誤って密結合するように調整する方法はいくつかありますが、誰かが実際にシステムをより密結合するように設計した例はわずかしかありません。

(私は時々、将来の開発者が特定のフレームワークアーティファクトへの静的参照を埋め込み、それらを強制的に使用することによってデザインを選択できないようにしたい人と協力しています。そして、多くのコンテキストで再利用します。)


3

パターンは、それらが最良のソリューションになるか、優れたソリューションの作成に役立つ場合にのみ使用する必要があります(同意しますか?)。

実装の詳細として設計パターンを厳密に見ています。公開APIとプログラムをそのドキュメントに文書化する場合、一般に、デザインパターンがどこにあるかは重要ではありません(または影響は大きくありません)。つまり、「ここにブリッジパターンがあります。その上にビジターを実装します」というわけではありません。代わりに、「このクラスはさまざまなオペレーティングシステムで異なる実装を持つため、ブリッジパターンを使用して実装されます」です。次に、それを使用する場合、ブリッジパターンとしてではなくパブリックAPIを見るので、ブリッジとして実装されていることに無関心です。

疎結合で柔軟な設計を作成するために実際にどれだけの労力を費やす必要がありますか?

疎結合は、単純な一連の規則に従うことで実現できます。これらを尊重すると、コードは(さらに)記述したときに疎結合になります(つまり、何らかの努力がすでに開発プロセスの一部になっています)。

ルールの中で(完全なリストではありません):

  • クライアントコード(クラスの使用方法)を検討(または記述)してインターフェースを定義します。クラスが行うこと(つまり、実装ではなくインターフェースを設計する)ではありません。
  • 「教えて、聞かないで」
  • すでに作成されたパーツからオブジェクトを構築する
  • コンストラクターに、使用する実際のオブジェクトを渡します(メンバーのファクトリー、パラメーターのファクトリーのパラメーターなどではありません)。
  • DRY(2つの場所に同じ順序で表示される2つの行がある場合、それらを別の関数に抽出する、など)。
  • オブジェクトの作成がより複雑な操作である場合は、中間パーツの作成をファクトリメソッド/クラスとして(つまり、コンストラクタ本体ではなく)実装します。
  • YAGNI(以前ではなく、必要に応じて作成する)。

これらのルールは、言語、開発方法論、続いてチーム(TDDなど)、時間予算の制約などに応じて、異なる方法で守られます。

たとえば、Javaでは、インターフェイスをとして定義し、interfaceその上にクライアントコードを作成することをお勧めします(その後、実装クラスでインターフェイスをインスタンス化します)。

一方、C ++ではインターフェイスがないため、インターフェイスを抽象基本クラスとしてのみ記述できます。C ++では、強い要件がある場合にのみ継承を使用するため(不要な仮想関数のオーバーヘッドを回避できるため)、おそらくインターフェイスを個別に定義せず、クラスヘッダーのみを定義します)。

設計パターンに反対する人々は、これらのパターンを使用するコストが利益を上回ることが多いと言います。

彼らはそれを間違っていると思います。疎結合(およびDRY)コードを記述する場合、最小限の追加労力で設計パターンをコードに統合できます。それ以外の場合は、設計パターンを実装するためにコードを適合させる必要があります。

デザインパターンを実装するために多くの変更を行う必要がある場合、問題はデザインパターンではなく、コードベースがモノリシックで密結合されていることです。これは、設計パターンの問題ではなく、不良/次善の設計問題です。

私が知りたいのは、抽象化とデザインの追加レベルを作成するために実際にどのくらいの努力を払うべきかということです。これは、アプリケーションが疎結合、インターフェイスへのプログラム機能などのオブジェクト指向の原則に従うことを許可するためだけです。それは本当に価値がありますかそれ?これにはどのくらいの努力が必要ですか?

あなたの質問は、疎結合の唯一の利点は設計パターンを簡単に実装できることであるという(述べられていない)仮定を立てます。そうではない。

疎結合の利点には、次のものがあります。

  • リファクタリングと再設計の柔軟性
  • 無駄な労力が少ない
  • テスト容易性
  • コードを再利用する可能性の増加
  • シンプルなデザイン
  • デバッガーで費やされる時間の短縮

...そして、今は思い浮かばない他のいくつか。

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