web-dev-qa-db-ja.com

ギャングオブフォーは「パターンスペース」を徹底的に探求しましたか?

私が最初に Gang of Four(GoF)デザインパターン について知って以来、少なくとも10年前に、これらの23のパターンは非常に大きなもののほんの小さなサンプルにすぎないという印象を持っていますPattern Spaceを呼び出すのが好きです。この架空のパターンスペースは、一般的なオブジェクト指向ソフトウェア設計の問題に対するすべての推奨されるソリューション(既知または未知)で構成されています。

したがって、既知の文書化された設計パターンの数が大幅に増加すると予想しました。

それは起こりませんでした。 GoFの本が出版されてから20年以上が経過し、ウィキペディアの記事には12の追加パターンのみがリストされています。そのほとんどは、元のパターンよりもあまり人気がありません。 (特定のトピックをカバーしているため、ここでは同時実行パターンを含めませんでした。)

理由は何ですか?

  • GoFのパターンセットは、実際には私が思っているよりも包括的ですか?

  • 新しいパターンを見つけることへの関心は低下しましたか、それはおそらく、それらがソフトウェア設計でそれほど有用ではないことが判明したためでしょうか?

  • 他に何か?

150
Frank Puffer

この本が出たとき、多くの人がそのように考え、「パターンライブラリ」または「パターンコミュニティ」さえも作成しようとする多くの努力がありました。あなたはまだそれらのいくつかを見つけることができます:

しかしその後...

新しいパターンを見つけることへの関心は低下しましたか、それはソフトウェアパターンで実際にはそれほど有用ではないためでしょうか?

これ、とても。デザインパターンの要点は、開発者間のコミュニケーションコミュニケーションですが、さらにパターンを追加しようとすると、人々がそれらを覚えられなくなるところにすぐに到達します、またはそれらを覚えていない、または正確に彼らがどのように見えるべきであるかについて同意しない、そしてコミュニケーションは実際には改善されていません。これはGoFパターンですでに多く発生しています。

個人的には、私はさらに進んでいきます。ソフトウェア設計、特に優れたソフトウェア設計は、パターンで意味のある形で捉えるにはあまりにも多様であり、特に人々が実際に覚えることができる少数のパターンでは–それらは人々にとってあまりに抽象的すぎるほんの一握り以上のものを本当に覚えています。だから彼らはあまり役に立たない.

そして、あまりに多くの人々がコンセプトに夢中になり、どこにでもパターンを適用しようとします。通常、結果のコードでは、すべての(完全に無意味な)シングルトンと抽象ファクトリの間の実際の設計を見つけることができません。

167

これらの23のパターンは、パターンスペースと呼べるはるかに大きなもののほんの一部にすぎないという印象を持っています。

これは、ソフトウェアパターンをつなぎ合わせるだけでプログラムを作成できると考えるプログラマである、初心者のプログラマによって広まる恐ろしい仮定です。そのようには機能しません。そのような「パターンスペース」がある場合、そのサイズは事実上無限であると想定できます。

(GoFの意味での)デザインパターンには、使用しているプログラミング言語の欠陥を補うという1つの目的があります

デザインパターンは普遍的でも包括的でもありません。別のより表現力豊かなプログラミング言語に変更すると、GoFブックのパターンのほとんどが不要になり、望ましくなくなります。

108
Robert Harvey

ここで出てくる3つの要因があると思います。

臨界質量の欠如

まず、パターンは基本的に、特定の機能の「チャンク」を実装するいくつかのコードに名前を付けることにすぎません。名前が多くの実際の値を提供する唯一の方法は、everybodyが名前の意味を知っているため、名前を使用するだけで、コードについて多くのことをすぐに理解できるかどうかです。

しかし、パターンはそれを達成するために必要な臨界質量を確立していません。むしろ反対、AAMOF。 GoFの本が発表されてから20年ほどで、関係者全員がコミュニケーションを改善するために十分なデザインパターンを実際に知っている会話が12件も見られなかったと確信しています。

少し趣のある言い方をすると、デザインパターンは失敗したという理由だけで失敗しました。

パターンが多すぎます

2つ目の大きな要因は、どちらかといえば、最初はあまりにも多くのパターンを指定したことです。多くの場合、パターン間の違いは非常に微妙であり、特定のクラスが1つのパターンに適合しているか、または両方に適合しているか(または両方に当てはまるか、あるいは両方に当てはまるか)を正確に判断することはほぼ不可能です。

その意図は、より高いレベルでコードについて話すことができるということでした。特定のパターンの実装として、かなり大きなコードのチャンクにラベルを付けることができます。その事前定義された名前を使用するだけで、聞いている人は通常、そのコードを気にかけているのと同じくらい知っているので、次のことに進むことができます。

現実はほぼ逆になる傾向があります。あなたが会議に参加していて、この特定のクラスがファサードであることを彼らに伝えたとしましょう。会議の半分の人々は、それが何を意味するのか正確に忘れて以来、まったく知らなかったか、長い間持っていません。そのうちの1人は、ファサードと、たとえばプロキシとの正確な違いを思い出させるように頼みます。ああ、そしてパターンを本当に知っている2人の人々は、これが本当にFacadeと見なされるのか、それとも「単なる」アダプタと見なされるのか(まだ1人の男がプロキシのように見えると主張しているのか)を議論する残りの会議を費やします。

あなたの意図が「このコードはそれほど興味深いものではないので、先に進みましょう」と言うだけだったとすると、パターンの名前を使用しようとすると、値ではなく、注意散漫になっただけです。

興味がない

ほとんどのデザインパターンは、コードの興味深い部分を実際には扱いません。彼らは、「これらのオブジェクトをどのように作成するのか」、「このオブジェクトにそのオブジェクトと通信させるにはどうすればよいのか」などを扱います。これらのパターン名(および前述の詳細などに関する議論)を記憶することは、ほとんどのプログラマーがあまり気にしていないことに多くのエネルギーを注ぐだけです。

少し違う言い方をすれば、パターンは多くのプログラムで同じことを扱いますが、プログラムを本当に面白くするのは、他のプログラムとは異なるであるということです。

概要

設計パターンは次の理由で失敗しました:

  1. 彼らは臨界質量を達成することに失敗しました。
  2. パターン間の差異は、明確さを保証するには不十分でした。
  3. 彼らは主にコードの一部を扱っており、とにかく誰も本当に気にしていませんでした。
62
Jerry Coffin

パターンには抽象化が欠落しており、単純なパターンは抽象化されており、複雑なパターンは認識されないため、パターンは役に立ちません(いくつかの高レベルのパターンを除く)。

ポール・グラハムはそれを最もよく言ったと思います:

プログラムのパターンを見ると、問題の兆候だと思います。プログラムの形は、解決する必要のある問題のみを反映する必要があります。コード内の他の規則性は、少なくとも私にとっては、十分に強力ではない抽象化を使用していることを示しています-多くの場合、私が書く必要があるマクロの展開を手動で生成しています。

コード内のパターンを認識する場合、それは何かが繰り返されることを意味し、より優れた抽象化を使用する必要があります。より良い抽象化がない場合は、パターンを回避策として使用します。新しいプログラミング言語はより良い抽象化を提供するので、パターンはあまり役に立たなくなります。
また、単純なパターンは簡単に抽象化され、複雑なパターンはほとんど認識されません。
パターンが抽象化に置き換えられた場合、それはパターンの背後にある概念が消えることを意味するのではなく、その概念を間接的ではなく明示的に記述することができ、他のコードやそれと比較してもはや特別ではないことを意味しますパターンとして認識できなくなります。

35
Siphor

私はほとんど他の人がここで答えたことに同意しますが、個人的には、パターンの数が増えていない主な理由は、無数のパターンがあるとパターンの意味が失われるためだと思います。これらのいくつかのパターンのいいところは、標準的な方法で多くの問題ドメインをカバーすることです。無限のパターンドメインに集中すると、パターンがまったくなくなります。 「島の海岸線の長さは?」みたいな感じです。あなたが地図上で測定する場合、あなたはまともな数が付属しています。しかし、より正確にしてより細かい解像度にしようとすると、長さが無限大(または不確実性)にますます長くなります。潮汐と原子レベルで正確な境界をどのように測定しますか?)。

13
qwerty_so

他のどの回答も関連がないと述べているもの:

動的型付け言語の台頭。

本が最初に出たとき、Javaは実際の作業を行うには遅すぎたという真剣な議論がありました。現在Javaは、より表現力のある言語で頻繁に使用されています- その理由その速度の可能性があります。Ruby、Python、JavaScriptなどは、一部の重要なアプリケーションクラスにはまだ遅すぎるかもしれませんが、概して、ほとんどの目的には十分高速です。少なくともJavaScriptすべてのリリースでより多くの機能がパックされているにもかかわらず、実際には速くなっています。

オリジナルのGoFブックにはSmalltalkとc ++の両方のパターンがあり、メモリが機能する場合、Smalltalkではパターンが常に短くなり、場合によってはパターンが大幅に短くなります。クラシックデザインパターンの一部の機能は、静的型付けされたシステムに動的機能を追加する方法です(既に説明したAbstractFactoryのように、ランタイムデータに基づいて正しいクラスをインスタンス化します)。他のものは、動的言語では非常に短いため、単純に言語自体の慣用的な使用に融合します。

11
Jared Smith

それはdidが起こります。出版社や作家がさらに別のバンドワゴンに飛びついたり(または作成したり)しようとしたため、コンピュータサイエンス全体をパターンの設計に還元する試みのように見えたもので、数百冊ではないにせよ数十冊の本が出版されました。棚があります。最初にスキャンしてから相談したことはありません。実際に使用したことはほとんどないか、まったく知られていないか、まだよく知られていなかったため、私は吸盤でした(たとえば、Type Objectを参照してください)。 1段落ではなく12ページ)、そして明らかにパターンが少ないほど良いので、ほとんどの開業医から逃れた点です。実際、Type Objectの反論を投稿したときに、テキストをデザインパターンとして再キャストするように指示されました。実話。これはまた、プロジェクトの別の欠陥を示しています。レビューや除外、拒否のメカニズムはありません。

実際のところ、GoFは実際に「デザインパターンを徹底的に調査」することを試みていませんでした。むしろ、彼らははるかに大きなプロジェクトに従事していました:CSに「パターン言語」を導入することで、フォースや参加者などのすべての奇妙な記譜のアーカナを使用しましたが、それは根本的に誤解されていて無意味だったために失敗しました。

彼らがdidが達成したことは、便利でしたが、2つのことでした。

  • visitorパターンなどのいくつかの便利なトリックを公開する
  • 主にスタックしている名前の標準セットを提供します:Factory、Adapter、Iterator、...直前に設計されたCORBAを見ると、この値がわかります:Interceptorなどのあらゆる種類の「外来」名、しもべ、ブローカー、...

生じた別の有用な概念は、「アンチパターン」でした。 「ログしてスロー」。このプロジェクトは、CSの多くの流行と同様に、独自の伝道と誤って別のCS宗教として採用されたことにより脱線し、そのようなほとんどの宗教の道を歩みました:部分的には有用ですが、確かに「特効薬はありません」((c )フレッドブルックス、1965)。数年おきにそれを再発見しなければならないのは悲しいことです。

10
user207421

PLoP( Pattern Languages of Program Design )というタイトルの本が数冊あり、それぞれが 年次会議 で発表された論文集です。

本を読んで、私はいくつかのパターンが興味深く、私にとって新しいものであることに気づきました。それらのいくつかは標準です(たとえば、「ハーフオブジェクトとプロトコル」)。

だから、いや、GoFのコレクションは完全なものではなく、人々に新しいコレクションを収集、説明、発見、発明するように促しました。

「ウィキペディアの記事に記載されている12の追加パターンのみ」も、おそらく完全なコレクションではありません。つまり、他の場所で文書化されている他のパターンがあります。 PLoPの本や他の場所でも。

6
ChrisW

Gang of Four(GoF)の本には、関数型言語を使用していない経験豊富なプログラマがツールベルトに持っているほとんどのパターンが含まれています。これは、すべてのビルダーが使用方法を知っている基本的なツールセットのようなものです。この本の主な貢献は当時、ほとんどの経験豊富なプログラマが一般的に使用していたパターンに明確な名前を付けるであり、したがって、設計オプションについて議論するプログラマ間のコミュニケーションに役立ちます。

電気技師が通常のビルダーにはないいくつかのツールを持っていることを期待します。同様に、WPFプログラマーが「依存関係プロパティ」の設計パターンを知っていること、または「SQLプログラマー」がトリガーを使用するための設計パターンを知っていることを期待します。監査データを作成します。

ただし、これらは1つのテクノロジーでのみ使用されるため、「デザインパターン」とは見なされません。

「既存のコードのデザインをリファクタリング、改善する(Martin Fowler)」「クリーンコード:アジャイルソフトウェアのハンドブック」 Craftsmanship(Robert C. Martin)これらの本はどちらも、「事前に用意された再利用可能なデザイン」としてではなく、現在のコードに対して行う変換として内容を示していますが、それらは「設計パターン」。

5
Ian

以下は、Erich Gammaへのインタビューです。彼は、パターンの選択とそれらが今日変更するもの(10年前は今日も)について反省しています。

http://www.informit.com/articles/article.aspx?p=1404056

Larry:「デザインパターン」をどのようにリファクタリングしますか?

Erich:この演習は2005年に行いました。ここでは、セッションからのメモをいくつか示します。それ以降、オブジェクト指向の設計原則とほとんどのパターンは変更されていません。分類を変更し、いくつかの新しいメンバーを追加して、パターンの一部を削除したかったのです。議論のほとんどは、分類を変更すること、特にどのパターンを削除するかについてでした。

どのパターンを落とすかについて話し合ったとき、私たちはまだそれらすべてを愛していることがわかりました。 (実際にはそうではありません。私はシングルトンを削除することに賛成です。その使用は、ほとんどの場合、デザインの匂いです。)

だからここにいくつかの変更があります:

  • InterpreterとFlyweightは、他のパターンとはまったく異なる獣であるため、「その他/複合」と呼ばれる別のカテゴリに移動する必要があります。 FactoryメソッドはFactoryに一般化されます。
  • カテゴリーは、コア、クリエーショナル、ペリフェラル、その他です。ここでの目的は、重要なパターンを強調し、使用頻度の低いパターンから区別することです。
  • 新しいメンバーは次のとおりです。Nullオブジェクト、タイプオブジェクト、依存関係注入、および拡張オブジェクト/インターフェイス(プログラム設計3のパターン言語の「拡張オブジェクト」、AddisonWesley、1997年を参照)。
  • これらはカテゴリでした:
    • コア:複合、戦略、状態、コマンド、イテレーター、プロキシ、テンプレートメソッド、ファサード
    • 作成:ファクトリ、プロトタイプ、ビルダー、依存性注入
    • 周辺機器:抽象ファクトリー、ビジター、デコレーター、メディエーター、タイプオブジェクト、Nullオブジェクト、拡張オブジェクト
    • その他:フライ級、通訳
3
akuhn

本の中の実際のパターンは時々本当に役に立つかもしれませんが、それらは本があなたに与えるより強力なツールの実例にすぎません:インターフェースによって分離され、規制されている独立した部分でモノリシックコードをカットしたほうがいいときと場所についての深い理解。

そのスキルを習得すると、実装しているソリューションをその目的に最適な方法でいつでもカットできるため、すべてのパターンの正確な詳細を覚えておく必要がないことに気付きます。したがって、ますます多くのパターンを書き留めるという考えは、非常に学術的で無意味なようです。

3
lud1977

したがって、既知の文書化された設計パターンの数が大幅に増加すると予想しました。

それは起こりませんでした。 GoFの本が出版されてから20年以上が経過しましたが、ウィキペディアの記事には12の追加パターンしかリストされていません。 (特定のトピックをカバーするため、ここでは同時実行パターンを含めませんでした。)

GoFブックとWikipediaだけが、既知のデザインパターンの唯一のソースではありません。 Amazon.comで「デザインパターン」を検索すると、数百冊の本が表示されます(これを試してください search )。私は彼らが Wikipediaの記事 で最もよく知られているパターンのみをリストしていると思います。

したがって、問題は十分に文書化された設計パターンがないことではありません。むしろたくさんあるので、誰もそれらをすべて覚えることはできず、ほとんどのプログラマーはほんの少ししか認識しません。共通パターン言語の大きな約束はこの時点で破綻します。

2
iluwatar