1

私はphpでファクトリデザインパターンについて学んでいました。私が理解していることから、このパターンは、たとえばclass_1、class_2、class_3などのクラスがたくさんある場合に役立ちます。インスタンス化する必要がある特定のクラスが実行時にのみわかっている場合は、新しいものを使用する代わりにこれらのクラスのオブジェクトを作成する演算子を使用して、ジョブを実行するファクトリクラスを作成します。

ファクトリクラスは次のようになります。

class Factory
{
// $type will have values 1, 2, 3 etc.
public function create_obj($type)
{
  $class_name = "class_".$type;
  if(class_exists($class_name))
  {
        return new $class_name();
  } 
}
}

私の質問は、ここでファクトリクラスを使用することの利点は何ですか?物事を複雑にするクラスの代わりに、単純な関数を使用しないのはなぜですか?

4

4 に答える 4

2

コードスニペットのメソッドはファクトリメソッドではなく、よく知られたリフレクティブタスクを実行するヘルパーメソッドにすぎません。名前に基づいてクラスをインスタンス化します。これは、ファクトリパターンの目的とは正反対です。作成されるオブジェクトの正確なクラスを指定せずにオブジェクト(製品)を作成します。

ウィキペディアで説明されているように:

このパターンの本質は、「オブジェクトを作成するためのインターフェースを定義しますが、インターフェースを実装するクラスに、インスタンス化するクラスを決定させる」ことです。

おそらく、ファクトリパターンに関するウィキペディアの記事の最後のPHPの例に混乱しているかもしれませんが、それは悪い例です。意味のある例については、そのすぐ上のJavaの例を確認してください(これをPHPに変換しようとした人は、全体のポイントを逃しました)。Javaの例では、拡張子に基づいてファイルリーダーが返されます。これは、ファクトリパターンのユースケースです。特定のクラスに特定の名前のプレフィックスが必要であるという独自の「ルール」を作成することは、設計上の決定として不適切である可能性があります。

于 2013-01-30T16:44:07.927 に答える
1

質問の基本的なルートでは、単純な関数を使用して目標を達成できます。これが崩壊するのは、低結合度、高凝集度が必要なプログラマーのベストプラクティスです。

関数自体はアプリケーション設計で特別な役割を果たし、さまざまな役割と目的を持つ他の関数と一緒に配置することは、保守と読み取りが直感的ではありません。パターンは、プロジェクトドメインを通じて(ほぼ)普遍的に直面する一般的な問題を単純化するために使用され、その結果、パターンを区別するために、残りのコードベースからセグメント化される傾向があることを忘れないでください。

さらに、パターンを独自のクラスに配置することにより、パターンを使用する必要のあるクラスは、class_1 / 2/3/etcのクラス構造を知る必要がなくなります。代わりに、親クラスを参照するだけで、後でさらにクラスを作成し、残りのコードの依存関係やリンクを解決することなく、それに応じてパターンを変更できます。これは、低結合に結びつきます。

于 2013-01-30T14:56:15.937 に答える
1

コンセプトは、インターフェイスに合わせて設計し、後でクラスを交換できるようにすることです。

このパターンを少しの間忘れて、これを考慮してください:

if (type == "manager")
    employee = new manager();
else
    employee = new employee();

employee.name = "myname";

この場合、従業員とマネージャーは両方とも同じクラスから継承します。ifステートメントの後、それらを人のように扱うことができ、実際の実装から抽象化されます。いたるところにifステートメントを配置する代わりに、ファクトリパターンを実装できます。あなたがカップルしかない場合、パターンはおそらくやり過ぎです。将来、プログラムを簡単に拡張したい場合は、パターンを検討してください。

于 2013-01-30T14:58:15.060 に答える
1

ファクトリパターンを使用するもう1つの重要な理由は、デザインとコードにクラスを追加する必要があるときにコードがどうなるかを考慮することです。
ファクトリパターンを使用していない場合、コードはますます緊密に結合されるため、さまざまな場所で変更を加える必要があります。コードに触れる必要のあるすべての場所が、触れる必要のある他のすべての(密結合の)場所と調整されていることを確認する必要があります。 テストははるかに複雑になり、何かが壊れてしまいます。

ファクトリパターンは、結合を減らす方法を提供し、責任をほんの数か所にカプセル化するのに役立ちます。ファクトリパターンでは、クラスを追加することは、より少ない場所でコードに触れることを意味します。テスト(テストケースの作成とテストの実行)が簡素化されます。

現実の世界では、ほとんどのコードは「十分に」複雑であるため、ファクトリパターンの利点は明らかです。オブジェクトモデルを変更、改良、拡張し、急速な変化に直面してテストを可能な限り完全かつ厳密にし、コードを可能な限り非厳密にすることを保証します(すべて、複数の人が数ヶ月/数年の間にそれに取り組んでいます)-ファクトリパターンは通常、簡単です。

簡単な例では、ファクトリパターンを使用する利点を理解するのは難しい場合があります。(そして、あなたのコードが本当に些細なものであるなら、そのパターンはおそらくあなたをあまり買わないでしょう。)それは私がウェブでそれを検索するときに私が見る多くの例の問題です-例は焦点を合わせる傾向があります'あなたは決定することができます実行時のクラス!」と単純化されています。

これはそれほど些細なことではない1つの例であり、パターンの考えられるすべての利点について人々に考えさせると思います 。BobTarrによるファクトリパターンに関するプレゼンテーション(pdf)。(例2、10ページから始まります。)人が迷路と迷路内のすべての部屋を探索する必要がある迷路ゲームを書いていると想像してください。オブジェクトモデルには、ドア部屋などで構成される迷路が含まれ、それらすべてを追跡する必要があるマップもあります。十分に単純です。しかし、エンチャントされた部屋エンチャントされたドア魔法の窓を追加し始めるとどうなりますか話す写真ツイスティリトルパッセージ?すべてを表すために多くのクラスが作成されることになります。新しいクラスを追加するときに、できるだけ少ないコードを変更(タッチ)する必要があることを確認する必要があります。また、たとえば、新しいクラスを追加するたびにMapクラスのコードを変更する必要はありません。つまり、クラスが実際に責任を負うべきことに焦点を合わせたままにしておきたいのです。

実行時にインスタンス化されるものだけでなく、コードの複雑さについても考えてください。
彼はまた、UIコンポーネントでファクトリパターン(具体的にはファクトリメソッド)を使用する例を示しています。ここでは、ファクトリパターンが頻繁に表示されます。(初心者、またはUIコードを扱ったことがない人にとって、その例はそれほど明確ではないと思います。)

ほとんどのコーディングは既存のコードで行われることを忘れないでください。ほとんどの時間は、すでに存在するコードの変更に費やされます。コードが壊れることなく変更を処理できることを確認する必要があります。結合を減らし、責任をカプセル化することは、そうするのに大いに役立ちます。

于 2013-02-18T08:40:35.380 に答える