Pythonのような動的言語で不要なデザインパターンはありますか?


98

GoFがデザインパターンブックを読み始めました。いくつかのパターンは非常に似ているように見えますが、概念的な違いはわずかです。

Pythonなどの動的言語では不要なパターンがいくつかあると思いますか(たとえば、動的機能に置き換えられるため)。


1
言語の選択がコード構造を効果的に代替できることを意味するため、一種の興味深い質問です。
joshin4colours

3
答えではありませんが、関連性があります-GoFのデザインパターンは、特定のパターンと同様に、それらから抽出できるいくつかの一般的な原則に関連していると思いました。私はパターンのアイデアを意味するわけではありませんが(確かに重要ですが)、単純なOOP原則に違反する特定の方法でクラスを使用する許可を増やすことです。たとえば、「シェイプ」が「自分自身を描画」しない、または少なくともジョブの一部を他のオブジェクトに委任しないパターンがたくさんあります。レッスンは、OOPをサポートするすべての言語で重要だと思います。
Steve314

非常に興味深い質問です。+1の代わりに+5ができたらいいのに。
MathAttack

1
でaslo概要言語機能欠けているデザインパターンデザインパターンは言語機能欠落している C2におけるオーバー。「動的言語」の問題でさえありません。最も単純な例は、Python、perl(および動的ではなくJava)でも些細なイテレータパターンです。

回答:


92

Peter Norvigは、GOFの本で見つかった23のデザインパターンのうち16 が動的言語で見えないか、より単純であることを実証しています(彼はLispとDylanに焦点を当てています)。

Pythonについて言及したので、Alex Martelliによるこのトピックに関する素晴らしいプレゼンテーションがあります。また、Pythonに関連して、慣用的なPythonの6つの設計パターンを示す素晴らしいブログ投稿があります。

また、Pythonで最も一般的なデザインパターンの実装(他の人による)とともにgithubリポジトリを保持しています。


すばらしいです!それは答えのスポットになります:)私は誰もが明確にその質問を理解していたことを望みました。
ジェレヌク

2
Norvigによると、16個のうち2個(インタープリターとイテレーター)は、マクロ(Pythonにはない)のために「非表示または単純」です。
mjs

1
Lispは、動的ではなく、なぜなら、そのような強力な関数型言語であることなど、他の機能であるため、すべてのこれらのパターンが必要とされていないことを私にはその明確ではない
JK。

@mjsイテレータは、Pythonの組み込み機能です。
サキスク

1
この偉大な答えは、少しでもやや無意味なリンクのキャプションを変更することで改善することができる実証しプレゼンテーションリポジトリ、彼らはその後、はるかに優れている- ここに :-) ...あなたが知っている、しかし
ウルフ

59

デザインパターンは必要ありません。どの言語でも。

私は、デザインパターンを読んで、それをあちこちで使うべきだと思う人々によって書かれた多くのコードに出くわす傾向があります。その結果、実際のコードは大量のインターフェース、ラッパー、レイヤーに埋もれてしまい、読みにくくなります。それはデザインパターンに対する間違ったアプローチです。

問題に遭遇したときに便利なイディオムのレパートリーが手元にあるように、デザインパターンが存在します。ただし、問題を特定する前にパターンを適用しないでください。シンプルに保つバカは常に優れた統治原則であるべきです。

また、設計パターンを、記述する特定の定型コードではなく、問題について考える概念として考えると役立ちます。また、Javaの回避策としてのボイラープレートの多くは、無料の関数と、それらを使用する他のほとんどの言語(Python、C#、C ++など)で使用する標準関数オブジェクトを欠いています。

私はビジターパターンを持っていると言うかもしれませんが、ファーストクラスの関数を持つすべての言語では、関数をとる関数になります。ファクトリクラスの代わりに、通常はファクトリ関数のみを持っています。私はインターフェースを持っていると言うかもしれませんが、それは他の実装がないため、コメントでマークされたいくつかのメソッドです(もちろん、Pythonではインターフェースは常にダックタイプであるため、単にコメントです)。私はまだパターンを使用するコードについて話します。それはそれを考えるのに便利な方法だからです。しかし実際に必要になるまですべてを入力しないでください。

したがって、すべてのパターンを概念として学びます。そして、特定の実装を忘れてください。実装はさまざまであり、現実の世界では、Javaでさえさまざまです。


28
あなたのオープニングステートメントは極端に単純化しすぎています。パターンにはコストがかかるのは事実です。そのため、盲目的に使用しないでください。しかし、適切な場所で、彼らは大きな助けになることができます。そして、はい、それらは言語固有です- 言語自体がより良いアプローチをサポートするため、一部の言語では一部のパターンが不要です。しかし、それはまだあなたのオープニングクレームからかなり遠いです。
ペテルトレック

2
Btw Visitorは、高階関数に完全に置き換えられているわけではありません-それはネイティブにサポートしていない言語(C#やC ++など)で二重ディスパッチを実装するためのソリューションです。(実際、非常に控えめに使用する必要があります-私がそれを使用するのが今まで使用したことがないことを正当化するのが非常に難しい最も難解で高価なパターンの1つだと思います。)
PéterTörök12年

14
まあ、あなたはパターンを必要としません。必要なのは問題解決することです。パターンのパターンがわからない場合でも解決できます。さらに考える必要があり、パターンに一致するソリューションと一致しないソリューションを考え出すことができます。パターンを知ることで簡単になります。
Jan Hudec

3
@Gerenuk:はい、しかし、ポイントは、パターンが言語固有ではなく、あなたの頭のためであることです。いくつかのパターンは、Pythonのさまざまなツールを使用してはるかに簡単に実現されることがよくありますが、通常は同じ概念が存在します。
ジャン・ヒューデック

4
@PéterTörök:訪問者は何にも置き換えられません。ポイントは、同じ概念が異なるケースで異なるツールを使用して実装される可能性があることですが、私はそれを同じパターンと考えています。
ジャン・ヒューデック

13

Pythonなどのアヒル型言語では、実際に言語に組み込まれているため、抽象ファクトリパターンは不要です。


10
まあ、まだ別の工場が必要です。インターフェイスの定義は必要ありません。
ステファノボリーニ

1
クラスがある場合は、すでにファクトリーがあります。クラスはファーストクラスのオブジェクトであり、あらゆる場所に渡して、オブジェクトを作成するために呼び出すことができます(Javaとは異なります)。他に何かを作成する必要はありません。デフォルトのコンストラクターではないものが必要な場合は、何らかの方法でコンストラクターをラップするラムダ/呼び出し可能オブジェクトを作成してください。
spookylukey

13

頭に浮かぶのは、シングルトンパターンだけです。

Pythonはすべてにクラスを使用することを強制しないため、代わりにグローバルデータ構造を使用することができます。そのグローバルデータ構造インスタンスで管理できますが、そのクラスのインスタンス化を制御する必要はありません。インポート時にインスタンスを作成し、そのままにしておきます。

ほとんどの場合、Pythonのシングルトンはモジュールに置き換えられます。Pythonのモジュールは、本質的にシングルトンです。Pythonインタプリタはこれらを一度だけ作成します。

私がPythonで使用したデザインパターンの他のすべてのパターンは、Python標準ライブラリ全体およびPython自体で使用されています。


2
これは最近のアンチパターンではありませんか?
デン

16
シングルトンはアンチパターンです。すべての言語で。いくつかの無関係な問題を解決するために作成されましたが、どちらにも適していません(Javaにもクラスごとに1つ存在する静的メンバーがあるため、そのためのインスタンスは不要です)。
Jan Hudec

1
また、Pythonでは、解決すべき問題がなかったので、それを気にしませんでした。
マルタインピータース

1
「Pythonは、あらゆるものにオブジェクトを使用することを強制しません」真実ではありません。Javaのように不快ではありませんが、それでもPythonではすべてがオブジェクトです。モジュールでさえオブジェクトです。
バルテック

3
@ダースフェット:私はどのようにlen機能するかをよく知っています。Guidoはここで明示的な選択をしました。私のポイントは、Pythonが純粋なOOP言語ではないことを示すことです。それは実用的な言語です。それが好き。
マーティンピーターズ

8

設計パターンはプログラマー向けであり、言語向けではありません。プログラマーは、目前の問題を理解するのに役立つパターンを使用する傾向があります。設計パターンは厳密には必要ありませんが、やろうとしていることを単純化するのに役立つかもしれません。

Python、特にカモタイピングは、多くの一般的なパターンと慣行の終わりを提供し、いくつかのパターン(プライバシー、不変性など)によって課せられた多くの制限は、プログラマがそれらを壊さないことに同意する範囲でのみ保持します。しかし、まだ、彼らがない限り、プログラマが一緒に果たしているとして働いています。ドアは、たとえ想像上の壁で囲まれていても、依然としてドアです。

Pythonは「マルチパラダイム」言語と見なされます。好きなパターンを使用できます。これは意図的なものです。たとえば、完全に不要で少し人工的なものであるにもかかわらず、複雑なクラス階層を提供します。しかし、一部の人々にとっては、特定の抽象化が役立つことです。問題がそれを要求しているからではなく、プログラマが要求しているからです。それであなたは行き​​ます。


それは確かに興味深いです。それでは、Pythonにはもっと良い方法があるので、特にどのパターンを忘れるのでしょうか?
ジェレヌク

4

オリジナルの「デザインパターン」の本は、C ++やSmalltalkなどの命令型のオブジェクト指向言語で役立ついくつかの一般的なイディオムを文書化し、命名しました。しかし、Smalltalkは動的に型付けされた言語であるため、厳密に動的であるということはできません。

ただし、あなたの質問に対する答えは依然として「はい」です。これらのデザインパターンの一部は、現代の動的に型付けされた言語とは無関係です。より一般的には、異なる言語、特に異なる種類の言語では、異なる設計パターンが存在します。

繰り返しになりますが、「設計パターン」とは単にプログラミングのイディオムの名前であり、頻繁に発生する問題の一般的な解決策です。言語ごとに異なるイディオムが必要です。1つの言語の問題は別の言語では些細なことかもしれないからです。この意味で、設計パターンは、適用する言語の弱点を指摘する傾向があります。

したがって、現代の動的言語(またはLispのような古代の言語)をより強力にし、これらの古典的なデザインパターンのいくつかを無関係にする他の機能を探すかもし​​れません。


1

デザインパターンは、特定の問題を解決する方法です。問題が満たされない場合、それを解決するパターンは役に立ちません。

人々は、プロジェクトにデザインパターンを含めることがベストプラクティスであるかのように、デザインパターンをあらゆる場所で適応しようとしています。それは別の方法です。工場出荷時のパターンで解決できる問題が発生しましたか?クール。それを適応させます。コードを調べて、シングルトン(またはファクトリー、ファサード、その他)を実装する適切な場所を見つけようとしないでください。

おそらくPythonには、Javaと.NETの人々には利用できない独自のデザインパターンがあります(これらの言語の性質のため)?


1

パターンは常に言語に依存していると思います。ほとんどのpythonパターンはGoFで定義されたもののように見えますが、それはPythonのOOPのためです。

そのため、一部のパターンは「そのまま」適用できず、一部は意味をなさない可能性があり、Pythonにとってのみ意味のあるパターンもあります。

あなたの質問に正確に戻って取得するには:あなたがいる場合のパターンにのみ必要です必要にそれらを。それらの必要がない場合は、それらを使用する必要はありません(Jan Hudecが既に述べたように)。

さらに、GoFで言及されているものよりもはるかに多くのパターンがあります。ウィキペディアで他のパターンを見る

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