1. PHP / Говнокод #4109

    +144

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    <?php
    
    class Event {
        private static $_instance = NULL;
        protected $_events_pool = array();
    
        public static function getInstance() {
            if (self::$_instance === NULL) {
                $class = __CLASS__;
                self::$_instance = new $class;
            }
            
            return self::$_instance;
        }
    
        private function __construct() { }
    
        public function connect($event, $callback, array $params = null) {
            $this->_events_pool[$event] = array(
                'callback'	=>	$callback,
                'params'	=>	$params,
            );
            
            return $this;
        }
    
        public function clear($event = NULL) {
            if ($event === NULL) {
                $this->_events_pool = array();
            } else {
                foreach ($this->_events_pool as $id => $_event) {
                     if ($_event['event'] === $event) {
                        $this->_events_pool[$id] = NULL;
                     }
                }
            }
        }
    
        public function emit($events = NULL) {
            if ($events === NULL) {
                $events = array_keys($this->_events_pool);
            } else {
                $events = (is_array($events)) ? $events : array($events);
            }
            
            foreach ($events as $event) {
                foreach ($this->_events_pool as $id => $item) {
                     if ($id === $event) {
                        $this->call($this->_events_pool[$id]['callback']);
                     }
                }
            }
        }
    
        protected function call($class_name, $method_name = NULL, array $params = array(), array $class_params = array()) {	
            $_method = ($method_name === NULL) ? $class_name : array($class_name, $method_name);
            call_user_func_array($_method, $params);
        }
    }

    Запостил: nergal, 26 Августа 2010

    Комментарии (18) RSS

    • Читателям предлагается найти говнокод? Где комментарии?
      Если откинуть грамматические говняшки, типа "new $class;" вместо "new self();", перебор всех событий вместо того чтобы одним точным ударом вычесть нужное, то остаётся менее очевидное - protected функция call, которая должна вызваться из потомка, но его нигде тут не показано.
      "Где здесь говнокод, nergal?!"
      Ответить
      • да он просто ошибся окошечком, хотел в IDE своё это скопировать =)
        Ответить
        • йопт, действительно ошибся - не тот код... извиняйте)
          Ответить
    • 1. попахивает метод getInstance(), как уже заметил newmindcore

      2.немного странный подход. Класс называется Event - ожидается, что обьектов будет два и более, а нет - видим шаблон синглтона. При этом организовывается очередь событий $_events_pool, и для работы с ней предоставляется интерфейс - но сама очередь событий НЕ статична!
      имхо довольно обескураживающая логика, и через месяц такие вот особенности без доки забываются

      Я бы рекомендовал переименовать класс в EventPool, и $_events_pool тоже на всякий случай сделать статичным - со стороны будет пониматься гораздо лучше.
      Ответить
      • Не переживайте, всё не так плохо, как Вы думаете. Как я уже говорил, я поспешил и отправил не тот код - копался в папке со старыми проектами, искал всякое-разное.

        Так вот:
        1. Метод претерпел изменений и вместо __CLASS__ там get_called_class() - не могу сказать с уверенностью, под него ли я писал изначально, но очень на то похоже.
        2. Также и с названием - сейчас этот файл есть частью фреймворка и носит имя Core_Signal.
        Не вижу ничего плохого в нестатичности очереди - она существует покуда жив инстанс класса, следовательно, пока к нему можно будет обратиться.
        Ответить
        • > Не вижу ничего плохого в нестатичности очереди
          в данном случае, может быть, кроме понимания и не будет ничего плохого, но в общем случае могут быть случаи:
          а. из-за ошибки в реализации мы случайно создали другой инстанс - очереди тоже стало две
          б. очередь доступна только в контексте обьекта - что значит, что зачастую извне мы не сможем получить очередь напрямую. Когда тут синглтон, то это неважно, а вот если мы бы организовали, скажем, пул - тогда бы нам пришлось явно указывать обьект
          Ответить
          • Это же синглтон, зачем ему делать статическую очередь?
            Что бы убица, если понадобится сделать вместо синглтона пул объектов?
            Ответить
            • эх... Наверное все же тут можно устроить холивар, навроде использования пробелов и табов для отступов. Не будем. Опыт как всегда покажет....
              Ответить
              • Это не холивар. Давайте начнем сначала: зачем вообще синглтон? почему не сделать пачку статических методов?
                Ответить
                • а кстати да, я попутал, я действительно говорил о статических методах (потому как тогда разницы не будет)

                  а так мы можем создать только иллюзию статики, а внутренне организовывать различные обьекты, расширять класс потомками и так далее. Если нам нужны именно эти свойства синглтона, то вряд ли имеет смысл предоставлять разделяемые данные
                  Ответить
                  • В кошерных языка у синглтонов приватный конструктор (иначе это мегадыра).
                    Интересно, как можно расширить класс с приватным конструктором?;)))
                    Ответить
                    • не знаю в каких это языках. Синглтон, это таки шаблон, а не языковая конструкция, а значит, создается усилиями программинга. Поэтому запросто конструктор может быть защищенный, или даже быть несколько таких конструкторов.
                      Поэтому можно и синглтон расширить. Ну, на худой конец, обернуть...
                      Ответить
                      • Наследование решается объявлением класса, как final.
                        Ответить
                      • Ладно. А как Вы переопределите статический метод getInstance()? Разве статические методы переопределяются?
                        Ответить
                        • они успешно перекрываются. Т.е. A::getInstance() и B::getInstance(), где B extends A - разные все же методы.
                          Ответить
                    • для этого делается protected конструктор, или вы не про это?
                      Ответить
          • а. И это правильно, т.к. в оригинале должно быть несколько очередей событий для разных целей. Ошибки реализации - это ошибки.
            б. А нам не нужна очередь напрямую - это ведь инкапсуляция по-сути, не так ли?)
            Ответить
      • Так, что ты имеешь против функции getInstance()? нормальный такой cинглетон паттерн.
        И тут очевидно, что класс выполняет роль event dispatchera, чего умничать то =)
        Ответить

    Добавить комментарий