4

このチュートリアルが PHP でファクトリ デザイン パターンを正しく実装しているかどうかを知りたいです。以下が実際のソースコードです。

<?php
class Automobile
{
    private $vehicle_make;
    private $vehicle_model;

    public function __construct($make, $model)
    {
        $this->vehicle_make = $make;
        $this->vehicle_model = $model;
    }

    public function get_make_and_model()
    {
        return $this->vehicle_make . ' ' . $this->vehicle_model;
    }
}

class AutomobileFactory
{
    public static function create($make, $model)
    {
        return new Automobile($make, $model);
    }
}

// have the factory create the Automobile object
$veyron = AutomobileFactory::create('Bugatti', 'Veyron');

print_r($veyron->get_make_and_model()); // outputs "Bugatti Veyron"

Gang of Fourの本「Design Patterns」によると、factory パターンの適用可能性は

  • クラスは、作成しなければならないオブジェクトのクラスを予測できません
  • クラスは、そのサブクラスが作成するオブジェクトを指定することを望んでいます
  • クラスがいくつかのヘルパー サブクラスの 1 つに責任を委任し、どのヘルパー サブクラスが委任されているかの知識をローカライズしたい

最初のポイントは、この例は、作成するオブジェクトのクラスを実際に知っているというAutomobileことです。

2 番目のポイントは、サブクラスがありません。Automobileクラスは から継承しませんAutomobileFactory。AutomobileFactory には、オブジェクトの作成を処理する Automobile によって実装される関数が少なくとも 1 つ必要であると考えました。

誰かがこれを明確にできますか?デザインパターンの学習を始めたばかりで、他のチュートリアルとは異なるチュートリアルに遭遇するたびに、とても混乱します。

4

4 に答える 4

3

ウィキペディアに書いてあることにほぼ同意

  • オブジェクトを作成すると、コードを大幅に複製することなく再利用できなくなります。
  • オブジェクトの作成には、構成クラス内に含まれてはならない情報またはリソースへのアクセスが必要です
  • 生成されたオブジェクトの有効期間管理は、アプリケーション内で一貫した動作を確保するために集中化する必要があります。

私が工場を作る主な理由は、私が強調したこの理由です。

たとえば、全国に多くの工場がある現実世界の工場を想像してみましょう。この工場はドアを生産しています。ドアにはノブが必要です。物流上の理由から、工場の各工場には独自のノブサプライヤーがあり、別の完全に別の工場です。

この工場の生産管理ソフトウェアは、いくつかの基準に基づいて、多くのドアを生産する工場を選択しますが、ノブがどこから来るかを知る必要はありません。選択された工場は、生産されたドアのノブを独自のサプライヤーに依頼します。

しかし、クライアントにとっては、どの工場がドアを作ったかは関係ありません。

これをコードに入れましょう:

class Knob {
    // something...
}

interface KnobSupplier {
    public function makeKnob();
}

class SaoPauloKnobSupplier {
    public function makeKnob() {
        return new Knob('Knob made in São Paulo');
    }
}

class NewYorkKnobSupplier {
    public function makeKnob() {
        return new Knob('Knob made in New York');
    }
}

class Door {
    public function __construct(Knob $knob) {
        // something...
    }
}

interface DoorFactory {
    public function makeDoor();
}

class SaoPauloDoorFactory {
    private $knobSupplier;

    public function __construct() {
        $this->knobSupplier = new SaoPauloKnobSupplier();
    }

    public function makeDoor() {
        return new Door($this->knobSupplier->makeKnob(), "Door made in São Paulo");
    }
}

class NewYorkDoorFactory {
    private $knobSupplier;

    public function __construct() {
        $this->knobSupplier = new NewYorkKnobSupplier();
    }

    public function makeDoor() {
        return new Door($this->knobSupplier->makeKnob(), "Door made in New York");
    }
}

class ProductionManager {
    private $plants = array();
    // methods for adding plants, etc...
    public function getDoor() {
        // Somehow decides which plant will create the door.
        return $plant->makeDoor();
    }
}

class Client {
    public function getMyDoor(ProductionManager $manager) {
        return $manager->getDoor();
    }
}

このコードを次のように使用します。

$manager = new ProductManager();
$manager->addPlant(new SaoPauloDoorFactory());
$manager->addPlant(new NewYorkDoorFactory());

$client  = new Client();

var_dump($client->getMyDoor($manager));

ProductManagerノブについてはClient何も知らず、複数の工場を持つ工場についても何も知りません。

于 2013-05-16T13:01:11.363 に答える
1

実際には、元の 4 つのカタログのギャングに続く 1 つの Factory Method デザイン パターンがあります。抽象ファクトリはまったく異なり、異なる構造的仮定に基づいています。Simple Factory は設計パターンではなく、Freemans が「プログラミング イディオム」と呼んでいるものです。Factory メソッドには抽象的な Creator と Product が含まれており、クライアントは通常、Creator を通じて要求を行います。特定のファクトリは ConcreteCreator にあり、具体的な製品は Product クラスの子クラスであり、具体的な作成者によってインスタンス化されます。完全で単純な PHP の例については、http: //www.php5dp.com/a-simple-php-design-pattern-the-factory-method/ を参照してください。

于 2014-01-11T13:03:22.983 に答える
1

私はキドンチュと一緒です、その例は伝統的なファクトリーメソッドのパターンとは思えません。

私はあなたの例をこのように書きます(疑似コード)

<?php

abstract class CarAbstract
{
    protected $_vehicleMake;
    protected $_vehicleModel;

    public function __construct($model)
    {
        $this->_vehicleModel = $model;
    }

    public function getMakeAndModel()
    {
        return $this->_vehicleMake . ' ' . $this->_vehicleModel;
    }
}

class Bugatti extends CarAbstract
{
    public function __construct($model)
    {
        parent::__construct($model);

        $this->_vehicleMake = get_class($this);
    }
}

class AutomobileFactory
{
    public static function getInstance($make, $model)
    {
        if (is_file('Model/Car/' . $make . '.php')){
            require_once 'Model/Car/' . $make . '.php';
            $car = new $make($model);
        }else{
            throw new Exception('Car not found');
        }
    }
}

$veyron = AutomobileFactory::getInstance('Bugatti', 'Veyron');

print_r($veyron->getMakeAndModel()); // outputs "Bugatti Veyron"
于 2013-05-16T11:59:49.543 に答える
1

私はチュートリアルがあまり好きではありません。工場に関するウィキペディアのページ ( https://en.wikipedia.org/wiki/Factory_pattern ) でわかるように、通常は別の方法で行われます。WikiPedia の例は、あなたが言及した規則に準拠しています。そこのPHPセクションをチェックしてください。

于 2013-05-13T14:28:19.723 に答える