В проекте PHP, что шаблоны существуют для хранения, получают доступ и организуют объекты помощника? [закрытый]

Смотрите на функция ucfirst.

$line = join " ", map {ucfirst} split " ", $line;

114
задан 19 revs, 2 users 100% 27 December 2011 в 16:17
поделиться

7 ответов

Я бы избегал подхода Singleton, предложенного Флавиусом. Есть множество причин избегать этого подхода. Это нарушает хорошие принципы ООП. В блоге о тестировании Google есть несколько хороших статей о синглтоне и о том, как его избежать:

http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-join-new-project. html http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html http://googletesting.blogspot.com/2008/08/where-have- all-singletons-going.html

Альтернативы

  1. поставщик услуг

    http://java.sun.com/blueprints/corej2eepatterns/Patterns/ServiceLocator.html

  2. внедрение зависимости

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

    и объяснение на php:

    http: //components.symfony-project. (Роберт Мартин) обсуждает ручной DI и использование фреймворка

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

    Хотя это не «правда» Синглтон , я все еще думаю, что Флавий ошибся. Плохое глобальное состояние . Обратите внимание, что такие решения также используют трудные для тестирования статические методы .

    Я знаю, что многие люди это делают, одобряют и используют. Но чтение статей в блоге Misko Heverys ( эксперт по тестированию Google ), перечитывание их и медленное переваривание того, что он говорит, во многом изменило мой взгляд на дизайн.

    Если вы хотите иметь возможность протестировать свое приложение , ты' Вам нужно будет применить другой подход к разработке вашего приложения. Когда вы занимаетесь тестовым программированием, у вас возникнут трудности с такими вещами: «Далее я хочу реализовать регистрацию в этом фрагменте кода; давайте сначала напишем тест, который регистрирует базовое сообщение, а затем придумаем тест, который заставит вас написать и использовать глобальный регистратор, который нельзя заменить.

    Я все еще борюсь со всем информацию, которую я получил из этого блога, и ее не всегда легко реализовать, и у меня много вопросов. Но у меня нет возможности вернуться к тому, что я делал раньше (да, глобальное состояние и синглтоны (большая S)) после того, как я понял, что говорил Миско Хевери: -)

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

    Я все еще борюсь со всем информацию, которую я получил из этого блога, и ее не всегда легко реализовать, и у меня много вопросов. Но у меня нет возможности вернуться к тому, что я делал раньше (да, глобальное состояние и синглтоны (большая S)) после того, как я понял, что говорил Миско Хевери: -)

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

    Я все еще борюсь со всем информацию, которую я получил из этого блога, и ее не всегда легко реализовать, и у меня много вопросов. Но у меня нет возможности вернуться к тому, что я делал раньше (да, глобальное состояние и синглтоны (большая S)) после того, как я понял, что говорил Миско Хевери: -)

    и у меня много вопросов. Но у меня нет возможности вернуться к тому, что я делал раньше (да, глобальное состояние и синглтоны (большая S)) после того, как я понял, что говорил Миско Хевери: -)

    и у меня много вопросов. Но у меня нет возможности вернуться к тому, что я делал раньше (да, глобальное состояние и синглтоны (большая S)) после того, как я понял, что говорил Миско Хевери: -)

68
ответ дан 24 November 2019 в 02:36
поделиться
class Application {
    protected static $_singletonFoo=NULL;

    public static function foo() {
        if(NULL === self::$_singletonFoo) {
            self::$_singletonFoo = new Foo;
        }
        return self::$_singletonFoo;
    }

}

Вот как я бы это сделал. Он создает объект по требованию:

Application::foo()->bar();

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

Примечание: то, что я представил, это даже не настоящий однотонный шаблон. Одиночка позволила бы создать только один экземпляр, определив конструктор (Foo::__constructor()) как private. Это только "глобальная" переменная, доступная всем экземплярам "Приложения". Поэтому я считаю ее использование корректным, так как она НЕ пренебрегает хорошими принципами ООП. Конечно, как ничто в мире, этот "паттерн" тоже не должен быть чрезмерно использован!

Я видел, что он используется во многих PHP фреймворках, Zend Framework и Yii среди них. И вы должны использовать фреймворк. Я не буду рассказывать вам, какой именно.

Addendum Для тех из вас, кто беспокоится о TDD, вы все еще можете сделать некоторую проводку для введения зависимости. Это может выглядеть следующим образом:

class Application {
        protected static $_singletonFoo=NULL;
        protected static $_helperName = 'Foo';

        public static function setDefaultHelperName($helperName='Foo') {
                if(is_string($helperName)) {
                        self::$_helperName = $helperName;
                }
                elseif(is_object($helperName)) {
                        self::$_singletonFoo = $helperName;
                }
                else {
                        return FALSE;
                }
                return TRUE;
        }
        public static function foo() {
                if(NULL === self::$_singletonFoo) {
                        self::$_singletonFoo = new self::$_helperName;
                }
                return self::$_singletonFoo;
        }
}

Здесь достаточно места для улучшения. Это просто PoC, используйте ваше воображение.

Зачем так делать? Ну, большую часть времени приложение не будет проходить юнит-тестирование, на самом деле оно будет запущено, , надеюсь, в производственной среде . Сила PHP в его скорости. PHP НЕ является и никогда не будет "чистым OOP языком", как Java.

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

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

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

Addendum

One function style:

function app($class) {
    static $refs = array();

    //> Dependency injection in case of unit test
    if (is_object($class)) {
        $refs[get_class($class)] = $class;
        $class = get_class($class);
    }

    if (!isset($refs[$class]))
        $refs[$class] = new $class();

    return $refs[$class];
}

//> usage: app('Logger')->doWhatever();
16
ответ дан 24 November 2019 в 02:36
поделиться

Мне нравится концепция впрыска зависимости:

«Инъекция зависимости в том, что компоненты придаются их зависимостям через их конструкторы, методы или непосредственно в полях. (Из веб-сайт контейнера PICO ) «

Fabien PotenChier написал действительно приятно серию статей о инъекции зависимости и необходимость их использования. Он также предлагает хороший и небольшой контейнер для инъекций зависимостей по имени Pimple , который мне очень нравится использовать (подробнее о Github ).

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

15
ответ дан 24 November 2019 в 02:36
поделиться

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

Также и реестр VS. Singleton вопрос.

6
ответ дан 24 November 2019 в 02:36
поделиться

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

1) Объект может иметь много полезных методов или необходимо вызывать более одного раза, в этом случае я реализую синглтон / реестр:

$object = load::singleton('classname');
//or
$object = classname::instance(); // which sets self::$instance = $this

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

$object = new Class();

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

4
ответ дан 24 November 2019 в 02:36
поделиться

Почему бы не прочитать прекрасное руководство?

http: / /php.net/manual/en/language.oop5.autoload.php

-1
ответ дан 24 November 2019 в 02:36
поделиться

Я бы выбрал функцию, возвращающую инициализированные объекты:

A('Users')->getCurrentUser();

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

3
ответ дан 24 November 2019 в 02:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: