Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> наследование и статические методы 
V
    Опции темы
MyDarkSide
Дата 9.12.2009, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 21.3.2008

Репутация: -1
Всего: -1



Думаю сейчас над реализацией моделей в своем фреймворке MVC.
Пришла в голову интересная идея: статические методы модели отвечают за выборку данных из множества. 
А обычные члены класса реализуют сам объект модели (т.е. сущность) 

Код

<?php
Class User {
  protected static $table = 'users';
  protected static $name  = 'User';
  
  
  public static function getById($id) {
    // код который загружает запись из базы и создает экземпляр класса User
    // return object типа  User 
  }
  
  public function isOnline() {
    return ( time() - $this->lastActive ) < 3000;
  }
  
}


$user = User::getById(1);

echo $user->name;
echo $user->isOnline() ? "online" : "offline" ;  
  
?>


следующий шаг естественно вынести методы типа getById() в базовый класс
Код

<?php
Abstract Class AbstractModel {
  protected static $table = '';
  protected static $name  = '';
  
  public static function getById($id) {
    // self::$table;  - содержит всегда '' даже если вызов идет через класс User
    // get_called_class() есть только в php >= 5.3
    // в debug_backtrace() нет даже упоминания о классе User не смотря на то что вызов метода я сделал как-бы через него
    
    // код который загружает запись из базы и создает экземпляр класса User
    // return object типа  User (если вызов User::getById() ) 
  }
  


Class User extends AbstractModel {
  protected static $table = 'users';
  protected static $name  = 'User';
  
  public function isOnline() {
    return ( time() - $this->lastActive ) < 3000;
  }
  
}
?>

и тут я познал дзен - комменты в AbstractModel::getById()

получается как в старом анекдоте: ни денег, ни топора и вроде все правильно.
PM ICQ   Вверх
awdev
Дата 9.12.2009, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 22.11.2009

Репутация: нет
Всего: 1



в чем вопрос?
PM MAIL   Вверх
NewDima
Дата 9.12.2009, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

Репутация: нет
Всего: 12



Пространства имен абстрактных членов классов разных уровней наследования не совпадают
PM ICQ   Вверх
NewDima
Дата 9.12.2009, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

Репутация: нет
Всего: 12



я бы сделал как-то так
Код

abstract class abstractModel {
    static protected $__prefix = 'tbl_';
    static public function __callStatic($method, $params) {
        if (!preg_match('#^get(\w+)By(\w+)$#', $method, $matches) || !count($params)) {
            throw new exception('dwad');
        }
        $tb_name = self::$__prefix . ($name = strtolower($matches[1])) . 's';
        $tb_by   = strtolower($matches[2]);
        $data    = self::loadData($tb_name, $tb_by, $params[0]);
        $class   = $name.'Model';
        return new $class($data);
    }
    static protected function loadData($table, $domain, $where) {
        return array($domain => $where);
    }
}

class userModel extends abstractModel {
    protected $data = null;
    public function __construct($data) {
        $this->data = $data;
    }
}

$user = abstractModel::getUserById();

PM ICQ   Вверх
awdev
Дата 9.12.2009, 20:22 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 22.11.2009

Репутация: нет
Всего: 1



Вот так и создаются ### фрейморки  smile 

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


PM MAIL   Вверх
NewDima
Дата 10.12.2009, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

Репутация: нет
Всего: 12



awdev, комментируя чей-то код, выкладывай аргументы. Голые твои слова стоят ровным счетом ничего. Это на тему ### кода.
Холеварить на тему "стоит ли писать самостоятельно велосипеды" не буду, потому что для меня здесь ответ очевиден.
MyDarkSide, Зачем создавать тему, в которой потом не отписываешься? Нравится, когда пинают репутацию?
PM ICQ   Вверх
sTa1kEr
Дата 10.12.2009, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 11
Всего: 146



Магический метод __callStatic() тоже только в PHP 5.3 доступен.

А вообще это избитый вопрос. Ответ: никак нельзя, только переходить на PHP 5.3
PM MAIL   Вверх
awdev
Дата 10.12.2009, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 22.11.2009

Репутация: нет
Всего: 1



Цитата(NewDima @ 9.12.2009,  16:47)
я бы сделал как-то так
Код

abstract class abstractModel {
    static protected $__prefix = 'tbl_';
    static public function __callStatic($method, $params) {
        if (!preg_match('#^get(\w+)By(\w+)$#', $method, $matches) || !count($params)) {
            throw new exception('dwad');
        }
        $tb_name = self::$__prefix . ($name = strtolower($matches[1])) . 's';
        $tb_by   = strtolower($matches[2]);
        $data    = self::loadData($tb_name, $tb_by, $params[0]);
        $class   = $name.'Model';
        return new $class($data);
    }
    static protected function loadData($table, $domain, $where) {
        return array($domain => $where);
    }
}

class userModel extends abstractModel {
    protected $data = null;
    public function __construct($data) {
        $this->data = $data;
    }
}

$user = abstractModel::getUserById();

Вся бизнес логика должна быть спрятана в модели.

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

Отсюда следует что конструктор у моделей может быть разный. 

Во вторых этот способ не абстрагируется. 

Сегодня мне нужно из БД, завтра считать с XML файла послезавтра вообще передумаю и буду брать через SOAP, в классической постановке мы меняем одну модель на другую в контроллере. Или вместо new News(new XMLClient) написали new News(new SOAPClient) и все пашет.  
Все остальное - остается неизменным, ваш же код будет вызывать один и тот же класс.

Например мне нужно получить Новость по ID:
Будет вызвано: return NewsModel(array("ID"=>10));

Или вообще захочу игнорировать все запросы. Изменить в контролере вызов NewsModel на NewsModelBlackHole - все. А у вас надо будет модель перезаписывать.

То есть если я передумаю использовать эту модель, и захочу другую - мне придется перезаписывать файл NewsModel.


Что, как мне кажется, не очень красиво и правильно.

Это сообщение отредактировал(а) awdev - 10.12.2009, 16:26
PM MAIL   Вверх
NewDima
Дата 10.12.2009, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

Репутация: нет
Всего: 12



awdev, а ты не заметил, что перед кодом я написал "как то так"? Это значит что это только смысл кода, почти псевдокод. Это одно. Другое: я ответил на вопрос топикстартера так, как он был поставлен, остальное - его проблемы.
sTa1kEr, а вы пишете для версий ниже?!

Добавлено через 4 минуты и 25 секунд
Вообще, создается впечатление, что большинство программистов пишут под четверку и даже горядтся этим...
PM ICQ   Вверх
awdev
Дата 10.12.2009, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 22.11.2009

Репутация: нет
Всего: 1



NewDima, я не понимаю почему Вы пишите сообщение на "ты"?

Во вторых я не хотел доказывать или что-либо еще, я лишь написал видимые для меня недостатки Вашего кода. 
Если вы хотели написать это как псевдокод, то это не прочиталось.

В любое случае, я надеюсь ответ ТС был дан.


PM MAIL   Вверх
sTa1kEr
Дата 10.12.2009, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 11
Всего: 146



Цитата(NewDima @  10.12.2009,  18:18 Найти цитируемый пост)
sTa1kEr, а вы пишете для версий ниже?!

Ну вопрос задал не я, а ТС и судя по
Цитата(MyDarkSide @  9.12.2009,  13:59 Найти цитируемый пост)
    // get_called_class() есть только в php >= 5.3
он пишет на версии ниже.

Добавлено через 1 минуту и 8 секунд
Но в этом нет ничего плохого, т.к. версия 5.3 еще очень сырая.
PM MAIL   Вверх
MyDarkSide
Дата 10.12.2009, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 21.3.2008

Репутация: -1
Всего: -1



Цитата(NewDima @  10.12.2009,  15:09 Найти цитируемый пост)
MyDarkSide, Зачем создавать тему, в которой потом не отписываешься? Нравится, когда пинают репутацию? 

вообще я работаю 8 часовой день, и отвечать ежечасно не могу, только вечером, днем если - только если свободная минута. к тому же обдумывал  свои варианты как извратиться. Пнуть ума большого не надо.

Цитата(NewDima @  10.12.2009,  17:18 Найти цитируемый пост)
awdev, а ты не заметил, что перед кодом я написал "как то так"? Это значит что это только смысл кода, почти псевдокод. Это одно. Другое: я ответил на вопрос топикстартера так, как он был поставлен, остальное - его проблемы.
sTa1kEr, а вы пишете для версий ниже?!

Добавлено через 4 минуты и 25 секунд
Вообще, создается впечатление, что большинство программистов пишут под четверку и даже горядтся этим... 

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


Цитата(awdev @  9.12.2009,  14:51 Найти цитируемый пост)
в чем вопрос? 

Кто виноват и что делать ? 
Виноват я (может нарушаю какие то концепции ООП) или ZendCo (не продумали)-на это наталкивает то что в 5.3 появилась функция get_called_class() ?

что делать: изначальная идея плохая и допиливать нет смысла или идея хорошая надо допиливать реализацию ?

Добавлено через 10 минут и 29 секунд
Цитата(awdev @  9.12.2009,  20:22 Найти цитируемый пост)
Вот так и создаются ### фрейморки
 
именно такие рамки и сподвигли написать своё. 
последнее время приходится много работать с cakePHP и больше всего бесит что, весь фреймворк типа ОО а данные из моделей возвращаются в виде ассоциативных массивов. И в итоге такой отстой получается: 
 
Код

$user = $this->User->getById(5);
$this->User->is_online($user['User']['id']);

//вместо очевидного
$user->isOnline(); 

вообще в чем основная фишка, из тех рамок что я сомтрел, никто не разделяет по сути два разных класса:
класс связанный с каким-то  единственным объектом реальности  (User, Post etc)  -  собственно модель, этот класс моделирует поведение объекта (метод isOnline()  )  ,    и класс-коллекция однородных классов-моделей, который занимается выборкой, сохранением, ассоциированием ит.д.  (метод getById() )


Это сообщение отредактировал(а) MyDarkSide - 10.12.2009, 18:13
PM ICQ   Вверх
NewDima
Дата 11.12.2009, 07:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

Репутация: нет
Всего: 12



Цитата(MyDarkSide @ 11.12.2009,  01:12)
вообще я работаю 8 часовой день, и отвечать ежечасно не могу, только вечером, днем если - только если свободная минута. к тому же обдумывал  свои варианты как извратиться.

это при том, что в других ветках ты участвуешь, а в своей нет?
PM ICQ   Вверх
MyDarkSide
Дата 11.12.2009, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 21.3.2008

Репутация: -1
Всего: -1



по большому в данном случае версия 5.3 не сильно спасет потому что, использование get_called_class все равно похоже на какой-то костыль. 
Т.е. когда речь идет о простых классах и членах, то класс-потомок переопределяет одноименные члены класса-родителя,  другие же наследует т.е. включает в себя. А со статическими членами - поведение почему то другое. И тут возникает вопрос - поведение от Zend'a (когда механизм наследования по сути не работает в статических членах ) - правильное и соответствует каким-то догмам ООП (может быть в других языках такая же ситуация), или это все-таки не доработки
PM ICQ   Вверх
awdev
Дата 11.12.2009, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 22.11.2009

Репутация: нет
Всего: 1



Цитата

когда механизм наследования по сути не работает в статических членах

Ну почему, работает, члены передаются потомкам, но получается их нельзя переопределить, и стат методы выполняются в контексте того класса, где они были объявлены изначально.
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Для профи | Следующая тема »


 




[ Время генерации скрипта: 0.0899 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.