ФорумПрограммированиеПыхнуть хотите?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($registryKeynew $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

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

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

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

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

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

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

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

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

    Сообщения: 11960 Репутация: 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

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

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

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

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

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

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


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

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

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

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

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

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

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


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

    именно ICar ?

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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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