最悪または最も厳密に定義されている設計パターンは何ですか?[閉まっている]


28

すべてのプログラミングプロジェクトについて、過去のプログラミング経験のあるマネージャーは、プロジェクトのデザインパターンを推奨するときに輝かそうとします。理にかなっている場合、またはスケーラブルなソリューションが必要な場合、デザインパターンが好きです。たとえば、プロキシ、オブザーバー、コマンドパターンを積極的に使用してきましたが、毎日そうしています。しかし、オブジェクトを作成する方法が1つしかない場合、Factoryは将来的にすべてを簡単にする可能性がありますが、コードを複雑にし、純粋なオーバーヘッドであるため、Factoryパターンを使用することを本当にためらっています。

だから、私の質問は私の将来のキャリアと、ランダムなパターン名を投げるマネージャータイプに対する私の答えです:

どのデザインパターンを使用しましたか?最悪の設計パターンはどれですか、それらが理にかなっている単一の状況を除いて考慮する必要があるものです(読んでください:どの設計パターンが非常に狭く定義されています)?(アマゾンの全体的な良い製品のネガティブなレビューを探して、デザインパターンを使用する際に最もバグを起こした人々を探しているようです。)そして、ここでアンチパターンについてではなく、通常と考えられるパターンについて話しています「良い」パターン。

編集:一部の人が答えたように、問題はほとんどの場合、パターンが「悪い」のではなく「間違って使用されている」ことです。パターンを知っていれば、それはしばしば誤用されるか、使用するのが難しい場合でも、答えとして当てはまります。


ほとんどのパターンは、一部の変更軸で将来の変更を容易にしますが、他の変更軸で変更をより難しくすることができます。4人組のギャングは、パターンが適用される場合に特に優れています。パターンに関するその後の多くの本は、この点を見逃しています。例として、訪問者パターンを取り上げます。新しいツリートラバーサルアルゴリズムを簡単に追加できますが、新しい種類のノードをツリーに追加するのが難しくなります。また、トラバーサルアルゴリズムをツリーよりも上位のレイヤーにすることができます。どの変化軸が最も安定していないかを考慮し、その軸に沿った変更を容易にするように設計する必要があります。
セオドアノーベル

「ギャングオブフォー」の本のすべて。
マイルルーティング

回答:


40

私は悪いパターンを信じていません、私はパターンがひどく適用されることができると信じています!

  • 私見シングルトンは、最も乱用され、最も誤って適用されたパターンです。人々はシングルトン病にかかっているようで、代替案を考えずにどこでもシングルトンの可能性を見始めています。
  • 私見の訪問者パターンは最も狭い用途を持ち、追加された複雑さが正当化されることはほとんどありません。ここで素晴らしいPDFを入手できます。事前にすべての方法を知らずに、データ構造に対してさまざまな操作を行いながら、横断することがわかっているデータ構造がある場合にのみ、ビジターパターンに戦いのチャンスを与えます。それはかなりですが:)

この回答では、GOFパターンのみを考慮しました。考えられるすべてのパターンを十分に把握していないので、それらを考慮することもできません。


訪問者の用途はほとんどありません。シングルトン...始めてはいけません。状況が完璧でない場合は、使用しないでください。
マイケルK

1
Visitorの用途はほとんどないかもしれませんが、ある場合は確かに問題を解決します。私の理解では、VistorはLINQに不可欠です。
クエンティン・スターリン

12
訪問者パターンは、ソフトウェアプログラムの循環的な複雑さを軽減(または排除)するために重要です。if / elseツリーまたはswitchステートメントがある場合は常に、訪問者がそれらを置き換えることができる可能性が高く、実行とコンパイル時のチェックが保証されます。訪問者は、私が知っている最も強力なパターンの1つであり、定期的に非常に効果的に使用しています。テストも夢になります。
レヘーズルウッド

@LesHazlewoodその場合、訪問者は不適切なプログラミング言語の回避策だけではありませんか?MLのような言語(Haskell、SML、OCamlなど)には、代数的データ型(「ステロイドの結合」)とパターンマッチング(「ステロイドの切り替え」)があります。ビジターと比較すると、オブジェクトプロパティを介して手動で管理する必要がある共有状態のメソッドは多くありません。MLに似た言語では、すべてのケースの区別は完全でなければなりません。そうでないとコンパイルされません。
vog

14

他の回答者によって既に言及されたシングルトンとビジターは別として、私は「悪名高い」デザインパターンを知りません。私見最大の問題は、特定の設計パターンが「間違っている」ことではなく、開発者がパターンをあまりにも熱心に適用していることに起因しています。

ほとんどの人は、パターンに慣れるときに「パターンフィーバー」フェーズを通過します。パターンはスライスされたパン以来の最良のものであると考え、最初は、可能性が見えるときはいつでもパターンを適用しようとします。その結果、コードはパターンの下に埋もれてしまいます。パターン自体はもはや役に立たず、コードを長期的に理解し、維持するのが難しくなります。

最終的に、私たちのほとんどはこのフェーズを乗り越え、パターンを使用して実際の問題を解決する方法を学び始めます。パターンには価格があり、複雑さを増します。特定のパターンを適用することは、システムの他の部分を単純化するのを助けることにより、追加された複雑さを回収する場合にのみ正当化されます。そうでない場合は、パターンから離れて、おそらく機能する可能性のある最も単純なソリューションにこだわる方がよい場合がよくあります。


絶対に。パターンは良いものでも悪いものでもありません。うまく適用されたり、誤って適用されたりします。

私はむしろ、私が学んだ方法を人々に教えたいです。まずオブジェクト指向、オブジェクトの関連性を理解してから、パターンの名前を学びます。パターンの観点から考えるのは、やるべきことよりも簡単です。それらはコミュニケーションツールです。
マイケルK

パターンはコミュニケーションの手段であり、規範的なリストではありません。あなたがいる場合開始念頭に置いパターンで、あなたはそれをmisapplyingすることができます。デザインで1つ、または1つのヒントを見つけた場合、パターンカタログは他に何が必要かを理解するのに役立ちます。
ロブクロフォード

14

ここで手足に出て、継承の使い過ぎを提案します。Javaのように、コンパイル時の多態性をしっかりサポートしていない言語で間違いなく最も適用可能 実行時継承はツールであり、ある種の機能をすべて備えているのも不思議ではありません。

私のシングルトンに対する嫌悪感に似ている人たちがすでに他にもいるので、ここでこれを拡大するつもりはありません。


10

シングルトン。現在ではアンチパターンと呼ばれることが多いGOFパターンがあります。その理由の1つは、シングルトンによりコードのテストがより困難になることです。


4
シングルトンパターンには多くの基本的な欠陥があり、そのほとんどは、スティーブイェッジ- シングルトンと見なされる愚かさ
-ocodo

Slomojo:素敵な記事。私は上の今から「阿呆パターン」それを呼び出すつもりだ:-)
誰も

2
はい、一部の愚か者はパターンを誤用し、OOが何であるかについてボートを完全に見逃しているため(彼が思いついたすべてのManagerクラスによる判断)、もちろんそれは開発者ではなくパターンのせいです。
ダンク

なぜ誰もがシングルトンの一般的な(面倒な)実装をシングルトンパターンに関連付けるのですか?1つはほとんど常に悪いもので、もう1つはそうではありません。
クエンティン・スターリン

1
@qes>シングルトンは、重要な実装の問題を引き起こします(特にスレッド化に関して)。これはすでに悪い点です。しかし、シングルトンは、クラスがどのように訴えられるかに関するパターンであり、どのように機能するかではないこともわかります。クラスの使用方法は、そのクラスを使用するコードで処理する必要があります。そのため、シングルトンは懸念事項の分離を壊します。
-deadalnix

7

パターンを知っていれば、それはしばしば誤用されるか、使用するのが難しい場合でも、答えとして当てはまります。

この質問で示されているように、WPFMVVMパターンに厳密に従ってください。一部の人々は、コードをコードビハインドウェイに厳密に入れてはならないというガイドラインに従い、あらゆる種類のエキゾチックなハックを考え出そうとしています。

そしてもちろん、MVVMは非常に難しく、小規模な短期プロジェクトには価値がありません。

WPF博士は彼の記事MV-pooでそれについて皮肉な投稿をしました。


@Akku:もちろん、その使用方法を知っておく必要があります。そのため、プロジェクトに適しているかどうかを判断できます。はい、それはWPF開発に不可欠であり、非常に便利です。
スティーブンジュリス

問題の1つは、人々がMVVMパターンを誤解していることです。「地獄のように難しい」わけではありません。人々は、コマンドパターンやメディエーターパターンなどの他のすべてのパターンがその一部であると考えて、そのようにします。私の意見では、MVVMはそれ自体が最も単純なパターンの1つです。私は、tに何かに従うことはばかげていることに同意します。
BK

5

GOFブックのパターンの一部はC ++固有です。つまり、リフレクションを使用する言語ではあまり適用されないという意味で、たとえばJavaではPrototypeパターンはそれほど重要ではありません。

Interpreterパターンは「狭い」パターンだと考えています。一般的な問題解決者を開発する価値がある一般的な問題を抱えている必要があります。言語を発明し、文法を定義し、インタプリタを書くことができる特別な問題に対してのみ機能します。問題のインスタンスは、文法の文として表現可能でなければなりません。そのような状況に頻繁に出会うとは思わない。


1
GOFのほとんどは、静的クラスベースのOOPにのみ適用できます。その種の言語からほんの少し外れ、本は単なる娯楽の逸話になります。
ハビエル

5

私が最も後悔しているのは(最も激しくはありませんが):関数を作成したばかりで、OOPソリューションを実装したときです。


1
どうして?何が後悔したのですか?答えを広げて、経験を追加してください。
ウォルター

実際、ローカル変数と明確なメソッドを持つクラスは、コピーペーストでのみ再適用できる200行の単一関数よりも再利用がはるかに簡単で、thenくてわかりにくい場所が1つしかないと思います。
-Akku

2
KISSは、まず関数にした後、必要に応じてクラスにリファクタリングすることを意味します。
エヴァ

5

工場。1つのタイプのみを作成するコードを実装するコードを見てきました。これは完全に無駄なコードIMOです。オンラインの例の多くが完全に考案されていることは役に立ちません。ピザ工場?

おそらく、ファクトリーは依存性注入のためにテストが簡単です。しかし、必要でないときにそのコードを追加するのは無意味であり、JMockitのようなモックフレームワークを使用できるようになると、テスト引数は消えます。プログラムを簡単に作成できるほど、より良い結果が得られます。ファクトリは、より多くのタイプの場合にのみ意味があります(大きくすると、少なくとも2つ以上を意味します)。


はい、ピザ工場、ヘッドファーストデザインパターンに感謝〜
Niing

2

シングルトン

私はシングルトンについて他の人に同意します。決してそれらを使用してはいけないということではなく、ごく少数のケースに限定すべきだということです。それらは、多くの場合、遅延グローバルとして使用されます。

スレッドセーフはシングルトンの1つの問題です。例外処理は別です-シングルトンが適切に作成できない場合-特にメインの前に作成されたオブジェクトの場合、安全にエラーをキャッチできるかどうかは必ずしもわかりません。そして、その後のクリーンアップの問題があります。

私は1つのシングルトンを使用し、他のすべての「志望」シングルトンにあなたのシングルトンを「サブスクライブ」させる傾向があります。私の最も一般的なシングルトンの使用法は、「シャウトイベント」処理です。イベントが発生したことを「世界にブロードキャストする」だけで、イベントを処理するリスニングを行う人は誰でもそうします。そうすることで、実際に起こっているイベントを、それらを聞いているものと切り離すことができます。(ロギング、シグナルなど)

ビジター

開発者が意味のある名前を考えることができず、メソッドvisit()を呼び出すことができないという事実を除けば、これについて私が見つけたいことは、別の方向にそれを削除しながら、一方の方向に拡張性を追加することです。訪問者が訪問する可能性があるすべてのオブジェクトタイプについて知る必要があるオブジェクトの数。

面倒ですが、両方向の拡張を許可することは可能ですが、これは通常の形式でビジターパターンを完全に使用するわけではありません。このための最も一般的なアプリケーションは、オブジェクトの印刷です。オブジェクトを印刷するさまざまな方法と、印刷する必要のあるさまざまなオブジェクトがあります。これを両方向に拡張できるはずです。(印刷とは、オブジェクトをストリームに変換するあらゆる種類のことです。ファイルに保存する/コンソールに書き込む/ GUIなど)。

(注:これをドキュメントビューアーキテクチャと混同しないでください。これはわずかに異なるパターンです)。


2
ソリューションでは、物事の引数を分離する古いものを使用します。特に、イベントを投稿すると、他の誰かがイベントを処理して記録します。みんなが切り離されているので、それは良いことです!違う!私はかつてそれをやった、それは王室の痛みになった。何かをログに記録したい場合は、この正確なことを、今ここで、発生した時点のコードに明示的に記録したいことがわかりました。他のオブジェクトが、何をログに記録する必要があるかを把握し、他のイベントが記録されている場合でも、他のハンドラーによって他のイベントが挿入されることはありません。それは複雑な過剰設計に他なりません。
ダンク

2

より複雑なパターンのいくつかの問題は、それらに非常に多くのバリエーションがあるため、通信デバイスとしての価値の多くを失うことだと思います。

このカテゴリで考えられる最悪の犯罪者は、MVCパターンです。MVPを無視しても、これらの各項目の役割には非常に多くのバリエーションがあるため、境界がどこにあるかを把握するために、新しいフレームワークごとに1時間を費やす必要があります。


また、MVCはどこでも使用すべきですが、どこでも同じ方法で実装すべきではないと思います。そして多くの人はそれを理解していません。初めて使用したいときは、Model、View(Windowsフォーム)、Controllerという3つのクラスを作成しました。MVC用のフォームが作成されなかったため、混乱しました。
Akku

1

悪い人だけに悪いパターンはありません。

私はむしろ明確な何かをするが、いくつかのミッシュマッシュよりも少し冗長か(キュー悪villian音楽)再利用可能(息をのむ!)で読みやすいコードを継承したいですInheritAbstractTemplateFaucetSink<Kitchen>

再利用可能なコードは素晴らしいです!再利用されるコードを書いたり、別のアプリケーションの類似のロジックを書き直したりすると、他のアプリケーションのコードを再利用しようとする異常な試みよりも時間がかからない可能性があります。

さらに読むために、posixヘッダーまたはclibsの正常な実装のCコードの一部を開いて、パターンを見つけてください。このコードは、世界で最も優秀で熱心なプログラマーによって作成されました。表示される抽象ファクトリパターンの数を知っていますか?... なし!。さらに良い可能性は、起こっていることの他の部分を理解すれば、ロジックの理解と追跡が非常に簡単になることです。

私のポイントは、ほとんどの「パターン」は、書籍やモデリングソフトウェアを販売するために作成されたコードを改善するために作成されたものではないということです。プログラミングが得意であれば、おそらくこれらのほとんどを避け、問題を解決する明確で簡潔で巧妙に設計されたコードを書くでしょう。別の問題がある場合は、その問題を解決するために、明確で簡潔な、巧妙に設計されたコードを作成します。あなたの目標がプログラマよりも少ないコードを書くことであるなら、私はあなたがプログラマーであると断言しないと思うでしょう。私はコードを書くのが大好きで、できる限りそれを書きたいと思っています。すでに書いたものを書き直すとき、私はそれを何十倍も速くし、最初にやったことで満足していなかったすべてのものを取り除きます。

それで、おそらくコンピュータサイエンスで最高の(関​​連する)引用を残します。

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

  • Tony Hoare(クイックソートの発明者、現代のOSデザインの父、Hoareロジックの作成者、Turing賞受賞者)

0

ほとんどのパターンには時間があり、多くのパターンを悪用できることは間違いありません。過去に最も悪用したのは、Abstract Templateパターンです。ASP.NET Webフォームとして知られているすべてを網羅しています。

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