Разница между синглтоном и заводским паттерном - PullRequest
48 голосов
/ 19 января 2010

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

Ответы [ 6 ]

62 голосов
/ 19 января 2010

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

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

Цель фабрики - создавать и возвращать новые экземпляры. Часто они вообще не будут одного типа, но они будут реализациями одного и того же базового класса. Тем не менее, может быть много экземпляров каждого типа

20 голосов
/ 22 апреля 2013

Singleton

Один шаблон - это часто используемый шаблон во многих приложениях, когда требуется только один экземпляр ресурса. Наиболее очевидным типом ресурса для веб-страниц PHP является соединение с базой данных, хотя могут использоваться и другие типы ресурсов. При получении динамического создания веб-страницы может потребоваться выполнить несколько вызовов базы данных. Если вместо создания нескольких соединений можно использовать один экземпляр ресурса, накладные расходы минимизируются. Единственный экземпляр в этом случае создается шаблоном синглтона.

<?php
class db {
    /*** Declare instance ***/
    private static $instance = NULL;

    /**
     * the constructor is set to private so
     * so nobody can create a new instance using new
     */
    private function __construct() {
        /*** maybe set the db name here later ***/
    }

    /**
     * Return DB instance or create intitial connection
     *  @return object (PDO)
     * @access public
     */
    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new PDO("mysql:host='localhost';dbname='animals'", 'username', 'password');
            self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        return self::$instance;
    }
    /**
     * Like the constructor, we make __clone private
     * so nobody can clone the instance
     */
    private function __clone() {

    }
} /*** end of class ***/
?>

Давайте посмотрим, что произошло в синглтон-классе выше. Имя переменной $instance создано и сделано private, это никому не гарантирует и пытается получить к ней доступ напрямую. Точно так же методы конструктора и __clone стали частными, чтобы предотвратить клонирование класса или того, кто пытается создать экземпляр его экземпляра. У класса есть единственный метод для предоставления ресурса, метод getInstance().

Метод getInstance() проверяет, что экземпляр еще не существует. Если экземпляр не существует, создается новый экземпляр класса PDO и назначается переменной $instance. Если существующий экземпляр доступен, метод getInstance() возвращает это. В результате возвращаемое значение всегда является одним и тем же экземпляром, и новый ресурс или служебные данные не требуются.

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

<?php
try {
    /*** query the database ***/
    $result = DB::getInstance()->query("SELECT animal_type, animal_name FROM animals");

    /*** loop over the results ***/
    foreach ($result as $row) {
        print $row['animal_type'] .' - '. $row['animal_name'] . '<br />';
    }
} catch (PDOException $e) {
    echo $e->getMessage();
}
?>

Завод

Фабричный шаблон - это класс, который создает объекты для вас, а не вам нужно использовать новое ключевое слово для его создания. Фабрика, как следует из названия, фабрика для создания объектов. Почему нам это надо? Давайте рассмотрим приложение, которое использует файл ini для конфигурации. Затем приложение изменяется, чтобы получить параметры конфигурации из базы данных. Остальная часть приложения разваливается, как карточный домик, когда база удаляется. Эта " жесткая связь " объектов, где каждый объект сильно зависит от другого, создает проблемы в более крупных приложениях. Система необходима, когда объекты могут ссылаться друг на друга, но не являются взаимозависимыми.
В нашем примере файл конфигурации становится базой данных, если другие классы зависели от класса, считывающего из файла ini, и это неожиданно было поручено возникновению проблем с классом базы данных.
Используя шаблон проектирования фабрики, если вы измените тип объекта из класса считывателя ini на класс базы данных, вам нужно только изменить фабрику. Любой другой код, который использует фабрику, будет обновлен автоматически.

<?php
/**
 * @config interface
 */
interface Config {
    function getName();
}

/**
 * @config class
 */
class userConfig implements Config {
    /*
     * @username
     */
     public $user_id;

     /*** contructor is empty ***/
     public function __construct($id) {
        $this->user_id = $id;
     }

     public static function Load($id) {
        return new userConfig($id);
     }

     public function getName() {
         try {
             /*** query the database ***/
             $sql = "SELECT username FROM user_table WHERE user_id=:user_id";
             $db = db::getInstance();
             $stmt = $db->prepare($sql)
             $stmt->bindParam(':user_id', $this->user_id, PDO::PARAM_INT);
             return $stmt->fetch(PDO::FETCH_COLUMN);    
        } catch (PDOException $e) {
            /*** handle exception here ***/
            return false;
        }
    }
} /*** end of class ***/

/*** returns instance of config ***/
$conf = userConfig::Load( 1 );
echo $conf->getName();
?> 

Это может показаться немного чрезмерным кодом для простого получения имени пользователя. Но в крупномасштабном приложении, где выполняется переход от файла к поиску базы данных, результаты могут быть катастрофическими. Здесь просто вопрос изменения метода getName(), который возвращает имя, и возвращаемый объект такой же, что позволяет другим частям приложения, которым требуется имя пользователя, например, логин для корзины, продолжать работу, пока они делал ранее.

6 голосов
/ 28 января 2018
+---------------------------+-------------------------------+
|         Singleton         |            Factory            |
+---------------------------+-------------------------------+
| Returns Same instance     | Returns various new instances |
| Single Constructor hiding | Multiple Constructors expose  |
| No interface              | Interface driven              |
| No Subclasses             | Subclasses                    |
+---------------------------+-------------------------------+
5 голосов
/ 19 января 2010

Шаблон Singleton обеспечивает существование только одного экземпляра класса и, как правило, обеспечивает хорошо известную, т. Е. Глобальную точку доступа к нему.

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

3 голосов
/ 19 января 2010

Синглтон-шаблон - это шаблон, целью которого является обеспечение того, чтобы независимо от того, сколько раз клиент (или несколько клиентов) запрашивал экземпляр этого конкретного Типа для него (создавался), он всегда получал точно такой же один и только один экземпляр типа. Это гарантирует, что может быть создан только один экземпляр типа (например, если Type управляет кэшированной в памяти 200 МБ копией некоторой структуры данных - вам нужна только одна копия). Тип Singleton обычно имеет фабрику метод в нем, чтобы предоставить запрашивающим клиентам один и только один экземпляр.

Метод Factory - это метод, который инкапсулирует создание или создание экземпляра типа, так что сам тип имеет контроль над тем, как он создается.

0 голосов
/ 24 февраля 2015

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

...