Что такое шаблон заводского дизайна в PHP?


Это смущает меня, в самых простых терминах, что он делает? Представьте, что вы объясняете своей матери или кому-то почти пожалуйста.

9 81

9 ответов:

фабрика создает объект. Так что, если вы хотите построить

 class A{
    public $classb;
    public $classc;
    public function __construct($classb, $classc)
    {
         $this->classb = $classb;
         $this->classc = $classc;
    }
  }

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

$obj = new ClassA(new ClassB, new Class C);

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

class Factory{
    public function build()
    {
        $classc = $this->buildC();
        $classb = $this->buildB();
        return $this->buildA($classb, $classc);

    }

    public function buildA($classb, $classc)
    {
        return new ClassA($classb, $classc);
    }

    public function buildB()
    {
        return new ClassB;
    }

    public function buildC()
    {
        return new ClassC;
    }
}

теперь все, что нам нужно сделать, это

$factory = new Factory;
$obj     = $factory->build();

реальное преимущество, когда вы хотите изменить класс. Допустим, мы хотели пройти в другой ClassC:

class Factory_New extends Factory{
    public function buildC(){
        return new ClassD;
    }
}

или новый ClassB:

class Factory_New2 extends Factory{
    public function buildB(){
        return new ClassE;
    }
}

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

хорошим примером может быть этот класс пользователей:

class User{
    public $data;
    public function __construct($data)
    {
        $this->data = $data;
    }
}

в этом классе $data - это класс, мы используем для хранения наших данных. Теперь для этого класса, скажем, мы используем сеанс для хранения наших данных. Фабрика будет выглядеть так:

class Factory{
    public function build()
    {
        $data = $this->buildData();
        return $this->buildUser($data);
    }

    public function buildData()
    {
        return SessionObject();
    }

    public function buildUser($data)
    {
        return User($data);
    }
}

теперь вместо того, чтобы сказать, что мы хотите сохранить все наши данные в базе данных, это действительно просто, чтобы изменить его:

class Factory_New extends Factory{
    public function buildData()
    {
        return DatabaseObject();
    }
}

фабрики-это шаблон проектирования, который мы используем для управления тем, как мы собираем объекты вместе, и использование правильных заводских шаблонов позволяет нам создавать индивидуальные объекты, которые нам нужны.

как реальная фабрика жизни, она создает что-то и возвращает его.

представьте себе, что-то вроде этого

$joe = new Joe();
$joe->say('hello');

или заводским методом

Joe::Factory()->say('hello');

реализация метода factory создаст новый экземпляр и вернет его.

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

давайте разберем это в другой раздел.

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

ему просто нужно беспокоиться об использовании методов вашего класса.

например, у вас есть две базы данных для вашего проекта

class MySQLConn {

        public function __construct() {
                echo "MySQL Database Connection" . PHP_EOL;
        }

        public function select() {
                echo "Your mysql select query execute here" . PHP_EOL;
        }

}

class OracleConn {

        public function __construct() {
                echo "Oracle Database Connection" . PHP_EOL;
        }

        public function select() {
                echo "Your oracle select query execute here" . PHP_EOL;
        }

}

ваш класс завода будет заботиться о создании объекта для подключения к базе данных.

class DBFactory {

        public static function getConn($dbtype) {

                switch($dbtype) {
                        case "MySQL":
                                $dbobj = new MySQLConn();
                                break;
                        case "Oracle":
                                $dbobj = new OracleConn();
                                break;
                        default:
                                $dbobj = new MySQLConn();
                                break;
                }

                return $dbobj;
        }

}

пользователю просто нужно передать имя типа базы данных

$dbconn1 = DBFactory::getConn("MySQL");
$dbconn1->select();

выход:

MySQL Database Connection
Your mysql select query execute here

в будущем у вас может быть другая база данных, тогда вам не нужно менять весь код, нужно только передать новый тип базы данных, а другой код будет работать без каких-либо изменений изменения.

$dbconn2 = DBFactory::getConn("Oracle");
$dbconn2->select();

выход:

Oracle Database Connection
Your oracle select query execute here

надеюсь, что это поможет.

В общем случае " фабрика "производит что-то: в случае объектно-ориентированного программирования" фабричный шаблон проектирования " производит объекты.

это не имеет значения, если это в PHP, C# или любой другой объектно-ориентированный язык.

заводская модель дизайна (заводская модель) предназначена для свободного соединения. Как и значение фабрики, данные на фабрику (производят данные) для конечного пользователя. Таким образом, завод разрывает плотную связь между источником данных и процессом обработки данных.

фабрика просто генерирует объект или объекты.

У вас может быть фабрика, которая строит соединение MySQL.

http://en.wikipedia.org/wiki/Factory_method_pattern

этот ответ относится к другому сообщению, в котором Даниэль Уайт сказал использовать factory для создания соединения MySQL с использованием заводского шаблона.

для подключения MySQL я бы предпочел использовать одноэлементный шаблон, поскольку вы хотите использовать одно и то же соединение для доступа к базе данных не создавать еще один.

классический подход к созданию экземпляра объекта:

$Object=new ClassName();

PHP имеет возможность динамически создавать объект из имени переменной, используя следующий синтаксис:

$Object=new $classname;

где переменная $classname содержит имя класса, который нужно создать.

таким образом, классический факторинг объектов будет выглядеть так:

function getInstance($classname)
{
  if($classname==='Customer')
  {
    $Object=new Customer();
  }
  elseif($classname==='Product')
  {
    $Object=new Product();
  }
  return $Object;
}

и если вы вызываете функцию getInstance ('Product'), эта фабрика создаст и вернет объект продукта. В противном случае, если вы вызов функции getInstance ('Customer') эта фабрика создаст и вернет объект типа Customer (созданный из класса Customer ()).

в этом больше нет необходимости, можно отправить "продукт" или "клиент" (точные имена существующих классов) в качестве значения переменной для динамического экземпляра:

$classname='Product';
$Object1=new $classname; //this will instantiate new Product()

$classname='Customer';
$Object2=new $classname; //this will instantiate new Customer()

для записи, в простых словах, фабрика, как @Pindatjuh сказал, возвращает объект.

Так в чем же разница с конструктором? (что делает то же самое)

  1. конструктор использует свой собственный экземпляр.
  2. что-то я хочу, чтобы что-то более продвинутое, и я не хочу раздувать объект (или добавлять зависимости).
  3. конструктор вызывается при создании экземпляра. Иногда ты этого не хочешь.

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

С помощью конструктора:

class Account {
      var $user;
      var $pwd;
      var ...
      public __construct() {
         // here i read from the file
         // and many other stuff
      }
}

С помощью фабрики:

class Account {
      var $user;
      var $pwd;
      var ...
}
class AccountFactory {
      public static Create() {
         $obj=new Account();
         // here we read the file and more stuff.
         return $obj;
      }