Класс PHP Translator - мнения о передовом опыте

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

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

Это пример класса переводчика.

class Translator{
    protected $translations;

    public function __construct(){
        $this->translations[] = include $this->language . ".php"; //General texts for a language
        $this->translations[] = include $this->language . "-" . $this->controller . ".php"; //General texts for a controller
        $this->translations[] = include $this->language . "-" . $this->controller . "-" . $this->action . ".php"; //Specific texts for an action
    }

    public function translate($key){
        return $this->translations[$key];
    }

}

Вот как это сделать, расширив. После прочтения о композиции объектов этот способ кажется крайне обескураживающим. См. http://www.cs.utah.edu/~germain/PPS/Topics/oop.html

class View extends Translator{
    ...
}

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

class View{
    protected $translator;

    public function __construct(){
        $this->translator = new Translator();
    }

    ...
}

Вместо того, чтобы создавать новый Translator, как насчет того, чтобы вставить его в глобальную переменную?

$translator = new Translator();

class View{
    protected $translator;

    public function __construct(){
        global $translator
        $this->translator = $translator;
    }

    ...
}

Последняя идея, с публичными функциями вместо класса

$translations = //Include the language array files like in the translator class

function translate($key){
    global $translations;
    return $translations[$key];
}

person Alexander Weihmayer    schedule 13.11.2015    source источник
comment
Ничто не должно расширять класс Translator, если только он не является переводчиком. Нечто, называемое Translator, никогда не должно расширять какое-либо приложение.   -  person PeeHaa    schedule 13.11.2015
comment
Узнайте о композиции объекта.   -  person PeeHaa    schedule 13.11.2015
comment
Также похоже, что ваши классы делают слишком много. Как будто у них слишком много обязанностей, если им всем нужен доступ к упомянутому переводчику.   -  person PeeHaa    schedule 13.11.2015
comment
Хорошо, я углублюсь в изучение того, как лучше создавать объекты. Есть ли хорошие источники, чтобы порекомендовать? Кроме того, скажем, мои объекты были сделаны правильно, какова стандартная практика для переводчиков?   -  person Alexander Weihmayer    schedule 13.11.2015
comment
Ну, об этом можно написать несколько книг. На самом деле это сделали люди.   -  person PeeHaa    schedule 13.11.2015
comment
Пока что другие классы расширяют класс переводчика, чтобы иметь доступ к методам перевода. =› И не захотят ли другие классы также расширить маршрутизатор, чтобы иметь доступ к методам маршрутизации, и контроллер к получить доступ к методам, связанным с представлением, и, и, и? Но это не сработает, потому что вы не можете расширить несколько классов. Вы думали об этом?   -  person Jon    schedule 13.11.2015
comment
Да, я думаю, что все довольно аккуратно и не дублируется, за исключением переводчика, который несколько раз расширяется (в показанных классах), что я нахожу ужасным. Мне не нужно несколько экземпляров или расширять его повсюду, поэтому я подумал о создании простых общедоступных функций перевода (покажу пример в редактировании).   -  person Alexander Weihmayer    schedule 13.11.2015
comment
@AlexanderWeihmayer: Чтобы было ясно: идея расширения переводчика ужасна и ошибочна. Перед тем, как убить его огнем, вы, конечно, должны понять, почему, но это уже другая тема. Здесь я пытался предложить другие, более практические причины, почему это не сработает. Чего я все же думаю, что не будет. Но даже если и так, это было только мое замечание. Никогда не делайте этого. Эта ошибка также известна как "автомобиль выдвигает двигатель". Поиск по этому запросу может дать лучшие результаты.   -  person Jon    schedule 13.11.2015
comment
Почитайте немного об этом, и я немного лучше пойму, что люди говорят о композиции объектов. Сделал правку для подтверждения :O   -  person Alexander Weihmayer    schedule 13.11.2015
comment
@AlexanderWeihmayer: самое простое улучшение — сделать переводчик одноэлементным — проблема с несколькими экземплярами решена. Но тогда вы хотели бы прочитать о том, какие недостатки есть у этого способа ведения дел и как он сравнивается с внедрением зависимостей.   -  person Jon    schedule 13.11.2015
comment
Прочитайте, что такое синглтон, и я счастлив! Хотя во многих ситуациях есть некоторые недостатки, но я очень сомневаюсь, что это будет проблемой для целей моего переводчика. Если вы хотите опубликовать ответ, я обязательно приму его.   -  person Alexander Weihmayer    schedule 13.11.2015


Ответы (1)


ИЗМЕНИТЬ

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

Ознакомьтесь с этим, чтобы получить представление о том, как создавать и использовать статические классы: Можно ли создавать статические классы в PHP (как в C#)?

СТАРЫЙ

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

Вот хороший пример того, как это сделать Создание шаблона проектирования Singleton в PHP5< /а>

Быстрая демонстрация

final class Translator{
    protected $translations;

    public static function getInstance(){
        static $inst = null;
        if ($inst === null){
            $inst = new Translator();
        }
        return $inst;
    }

    private function __construct(){ //Private constructor so nobody else can instance it
        ...//Look at translator class in question
    }
}

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

$translator = Transaltor::getInstance();
person Alexander Weihmayer    schedule 16.11.2015