抽象化が多すぎると悪いことはありますか?


46

プログラマーとして、私たちの目標は、与えられたドメインモデルとビジネスロジックを適切に抽象化することだと思います。しかし、この抽象化はどこで止めるべきですか?抽象化とそのすべての利点(柔軟性、変更の容易さなど)と、コードとそのすべての利点の理解の容易さとの間でトレードオフを行う方法。

私は過度に抽象化されたコードを書く傾向があり、それがどれほど良いのかわかりません。私はよく、2つの部分で構成されるマイクロフレームワークのようなものを書く傾向があります。

  1. マイクロフレームワークに接続されたマイクロモジュール:これらのモジュールは、単一ユニットとして理解、開発、および保守が容易です。このコードは基本的に、要件で説明されている機能的な機能を実際に実行するコードを表しています。
  2. 接続コード; 今ここに私は問題があると信じています。このコードは、時には非常に抽象化されていて、最初は理解しにくいため、複雑になる傾向があります。これは、純粋な抽象化、現実のベース、および提示されたコードで実行されるビジネスロジックにすぎないという事実により発生します1。この理由から、このコードはテスト後に変更されることはありません。

これはプログラミングの良いアプローチですか?多くのモジュールで非常に断片化されたコードの変更が非常に理解しやすく、抽象化POVからの変更のないコードは非常に複雑であるということですか?すべてのコードが均一に複雑である(つまり、コード1がより複雑で相互にリンクされ、コード2がより単純である)ため、コードを見ている人は合理的な時間内にそれを理解できますが、変更は高価であるか、上記のソリューションは優れています「コードの変更」は理解、デバッグ、変更が非常に簡単であり、「コードのリンク」は一種の困難です。

注:これはコードの可読性に関するものではありません!1と2のコードはどちらも読み取り可能ですが、2のコードにはより複雑な抽象化があり、コード1には単純な抽象化があります。


3
複雑なコードを理解するのに必要な時間を早めるために、コメントとわかりやすい名前が考案されました。下位レベルのコードがより複雑であっても問題ありません。あるレベルでは、とにかくはるかに複雑ではるかに低いレベルをほぼ確実に呼び出しています。
ダグ

25
「多すぎる」は定義上悪いです。
ジョンパーディ

@JimmyHoffa:これらのタイプを適切な場所に保持する必要があります。そして嫉妬-Iは、Haskellのを書くために取得しないことはありませんすべての日。実際には、ほとんどがPHP、JavaScript、およびOCamlです。
ジョンパーディ

回答:


78

TC ++ PL4の最初の言葉:

コンピュータサイエンスのすべての問題は、インダイレクションの層が多すぎるという問題を除き、別のレベルのインダイレクションによって解決できます。–デビッドJ.ウィーラー

(David Wheelerは私の論文アドバイザーでした。重要な最後の行のない引用は、「コンピューターサイエンスの最初の法則」と呼ばれることもあります。)


6
また、間接参照のレベルが多すぎる場合、どのようにわかりますか?私はそれが経験を伴うと言う傾向がありますが、経験豊富なプログラマーは間接性をより容易に理解するので、あまりにも多くのレベルで問題は見られません。
m3th0dman

2
@ m3th0dman-将来の変更が容易になったときに、適切な抽象化レベルが得られます。もちろん、それがいつ起こるかをどのように知るかを尋ねることもできますが、それは単に質問サイクルを異なる方法で繰り返すだけです。


1
この質問はプログラマレベルに依存しているようなものです。あなたは、あなたのクレイジーな8層レイヤーアーキテクチャを理解し、それを素晴らしいと感じる複雑なプログラマーを持っているでしょう。階層化プロジェクト..これは、ドキュメントが成果をもたらす場所であり、コードをドキュメント化するだけでなく、それを守ることもできます
ライアン14

1
私の無知を許しますが、「TC ++ PL4」を理解していません
-LastTribunal

30

はい、間違いなく。問題は、完璧な抽象化はないということです。抽象化が置かれるレイヤーの詳細はすべて理由があるため、多くのことを簡素化できますが、ある時点でその複雑さが必要でなければ、そもそもそこにはないでしょう。そしてそれは、ある時点で、すべての抽象化が何らかの形で漏洩することを意味します。

そして、そこが本当の問題です。抽象化が失敗した場合、記述したコードと実際に行われていることの間にレイヤーを重ねるほど、問題が発生する可能性のある場所が増えるため、問題を見つけて修正することが難しくなります。そして、レイヤーが多いほど、それを追跡するために知る必要があります。


1
「そしてそれは、ある時点で、すべての抽象化が何らかの形で漏洩することを意味します。」:本当。より優れた抽象化は、リークの頻度が少ないものです。
ジョルジオ

11
Bjarneの回答(およびDavid Wheelerのwikiページを参照)に照らして、おそらく引用属性を変更できますか?:)
コンガスボン

2
@CongXu:ところでもう一方の端から行った: "Bjarne Stroustrup quotes"をグーグルで検索し、 "間接の別のレイヤーを追加する"というフレーズを発声したBjarneの単一の参照を見つけていない。彼が最初にそれを発声したのは非常にありそうにない。
マルジャンヴェネマ

1
抽象化の層が増えると、単純な抽象化が得られるため、抽象化ごとのリークが少なくなります。そのため、数学的な定式化(もちろん、証拠なし)では、抽象化レベルの数が変化しても、抽象化リークの合計は一定になる可能性があります。
m3th0dman

2
私はかつて、必要のない場所に抽象化を追加するように先輩のアドバイスを受けました。そもそも私がやりたいことを超えて使われることはなかった。
シーズティマーマン

15

そのとおり。

プログラミングを説明するのに使用したい例えは、テーラーの例えです。スーツを作るとき、優れたテーラーは常に衣服の戦略的な場所に少量の布地を残し、全体的な形や構造を変えずに衣服を出し入れできるようにします。

グッドテーラーは、たまたま第3の腕を伸ばしたり妊娠したりした場合に備えて、縫い目に大量の布地を残さないでください。間違った場所にある材料が多すぎると、フィット感が悪くなり、衣服を着たときに、余分な布地が通常の使用の邪魔になります。小さな布地や衣服に破れがちであり、着用者の体格のわずかな変化に対処するために変更することはできず、衣服の座り方に影響を与えます。

おそらくいつか、私たちの良い仕立て屋はドレスをとてもきつくするように任せられます。そして、おそらく私たちのGood Tailorは、スタイルとフィット感が快適さと拡張性に次ぐマタニティウェアを作るように求められています。しかし、これらの特別な仕事のいずれかを引き受ける前に、優れたテーラーは、それらの目標を達成するために行われている妥協点を全員に気付かせるのに十分賢明です。

時にはこれらの妥協が正しい道であり、人々は彼らの結果を喜んで受け入れます。しかし、ほとんどの場合、それが最も重要であるところを少し残すというアプローチは、認識された利益よりも重要です。

したがって、これを抽象化に関連付けます。絶対に多すぎるほど抽象化の層が多すぎる可能性があります。プログラマーの真の芸術は、私たちのテーラーの友人のように、最も重要な場所に少しだけ残すことです。

トピックに戻って。

通常、コードの問題は抽象化ではなく、依存関係です。あなたが指摘したように、それは問題である個別のオブジェクトを接続するコードです。なぜなら、それらの間には暗黙的な依存関係があるからです。ある時点では、物事間のコミュニケーションは具体的である必要がありますが、通常、そのポイントがどこにあるかを判断するには推測が必要です。

「マイクロ」と呼ばれることは、通常、オブジェクトレイアウトを過度に細分化したことを示しており、おそらくDataの同義語としてTypeを使用している可能性があります。また、物事が少ないということは、それらの間の通信に必要な依存関係が少なくなることを意味します。

この理由から、私はシステム間の非同期メッセージングの大ファンです。互いにではなく、メッセージに依存する2つのシステムになります。通信システム間の密結合を緩和します。その時点で、システム間の依存関係が必要な場合は、適切な場所に依存するビットがあるかどうかを考慮する必要があります。そして、あなたがしてはいけないことがよくあります。

最後に、複雑なコードは複雑になります。多くの場合、それを回避する方法はありません。ただし、依存関係の少ないコードは、さまざまな外部状態に依存するコードよりも理解しやすいです。


2
「グッドテーラーは、第3の腕を伸ばしたり妊娠したりする場合に備えて、縫い目ごとに布地を残さないでください」の+1。残念ながら、この方法でソフトウェアを設計する傾向があります。
ケモダ

理解しやすいことに加えて、曲線を直線に曲げるときに抽象化が役立つこともわかります。つまり、抽象化によって複雑さおよび/またはエントロピーが削減されます。おそらく、カレー型のデータハンドラーのようなもので、シェービングした脂肪が後でまだ有用です。
コーディ14

13

私たちの目標は、特定のドメインモデルとビジネスロジックを適切に抽象化することです。

私は別の見方をしています:私たちの目標はビジネス上の問題を解決することです。抽象化は、ソリューションを整理するための単なるテクニックです。別の答えは、服を作る仕立て屋のアナロジーを使用しています。私が考えたい別のアナロジーがあります:スケルトンです。コードはスケルトンに似ており、抽象化はボーン間のジョイントです。ジョイントがない場合は、まったく動かず、役に立たない単一のボーンで終わるだけです。しかし、関節が多すぎると、それだけでは立ち上がれないずさんなゼリーの山になってしまいます。コツは正しいバランスを見つけることです-動きを可能にするのに十分な関節ですが、実際に定義された形状や構造がないほどではありません。

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