2011-12-31 12 views
4

私は初心者です。私はOOPの基礎を知っていますが、私はまだ "ベストプラクティス"を知らないのです。たとえば、プログラミングで引き続き出てくる1つのパラダイムは、「抽象的なファクトリ」デザインパターンです。これはかなり単純です。その背後にある主な目的の1つは、有害であると考えられるため、キーワード「新規」を避けることです。私はプログラミングで取ったコースでこれを聞いたことはありません。誰かがその点について詳しく説明できますか?なぜこの形のオブジェクトのインスタンス化を避けたいのですか?工場設計パターンとキーワード「新規」

答えて

8

はあなたが書いたあなたのクライアント/呼び出し側のクラスで考えてみましょう:

Vehicle v = new Car("BMW"); 

あなたのコードは、上記のいずれかのようであるならば、あなたはいつも車を取得します。将来、プレーンが実際に必要な場合は、クライアントコードを更新する必要があります。

また、あなたは工場出荷時のパターンを使用し、あなたが何かコード:

Vehicle v = Factory.getVehicle(); 

を今、あなたはクライアントから離れた車両を得るためのロジック(疎結合)を保つことができ、あなたのクライアントは必要ないだろうあなたが得る最終車両を更新する必要がある場合の変更。 Factory実装のみが更新され、クライアントはそのまま動作します。

+2

非常に良い応答!ありがとうございました;コードの再利用性を考慮すると意味があります。 – Sal

+1

これは良い答えであり、明らかに理解していますが、これも念頭に置いておいてください。私たちのほとんどがフレームワークで作業しています。ほとんどのコーディングは、非常にドメイン固有の社内LOBアプリケーション開発です。一般的なパーツは、データベースアクセスがLINQによって提供されるなど、フレームワーク内に通常存在します。 (一般的なフレームワークではなくドメイン固有のものをやっているときに)あなたのコードはできるだけシンプルで直接的でなければならないという考えの学校があります。 –

+0

@Peter:私は同意します。時には設計を過度に行うとコードが複雑になる傾向があります。あなたのアプリケーションでどのくらいのカップリングがOKかについていくつか考慮する必要があります。しかし、将来、アプリケーションが成長するのを見れば、スケーラビリティ/疎結合を保つという考え方を検討し、フレキシブルなデザイン(デザインパターンが役立つかもしれない)を維持することが大いに役立つでしょう。 – Nrj

0

私が知っている限り、新しいキーワードに間違いはありません。 ImはPHP開発者として話しています。新しいキーワードに間違いはありません。また、いくつかの証券問題もあります。

PHPのファクトリパターンは、自動的に要求し、クラスのインスタンスを作成し、そのクラスを返すために使用されます。新しいキーワードでは何か問題はありませんが、静的関数を1つ実行して必要なすべてのオブジェクトに新しいキーワードを使用するほうがはるかに高速です。

、バックグラウンドで、あなたはとにかく新しいキーワード:)新しいと間違っ

だから、何を使用して、それを避けるために必要はありません。ファクトリーパターンを使用すると、クラスインスタンスを取得してからクラスを取得し、新しいキーワードでインスタンス化することができます。

+3

これは本当にスピードの問題ではなく、疎結合と責任の分離(オブジェクトの使用から作成を分離)に関するものです。 – bobbymcr

+0

"new"を使うファクトリメソッドを "new"を使うよりも速く呼び出すのですか?それを裏付けるパフォーマンスデータがありますか? –

+0

いいえ、いいえ、私は言うより速く、サーバー上で実行されます。私は簡単に$ someClass = Factory :: produce( 'someClass')を呼び出すと言っています。そのようなコードを使用する方が速く、Factoryを使用してオブジェクト作成を管理するのが簡単です。何を言っているのですが、私はとにかく質問に答えませんでした。その男は何か他のものを探していた。 – Limeni

3

これまでのところ、newは有害であるとは言いません。抽象ファクトリパターンでは、newがオーバーライドできない(つまり、少なくともJavaやC#などの言語では仮想ディスパッチと互換性がない)という問題を解決しています。我々は前方いくつかのエンドポイントへの通信を可能にするために、基本インタフェースISendChannelを有し、このコードで

class Sender 
{ 
    private ISendChannel channel; 

    public Sender() 
    { 
    } 

    public void Connect(Uri endpointAddress) 
    { 
     // !! Sender is tightly coupled to TCP implementation 
     // !! even though it doesn't apparently have to be. 
     this.channel = new TcpSendChannel(endpointAddress); 
    } 

    /* ... */ 
} 

このサンプルコード(C#)を検討してください。しかし、与えられた実装は、何があっても常にTCPチャネルを使用するように固定されています。これは望ましいことではありません.HTTP送信者が必要な場合は、Senderクラスを変更するか、新しいメソッドを追加する必要があります。これは「悪いカップリング」です。

代わりに、ファクトリを使用してチャネルを作成し、それを送信側に渡すことができます。送信者は、工場にチャネルを作成し、その責任を放棄するように依頼します。新しい実装は次のようになります。

class Sender 
{ 
    private readonly ISendChannelFactory factory; 
    private ISendChannel channel; 

    public Sender(ISendChannelFactory factory) 
    { 
     this.factory = factory; 
    } 

    public void Connect(Uri endpointAddress) 
    { 
     // Sender does not have to care what type of channel it is. 
     this.channel = this.factory.CreateSendChannel(endpointAddress); 
    } 

    /* ... */ 
} 

HTTPチャネルを使用するために、あなたは、例えば異なる工場のタイプを使用して、送信者をインスタンス化できnew Sender(new HttpSendChannelFactory(/* ... */));HttpSendChannelFactoryは、そのCreateSendChannelメソッドからHttpSendChannelISendChannelに由来する具体的なタイプ)を返すことができます。

+0

細かいことをありがとう、ボビー。 – Sal

0

抽象的な工場パターンの考え方は、コンストラクタを含む具体的な実装については何も知りません。

したがって、標準のFactoryパターンは具体的なクラスを返します。

SomeType SomeVar = SomeFactory.CreateSomeType(); Abstract Factoryパターンが

SomeInterface SOMEVAR = AbstractFactory.CreateSomeInterface()であるように

したがって、消費者に公開されるSomeTypeの代わりに、インターフェイスのみが使用されます。工場の消費者がSomeTypeについて知る必要がないようにするために、すべての有益な、しかし唯一の有害な抽象概念の高レベル。

このパターンを理解することが
1

または何newキーワードを使用して間違っているあなたがProgramming against an interface

研究これで基本的な前提条件のプログラミングパラダイムが欠落している、あなたはそれが何であるかを理解すれば、あなたが唯一の方法にあることを理解するであろう実際にそれを強制する/それに従うことは、あなたのコードでnewを使用することを避けることです。すなわち、コード結合の厄介な効果を持つコード内の具体的なオブジェクトを明示的にインスタンス化します。

+0

多分私はこれについて詳細に読むべきです。私はその言葉が(コード結合)の周りにスローされたと聞いたが、私はその言葉がキャプチャしようとしているものを理解していない。それは単に不十分なrobustness/reusability/etcを参照していますか? – Sal

+0

カップリングがしっかりしているか緩いです。基本的には、あなたのコードがどのように相互依存するかの尺度です。あなたがXを変更した場合、Xに直接依存しない他のいくつの変更が強制されますか?あなたの質問では、抽象的なファクトリを使用して、抽象的な工場はより疎結合しています。 –

3

私はこの記事を読んでお勧め:http://www.codinghorror.com/blog/2005/09/head-first-design-patterns.html

重要な部分は、次のとおりです。簡単なコードを書くことを学ぶための最善の方法は、簡単なコードを記述することです!パターンは、あらゆる形態の複雑さのように、絶対に必要となるまで避けるべきです。これは、初心者が学ぶ必要がある最初のものです。最後のことではありません。

私はそれに同意します - 本当にが必要なときだけ工場が必要です。

[OK]をトピックに戻ると、キーワードnewは悪い可能性がありますが、ほとんどの場合、必ずしも頭痛の原因ではないし、そうでもありません。見てください

List <Person> persons = new ArrayList<Person>(); 

完璧です。工場をArrayListまたはLinkedListにすることを敢えて考えないでください。それは完全に強化されるだろう。

"たとえば、システムのすべてのオブジェクトが直接インスタンス化(たとえば、新しいStringNode(ノ))の代わりにファクトリを使用して作成された場合、システムは、おそらく工場の過剰を持っている。」ジョシュアKerievsky

@あなたはそれは良いアイデアだ、とあなたは十分な経験せずにそのことを確認することができないことを確認しない限り、早期のパターンを追加しないでください。種類:工場、これは素晴らしいです、私はそれを配置することができます参照してください! - これは良い考えではありません:)。あなたが感じるときに面倒なコード内の場所にパターンを追加する方が良いでしょう。パターンへのリファクタリングはです。

あり、それについての素晴らしい本がある、と私は私はそれが長いことを知っている

http://www.informit.com/articles/article.aspx?p=1398606&seqNum=2

「工場移動クリエーション知識」あなたは章にリンク与えるが、それは、それはですしてください読んであげます努力する価値があります。

関連する問題