PHP Translator class - Мнения за най-добрите практики

Създавам своя собствена рамка и имам клас преводач, който се използва на няколко места в приложението.

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

Това е пример за класа преводач.

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 = 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: За да бъде ясно: идеята за разширяване на преводача е ужасна и погрешна. Преди да го убиете с огън, разбира се трябва да разберете защо, но това е друга тема. Тук се опитвах да предложа други, по-непосредствено практични причини защо това няма да работи. Което все си мисля, че няма да стане. Но дори и да беше, това беше само моята странична бележка. Никога не правете това. Тази грешка е известна също като car extends engine, може да имате по-добри резултати при търсене на това.   -  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