Понимание шаблонов проектирования и ООП в PHP - PullRequest
1 голос
/ 14 марта 2012

Я новичок в php и пытаюсь учиться.У меня есть 2 одинаковых класса.Я хочу создать эти объекты, когда я передаю количество и тип объекта.Я читал некоторые о заводском образце.Вот мой заводской класс:

    class AssetFactory
    {
        private static $table;
        public static $objects = array();
        public static function Create($asset,$count)
        {

            switch ($asset) {
            case "Item":
                self::$table = "items";
                break;
            case "Job":
                self::$table = "jobs";
                break;
            }
                $db = new Database();
                $rows = $db->query("SELECT * FROM ".self::$table." LIMIT ".$count);

                foreach($rows as $row)
                {
                    self::$objects[] =  new $asset($row);
                }

            return self::$objects;
         }
    }

и когда мне нужно 5 предметов, я использую:

  $myItems = AssetFactory::Create('Item',5);

, когда мне нужны рабочие места, я использую:

  $myJobs= AssetFactory::Create('Job',5);

предмет и работа - это те же классы.Мой вопрос здесь, как я уже сказал, я пытаюсь учиться.Я делаю это правильно?Правильно ли я понял фабричный образец?Есть хорошие документы по этому поводу (я прочитал все на php.net, получил что-нибудь еще).

Ответы [ 2 ]

6 голосов
/ 14 марта 2012

В этом случае мало что кажется неправильным.

Прежде всего, есть две подобные структуры, которые используются для создания объекта:

  • фабрики: если объекту требуется какая-то инициализация перед выпуском для «потребления»
  • строители: если перед созданием объекта вам нужно создать кучу других объектов

Обычно люди не делают различий между ними, а просто называют их "Фабрики". Так что это будет два случая, когда вы используете фабрику.

То, что у вас сейчас есть, не подходит под описание. Вы создаете какое-то соединение с базой данных, затем получаете некоторые данные и затем используете их для создания списка объектов. Это не код многократного использования.

Было бы намного лучше, если бы использование фабрики было примерно таким:

$connection = new PDO( .. blah.. );
$stmt = $connection->query( 'SELECT * FROM '.$type.' LIMIT '.$count );
$factory = new Factory;
$collection = $factory->buildCollection( $type, $stmt->fetchALL(PDO::FETCH_ASSOC) );

Конечно, с фабричным классом, который реализует это поведение.

Кроме того, вы можете посмотреть (при условии, что вы еще не видели) два видео на эту тему:

0 голосов
/ 14 марта 2012

Я далек от авторитета по шаблону проектирования фабрики, но я обычно делегирую инстанцирование подклассу.

<?php
class AssetFactory
{
    public static function Create($asset, $count)
    {
        $objects = false;

        switch ( strtolower($asset) ) {
            case 'item':
            case 'job':
                $class_name = 'Asset'.$asset;
                $asset_obj  = $class_name::getInstance();
                $objects    = $asset_obj->Create($count);
                break;

            default:
                // Invalid asset
                break;
        }

        return $objects;
    }
}

class Asset
{
    var $name                = null;
    var $table               = null;
    private static $instance = null;

    private function __construct() {}

    private function __clone() {}

    public function Create($count)
    {
        $objects = array();

        $db   = new Database();
        $rows = $db->query("SELECT * FROM ".$this->table." LIMIT ".$count);

        if ( is_array($rows) ) {
            foreach($rows as $row)
            {
                $objects[] = new Item($row);
            }
        }

        return $objects;
    }

    public static function getInstance()
    {
        if ( empty($self::$instance) ) {
            $class_name = __CLASS__;
            self::$instance = new $class_name();
        }

        return self::$instance;
    }
}

class AssetItem extends Asset
{
    private function __construct()
    {
        $this->name  = 'Item';
        $this->table = 'item';

        parent::__construct();
    }

}

class AssetJob extends Asset
{
    private function __construct()
    {
        $this->name  = 'Job';
        $this->table = 'job';

        parent::__construct();
    }

}
...