Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > MVC, экз. класса или стат. класс контроллера


Автор: MCMXC 17.8.2011, 11:38
У меня возник такой вопрос: почему все создают экземпляр определенного класса контроллера, а не изначально объявляют класс контроллер как статический?.. Ведь по идее, всё равно ж нам не понадобится использовать две копии контроллера в приложении с разными данными... Как вы считаете?..

Автор: krundetz 17.8.2011, 16:28
Не совсем понимаю ваш вопрос. Можно увидеть пример?

Автор: MCMXC 17.8.2011, 16:35
Ну смотрите, допустим, фронт контроллер вызывает определенный контроллер в зависимости от запроса пользователя, например, посетитель переходит по ссылке index.php?c=catalog&act=list, сразу вызывается фронт контроллер который создает нужный экземпляр класса, в нашем случае CatalogController

$catalog = new CatalogController();
$catalog->tralivali();

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

CatalogController::tralivali();

Автор: krundetz 18.8.2011, 15:08
Основная и думаю главная причина здесь в том что у нас не создается экземпляр класса, а следовательно:

1. В этом статическом методе должна быть вся реализация конкретного функционала, так как из статического метода мы не можем сделать так:

Код

class CatalogController {
    public function tralivali() {
        $this->tralivali1();
        $this->tralivali2();
    }
    public function tralivali1() {
        /*некое действие 1*/
    }
    public function tralivali2() {
        /*некое действие 2*/
    }
}


Если метод tralivali, будет статическим так сделать не получиться, если только в статическом методе не создавать экземпляр класса.

2. Также из статического метода нельзя обратиться к не статическим свойствам класса,  а соответственно мы не можем хранить состояние, точнее мы должны его тащить за собой.

3. Из 1 и 2 следует, что мы теряем такой мощный инструмент как наследование.То есть вместо того чтобы написать один раз повторяющийся код в классе родителе, мы его повторяем во множестве реализаций контроллеров в нашей системе.

думаю можно ещё перечислить несколько причин, почему так делать не стоит.

То есть, заменяя таким образом вызовы методов их статическими вариантами вы отказываетесь от мощи ООП, возвращаясь к функциональному подходу. То есть все зависит какой концепции вы собираетесь следовать, функциональной или объектно-ориентированной.

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

Автор: Shogun 18.8.2011, 21:23
Цитата(krundetz @  18.8.2011,  15:08 Найти цитируемый пост)
1. В этом статическом методе должна быть вся реализация конкретного функционала, так как из статического метода мы не можем сделать так:

Код

class CatalogController {
    public function tralivali() {
        $this->tralivali1();
        $this->tralivali2();
    }
    public function tralivali1() {
        /*некое действие 1*/
    }
    public function tralivali2() {
        /*некое действие 2*/
    }
}



Код

class CatalogController {
    public static function tralivali() {
        self::tralivali1();
        self::tralivali2();
    }
    public static function tralivali1() {
        /*некое действие 1*/
    }
    public static function tralivali2() {
        /*некое действие 2*/
    }
}


По 2 и 3 почитайте про основы ООП внимательнее.

В общем можно обойтись и статическими классами, но некоторый функционал все-таки теряется.
Так как статический класс не инициализируется то нет возможности использовать конструкторы и деструкторы, также нет и магических методов __set или __get.
Во многих фреймворках к обьекту динамически присваиваются обьекты других загружаемых классов чтобы можно к ним обратится через $this->user например, ну и много чего еще...


Автор: krundetz 19.8.2011, 11:12
Shogun, вы видимо меня совсем не поняли. Фразой:
Цитата(krundetz @  18.8.2011,  15:08 Найти цитируемый пост)
Если метод tralivali, будет статическим так сделать не получиться, если только в статическом методе не создавать экземпляр класса.

Я имел в виду что нельзя сделать вот так:
Код

class CatalogController {
    public static function tralivali() {
        $this->tralivali1();
        $this->tralivali2();
    }
    public function tralivali1() {
        /*некое действие 1*/
    }
    public function tralivali2() {
        /*некое действие 2*/
    }
}


Ваш пример конечно обходит, это ограничение, но сразу возникает вопрос. А зачем в вашем примере класс вообще нужен? Делайте тогда так:
Код

function tralivali() {
    tralivali1();
    tralivali2();
    }
function tralivali1() {
    /*некое действие 1*/
}
function tralivali2() {
    /*некое действие 2*/
}

В посте выше я это отметил:
Цитата(krundetz @  18.8.2011,  15:08 Найти цитируемый пост)
То есть, заменяя таким образом вызовы методов их статическими вариантами вы отказываетесь от мощи ООП, возвращаясь к функциональному подходу.

Заметьте я не говорю что так делать нельзя, я говорю что вы просто отказываетесь от ООП.

По 2 пункту, посмотрите вот на этот код:
Код

abstract class MyClass1 {
    protected static $myStatic = 'Значение1';
    public static function getMethod () {
        return self::$myStatic;
    }
    abstract public static function setMethod ();
    
}
class MyClass2 extends MyClass1 {
    public static function setMethod () {
        self::$myStatic = 'Значение2';
    }
}

class MyClass3 extends MyClass1 {
    public static function setMethod () {
        self::$myStatic = 'Значение3';
    }
}

MyClass2::setMethod();
echo MyClass3::getMethod() . '<br/>';
MyClass3::setMethod();
echo MyClass2::getMethod() . '<br/>';


По 3 пункту, я опят же не говорю что оно невозможно,  я говорю что мы его теряем.

Автор: krundetz 22.8.2011, 22:29
Shogun, мне было бы интересно продолжить с вами дискусию, если вам тоже, то жду ваших комментариев к вышеописанному.

Автор: Muerto 23.8.2011, 16:08
А можно и со статическими контроллерами работать...

Мне кажется главная причина именно потому что так принято...

Идет раутинг, создается instance контроллера, вызывается действие, далее вызываются модели и тп...

---

Единственное что приходит в ум:

проблем с инкапсуляцией нету
Код

class Test{
    public static function bar(){
        self::foo();
    }
    private static function foo(){
        echo 'z';
    }
}
Test::bar();//z


Но вот какбыть с магическими методами?

Автор: krundetz 25.8.2011, 08:53
Цитата(Muerto @  23.8.2011,  16:08 Найти цитируемый пост)
проблем с инкапсуляцией нету

вы правы, да и Shogun уже показал способ инкапсулировать вызов статических методов. Мне интересно другое, насколько оправдано использование классов у которых есть только статические методы? Какова их область применения? Возможно проще и разумнее заменить такие классы набором обычных функций?

Цитата(Muerto @  23.8.2011,  16:08 Найти цитируемый пост)
Но вот какбыть с магическими методами? 

Я так понимаю что, никак. Такие магические методы как, __get() и __set() работают со свойствами. А соответственно нам нужно инстанцирование класса.

Добавлено через 3 минуты и 10 секунд
Цитата(MCMXC @  17.8.2011,  11:38 Найти цитируемый пост)
Ведь по идее, всё равно ж нам не понадобится использовать две копии контроллера в приложении с разными данными...

а если понадобиться?

Автор: 502 25.8.2011, 10:01
а что Singleton уже не в моде?

Добавлено через 1 минуту и 42 секунды
Цитата(krundetz @  25.8.2011,  08:53 Найти цитируемый пост)
а если понадобиться? 

нет

контроллер не должен хранить данные, а значит и не надо создавать 2 экземпляра  smile 

Автор: krundetz 26.8.2011, 11:57
Цитата(502 @  25.8.2011,  10:01 Найти цитируемый пост)
а что Singleton уже не в моде?

А у Singliton только статические методы? По моему, в классическом Singleton есть один статический метод, который используется для получения экземпляра класса, либо создания экземпляра если он ещё не создан.
Цитата(502 @  25.8.2011,  10:01 Найти цитируемый пост)
нет

почему?
Цитата(502 @  25.8.2011,  10:01 Найти цитируемый пост)
контроллер не должен хранить данные, а значит и не надо создавать 2 экземпляра

а где я говорил о данных? Я говорил о состояние? Или вы считаете что данные и состояние это одно и тоже?

Автор: Absinthe 26.8.2011, 12:16
Цитата

У меня возник такой вопрос: почему все создают экземпляр определенного класса контроллера, а не изначально объявляют класс контроллер как статический?
 Начнем с того, что теоретически статические контроллеры стали доступны только в PHP 5.3, т.к. только в нем появилось позднее связывание.
Но смысл изображать объект классом когда можно воспользоваться обычным объектом?

Тема напоминает "Но ведь можно ложки держать попами и друг друга кормить". Можно, но руками то удобнее держать?

Автор: Sentox 27.8.2011, 20:56
Эта проблема не семантического порядка, а проектного.
Статический метод инкапсулирует в себе знания  и алгоритм работы на уровне класса! а не экземпляра. То есть дочерние классы так же, если вызывается статический метод, работают на уровне родительского класса (не важно что он был унаследован),  в противовес своим внутренним методам - интерфейсам, которые являются частью дочернего класса и работают на уровне не класса а экземпляра. Отсюда и строятся две диаграммы в UML  диаграмма объектов и диаграмма классов. Если смотреть со стороны "клиентов", используемых эту архитектуру: это позволяет обеспечить выполнение статического интерфейса исключительно Определённого класса, что в принципе создаст большую связность, но если это укрепит архитектуру то только обеспечит уменьшение архитектурных ошибок, сори за тавтологию.  

Автор: 502 27.8.2011, 22:01
Цитата(krundetz @  26.8.2011,  11:57 Найти цитируемый пост)
А у Singliton только статические методы?

нет
Цитата(krundetz @  26.8.2011,  11:57 Найти цитируемый пост)
По моему, в классическом Singleton есть один статический метод, который используется для получения экземпляра класса, либо создания экземпляра если он ещё не создан.

 smile 
Цитата(krundetz @  26.8.2011,  11:57 Найти цитируемый пост)
а где я говорил о данных? Я говорил о состояние?

а что раз вы не говорили то и я не должен?

если у класса есть только методы, то почему его методы не сделать статическими или Singleton?

Цитата(krundetz @  26.8.2011,  11:57 Найти цитируемый пост)
Или вы считаете что данные и состояние это одно и тоже? 

а что, нет?

Автор: Sentox 27.8.2011, 22:28
502
Цитата(krundetz @  26.8.2011,  11:57 Найти цитируемый пост)
Или вы считаете что данные и состояние это одно и тоже? 
а что, нет?

Глубокое заблуждение.

>если у класса есть только методы, то почему его методы не сделать статическими или Singleton?

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

Автор: 502 27.8.2011, 23:36
Цитата(Sentox @  27.8.2011,  22:28 Найти цитируемый пост)
Глубокое заблуждение.


Цитата(Sentox @  27.8.2011,  22:28 Найти цитируемый пост)
Выбор должен быть обоснован и аргументирован

ну и где аргументы?

Автор: Sentox 28.8.2011, 10:47
Цитата(502 @ 27.8.2011,  23:36)
Цитата(Sentox @  27.8.2011,  22:28 Найти цитируемый пост)
Глубокое заблуждение.


Цитата(Sentox @  27.8.2011,  22:28 Найти цитируемый пост)
Выбор должен быть обоснован и аргументирован

ну и где аргументы?

Слово "данные" происходит от слово "давать", из этого следует что это больше подходит к параметрам для класса, которые ему передаются (не важно через интерфейс его личных методов или конструктор). Состояние объекта хранят свойства объекта, И ТО не факт что все они будут отражать состояние объекта на данный момент.  smile 
Вот как бы так, такой аргумент подходит.

Автор: 502 28.8.2011, 11:05
Цитата(Sentox @  28.8.2011,  10:47 Найти цитируемый пост)
Состояние объекта хранят свойства объекта,

а что хранят свойства? не данные?

Цитата(Sentox @  28.8.2011,  10:47 Найти цитируемый пост)
И ТО не факт что все они будут отражать состояние объекта на данный момент.

а я где-то написал что все?

ну и где я ошибался?

Автор: Absinthe 28.8.2011, 15:03
Цитата

Слово "данные" происходит от слово "давать", из этого следует
 Что за бред? Откуда стремление делать эзотерические выводы?
Каким это образом data произошла от give?

Теоретически MVC можно сделать и без ООП, как и предложено здесь(статический класс использован как неймспейс, что ни капли не ооп), но будет не удобно.
Подтверждение: перепишите популярный фреймворк на статик-контроллеры.

Автор: Sentox 28.8.2011, 19:31
Цитата(Absinthe @ 28.8.2011,  15:03)
Цитата

Слово "данные" происходит от слово "давать", из этого следует
 Что за бред? Откуда стремление делать эзотерические выводы?
Каким это образом data произошла от give?

Теоретически MVC можно сделать и без ООП, как и предложено здесь(статический класс использован как неймспейс, что ни капли не ооп), но будет не удобно.
Подтверждение: перепишите популярный фреймворк на статик-контроллеры.

Не не не ...
не путайте грешное с праведным. 
Цитата
(статический класс использован как неймспейс, что ни капли не ооп),

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

Автор: krundetz 29.8.2011, 12:31
Цитата(502 @  27.8.2011,  22:01 Найти цитируемый пост)
если у класса есть только методы, то почему его методы не сделать статическими

Потому что, это снижает гибкость разработки, и потому что, тогда у вас должны быть не методы, а функции. Подумайте об этом в контексте легкой расширяемости системы.
Цитата(502 @  27.8.2011,  22:01 Найти цитируемый пост)
или Singleton?

 smile о как! И чем же это поможет? Попробуйте перенести ваши слова в код.

Повторюсь. Меня интересует прежде всего целесообразность использования классов только со статическими методами. А товарища топикстартера интересует тот же вопрос в контексте контроллеров.

Цитата(502 @  27.8.2011,  22:01 Найти цитируемый пост)
а что, нет? 

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

Автор: 502 29.8.2011, 13:48
Цитата(krundetz @  29.8.2011,  12:31 Найти цитируемый пост)
Потому что, это снижает гибкость разработки

 smile 
Цитата(krundetz @  29.8.2011,  12:31 Найти цитируемый пост)
о как! И чем же это поможет? Попробуйте перенести ваши слова в код.

Код

class Person
{
    private static $instance = null;
    final private function __clone() {}
    protected function __construct() {}
    public static function getInstance() 
    {
        if ( ! self::$instance)
            self::$instance = new Person;
        
        return $instance;
    }

    public function getAge()
    {
        return 42;
    }
}

Person::getInstance->getAge();

и что тут не так? 

Цитата(krundetz @  29.8.2011,  12:31 Найти цитируемый пост)
а вот работает ли он, спит ли, думает это состояние.

а как вы определяете что он работает, спит, не по данным?

Цитата(krundetz @  29.8.2011,  12:31 Найти цитируемый пост)
Повторюсь. Меня интересует прежде всего целесообразность использования классов только со статическими методами. А товарища топикстартера интересует тот же вопрос в контексте контроллеров.

может он не знает про Singleton

Автор: krundetz 29.8.2011, 14:23
Цитата(502 @  29.8.2011,  13:48 Найти цитируемый пост)
может он не знает про Singleton

это надо у него спросить.
Цитата(502 @  29.8.2011,  13:48 Найти цитируемый пост)
и что тут не так? 

Вы сами сказали, что:
Цитата(502 @  27.8.2011,  22:01 Найти цитируемый пост)
если у класса есть только методы

так зачем мне придумывать ещё один метод ( в вашем примере это getInstance() ) который является излишней прослойкой для обращения к методу getAge()? ИМХО Singliton без свойств и состояний теряет смысл, ведь его смысл в том, чтобы иметь доступ к данным и состояниям объекта из любой точки программы не прибегаю к их дублированию, и исключить их возможное случайное изменение.


Пример по нарушению гибкости приведу придя с работы.

Добавлено через 8 минут и 39 секунд
Цитата(502 @  29.8.2011,  13:48 Найти цитируемый пост)
а как вы определяете что он работает, спит, не по данным?

а вы попробуйте определить, исходя из того что человек весит 80 кг его состояние

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)