ФорумПрограммированиеПыхнуть хотите?F.A.Q. → Немножечко о паттернах или то, что должен знать каждый программист

Немножечко о паттернах или то, что должен знать каждый программист

  • NRG

    Сообщения: 4761 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 1:25

    Singleton
    В этом паттерне название говорит само за себя, singleton(single = единственный).
    Т.е. паттерн должен реализовывать функционал единоразового создания обьекта.
    Для чего это надо ? А для того чтобы не плодить обьекты.
    Итак рассмотрим типичный пример синглтона :

    <?php 
    class NRG_Singleton
    {
        // переменная в которой мы будем хранить сущность текущего класса
        private static $instance;
        
        // конструктор обьявлен приватным для того чтобы избежать попытки прямого создания обьекта
        private function __construct() 
        {}

        // метод который реализовует всю логику
        public static function singleton() 
        {
            if (!isset(self::$instance)) {
                $c = __CLASS__;
                self::$instance = new $c;
            }
            return self::$instance;
        }

        // для особо хитрожопых
        public function __clone()
        {
            trigger_error('Нельзя. Онотоле не одобрям.', E_USER_ERROR);
        }
    }


    Даный пример кода позаимствован с мана
    http://www.php.ru/manual/language.oop5.patterns.html#language.oop5.patterns.singleton

    В этом примере все просто. Обьект NRG_Singleton мы можем создать только через вызов статического метода singleton(). И суть данного метода в том что «реально» обьект создастся только один раз ( при самом первом вызове метода singleton() ), а все последующие разы метод будет возвращать уже готовый обьект.




    Registry
    Ну по названию этого паттерна я думаю что тоже не сложно догадаться что он делает. =)
    Ну а для тех кто всетаки не догадался, то скажу по секрету, он регистрирует.
    Вот типичный примерчик для такого паттерна:

    <?php 

    class NRG
    {
        // наше чудо-хранилище
        static private $_registry = array();

        // чудо-метод который извлекает данные из хранилища
        public static function registry($key)
        {
            return (isset(self::$_registry[$key])) ? self::$_registry[$key] : null;
        }

        // чудо-метод который добавляет данные в хранилище
        public static function register($key, $value)
        {
            self::$_registry[$key] = $value;
        }

        // удаление данных из хранилища
        public static function unregister($key)
        {
            if (isset(self::$_registry[$key])) {
                if (is_object(self::$_registry[$key]) && (method_exists(self::$_registry[$key], '__destruct'))) {
                    self::$_registry[$key]->__destruct();
                }
                unset(self::$_registry[$key]);
            }
        }
    }


    Ну и что мы здесь видим ?
    Все наши пряники лежат в хранилище $_registry. Попадают они туда благодаря методу register(), который просто невероятным(почти волшебным) способом их туда складывает.
    Метод registry() получает данные, а метод unregister() их оттуда удаляет.

    Кстати, может кто-то из вас уже догадался, но реализацию паттерна синглтон можно впихнуть сюда, что как по мне будет правильнее.
    Т.е. нам не надо при создании класса думать о том будет ли он использоватся как синглтон или нет, и плюс мы сэкономим чуток места, за счет того что опишем функционал синглтона всего лишь в одном месте.
    А сделаем мы всю эту прелесть очень просто, все что нам нужно, это добавить один метод в класс NRG , и выглядеть он будет так:

        public static function getSingleton($modelClass='') 
        {
            $registryKey = '_singleton/'.$modelClass;
            if (!self::registry($registryKey)) {
                self::register($registryKey, new $modelClass);
            }
            return self::registry($registryKey);
        }


    Вот вам и все пряники! =)




    Factory
    Ну тут тоже ничего сложного, непонимаю почему, но многие боятся этого паттерна(имею ввиду новичков). Просто надо найти ему применение.
    Рассомотрим пример:

    <?php 

    class NRG
    {    
        // наша фабрика
        public static function factory($type)
        {
            if (include_once(' lib/Database/Driver/' . $type . '.php')) {
                $classname = 'Database_Driver_' . $type;
                return new $classname;
            } else {
                throw new Exception ('Driver not found');
            }
        }
    }

    // пробуем подгрузить дравйвера
    $mysql = NRG::factory('Mysql');


    Даный пример кода позаимствован с мана
    http://www.php.ru/manual/language.oop5.patterns.html#language.oop5.patterns.factory

    В даном методе все работает чересчур просто. В зависимости от входящего параметра мы подключаем нужный нам драйвер. Т.е. если на вход(как в примере) прийдет Mysql, то сначала мы попытаемся заинклудить файл в котором описан сам класс драйвера (lib/Database/Driver/Mysql.php) , если не получилось, то трубим во все трубы и говорим что наш драйвер не найден. Иначе мы создаем инстанс Database_Driver_Mysql и возвращаем его.

    Надеюсь все описал просто, кратко и понятно.
    Если есть вопросы, то не стесняйтесь)))
    Всем чмоки.
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 1:35, спустя 9 минут 53 секунды

    сори, но както галопом по европе + теории не хватает)
    Спустя 9 сек.
    зы 8888
    Спустя 26 сек.
    минус: ты НЕ ОБЪЯСНИЛ ЗАЧЕМ ЭТО НАДО и КОГДА..
    Сапожник без сапог
  • NRG

    Сообщения: 4761 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 1:39, спустя 4 минуты 20 секунд

    phpdude,
    Надеюсь все описал просто, кратко и понятно

    =)
    теории не хватает

    чего именно не хватает ?
  • md5

    Сообщения: 11949 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 1:52, спустя 12 минут 59 секунд


    минус: ты НЕ ОБЪЯСНИЛ ЗАЧЕМ ЭТО НАДО и КОГДА..
    все умрут, а я изумруд
  • NRG

    Сообщения: 4761 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 1:53, спустя 1 минуту 15 секунд



    минус: ты НЕ ОБЪЯСНИЛ ЗАЧЕМ ЭТО НАДО и КОГДА..

    ок, потом апдейтну
  • Troy

    Сообщения: 2532 Репутация: N Группа: Джедаи

    Spritz 7 октября 2009 г. 1:55, спустя 1 минуту 52 секунды

    NRG, для фабрики, кокое применение ? Где ты например используеш ?
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 2:17, спустя 22 минуты 7 секунд

    а я говорил!… ))))

    что вопросы будут, ибо непонятно после прочтения: НАХУЙ "это должен знать каждый программист"?
    Сапожник без сапог
  • NRG

    Сообщения: 4761 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 2:25, спустя 7 минут 41 секунду


    а я говорил!… ))))

    что вопросы будут, ибо непонятно после прочтения: НАХУЙ "это должен знать каждый программист"?
    а я говорю, выдержите паузу и имейте терпение, ибо
    ок, потом апдейтну
  • Trej Gun

    Сообщения: 5299 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 2:26, спустя 1 минуту 27 секунд

    ващето фабрика возвращает не класс а интерфейс
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 2:32, спустя 5 минут 17 секунд


    ващето фабрика возвращает не класс а интерфейс
    а базовый она возвращать идеологически не может? например Car класс?

    именно ICar ?

    хотя по сути одно и тоже мне кажется. лишь бы знать что ДОЛЖЕН уметь возвращенный объект.
    Сапожник без сапог
  • Trej Gun

    Сообщения: 5299 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 2:41, спустя 9 минут 29 секунд

    ну если Car имплементит ICar то все будет работать так же как и Легковушка-Митсубиси-Лансер-Х все имплементят ICar но только фабрика знает насколько конкретную реализацию надо вернуть
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 3:09, спустя 27 минут 34 секунды


    ну если Car имплементит ICar то все будет работать так же как и Легковушка-Митсубиси-Лансер-Х все имплементят ICar но только фабрика знает насколько конкретную реализацию надо вернуть
    я спрашиваю не это, то что ты мне объяснил, это очевидно))

    я спрашиваю: почему возвращают объект который имплементит какой либо ИНТЕРФЕЙС? почему он не может возвращать объект унаследованный от абстрактного класса ACar к примеру? :)

    это идеология такая, стандарт? вернуть то он по факту может интерфейс или наследника абстракт класса, лююбой язык это сможет выполнить ):
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5139 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 3:43, спустя 34 минуты 31 секунду


    ващето фабрика возвращает не класс а интерфейс

    точнее фабрика обязуется вернуть объект класса, реализующего интерфейс.
    ιιlllιlllι унц-унц
  • Trej Gun

    Сообщения: 5299 Репутация: N Группа: в ухо

    Spritz 7 октября 2009 г. 6:03, спустя 2 часа 20 минут 12 секунд

    нет он не может вернуть ACar. ACar это уже по сути реализация.

    то есть нет разницы что ты допишешь недостающие методы в ACar что переопределишь готовые из ConcreteCar

Пожалуйста, авторизуйтесь, чтобы написать комментарий!