Архитектура и ООП

spiverg

Новичок
Архитектура и ООП

Правильна ли следующая архитектура с точки зрения ООП:
Есть абстрактный класс ModelUser, через методы которого потомки этого класса, получают данные из источника данных
упрощенно класс выглядит примерно так
PHP:
abstract class ModelUser {
    protected $db = null;   // ссылка на объект предоставляющий интерфейс к СУБД
    /**
    * array getDataUser(int $id)
    * возвращает данные пользователя с идентификатором $id
    */
    public function getDataUser($id) {
        return $this -> db -> queryFetch("SELECT id, name, descr, extract(EPOCH FROM date0) AS datet FROM siteuser WHERE id=?", $id);
    }
...далее другие методы к источнику данных в моем случае к СУБД
}
И скажем его потомок
PHP:
class User extends ModelUser {
    private $view    = null;    // ссылка на объект шаблонизатор
    /**
    * конструктор инициализируем через фабрику нужные звездные классы
    */
    public function __construct() {
        $this -> factory = Factory :: getInstance();
        $this -> view = $this -> factory -> getView();    // getView() создает объект класса View и возвращает ссылку на объект
        $this -> db   = $this -> factory -> getDB();    // getDB() создает объект класса DB и возвращает ссылку на объект
    }
    /**
    * string showUser(int $id)
    * отображение данных пользователя с идентификаторм $id
    */
    public function showUser($id) {
        $data_user = $this -> getDataUser($id);
        ... далее используем шаблон и возвращаем результат его работы
    }
}
Все отлично работает, но я все затачиваю под ООП, и меня смущает следующий момент, в ModelUser мы используем $db, которое инициализируется в дочернем классе, получается так, что методы родительского класса используют свойство, которое определяется в классе-потомке, но с другой стороны ModelUser, является абстрактым классом и напрямую не используется.
 

dr-sm

Новичок
блин, у ооп нет точки зрения :), не надо под него ниче затачивать, это концепция :).

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

spiverg

Новичок
блин, у ооп нет точки зрения , не надо под него ниче затачивать, это концепция .
игра слов, задам вопрос по другому, соответстует ли данная архитектура концепции ООП?
значит его (свойство) нужно инициализировать в конструкторе базового класса.
мне так неудобно, тот же parent :: __construct, хотя есть и другие причины
 

rotoZOOM

ACM maniac
spiverg неудобно носки на ушах сушить - и мокро и слетают. Полностью согласен с dr-sm. И еще фабрика какая-то у тебя интересная ... многопрофильная.
 

spiverg

Новичок
rotoZOOM
неудобно носки на ушах сушить - и мокро и слетают.
Это значит не соответствует ООП?

С фабрикой все отлично и у меня вопрос был не по ней будем считать что у класса User, конструктор такой:
PHP:
    public function __construct(MyClassDb $db, MyClassView $view) { 
        $this -> db   = $db;
        $this -> view = $view;
    }
 

StUV

Rotaredom
по крайней мере, для обеспечения некоторой "прозрачности" оо-модели - необходимо в родительском методе определить метод получения коннекта к бд, можно абстрактный, а в конструкторе воспользоваться им для инициализации внутренней переменной

соответственно в классах-потомках этот метод можно или имплементировать (если базовый абстрактный), или переопределить (если в этом _действительно_ есть необходимость)

-~{}~ 04.06.08 08:56:

зы:
интересно, цель всего этого - разные способы инициализации $db в разных потомках.... - так ? =)
 

spiverg

Новичок
интересно, цель всего этого - разные способы инициализации $db в разных потомках.... - так ? =)
не совсем, $db будет разным в разных компонентах(в данном случае под компонентом понимается ModelUser, User и шаблоны, контроллеры также реализованы методами User) $db в разных компонентах будет различными объектами одного класса(если одна СУБД, но разные БД), или объектами разных классов(разные СУБД), со вторым случаем на практике еще не сталкивался, а с первым столкнулся. Даже есть компоненты которые сразу работают с двумя БД.
Создание этих объектов, реализовано через методы фабрики, фабрика для удобного доступа к ней является синглетоном, например getDBFirst, всегда возвращает объект для работы с одной БД, а getDBSecond с другой

PHP:
    /**
    * object getDBFirst( void )
    * возвращает ссылку на объект для работы с первой БД
    */
    public function getDBFirst() {
        return new DB(DB_HOST_1, DB_PORT_1, DB_NAME_1, DB_USER_1, DB_PASSWORD_1, DB_DEBUG_MODE_1, DB_CACHE_1, DB_QUOTES_1);
    }
    /**
    * object getDBSecond( void )
    * возвращает ссылку на объект для работы со второй БД
    */
    public function getDBSecond() {
        return new DB(DB_HOST_2, DB_PORT_2, DB_NAME_2, DB_USER_2, DB_PASSWORD_2, DB_DEBUG_MODE_2, DB_CACHE_2, DB_QUOTES_2);
    }
Эти методы вроде оберток, для создания нужных объектов, вы мне предлагаете инициировать т.е. создавать объект в модели, то в модель предлагается добавить что-то вроде:
PHP:
    public function __construct() {
        $this -> defineDB();
    }
    protected function defineDB() {
        $this -> db   = Factory :: getInstance() -> getDBDefault();
    }
StUV я правильно понял?
 

StUV

Rotaredom
StUV я правильно понял?
вроде того

-~{}~ 04.06.08 11:49:

+
можно сделать в паренте
abstract protected function defineDB();

чтобы в каждом конкретном классе потомке было очевидно какая из баз используется - причем в "обязательном" режиме

но... это все уже "дело вкуса" =)
 

spiverg

Новичок
да согласен, через абстрактный метод будет лучше, сам по себе он будет намекать что есть какое-то определение источника данных(хотя на самом деле будет определение класса через который будет производиться работа с этим источником данных), плюс не будет зависимости между классами ModelUser и Factory, с классом Factory будет работать только User, плюс гарантированное переопределение этого метода обеспечит наглядность с чем работает конкретный потомок

тему можно закрывать
 

alexey84

phplancer
spiverg
извиняюсь вопрос не в тему, просто очень заинтересовал запрос
SELECT id, name, descr, extract(EPOCH FROM date0) AS datet FROM siteuser WHERE id=?
extract(EPOCH FROM date0) - это че значит?
 

spiverg

Новичок
я использую постгрес, поле date0 в таблице siteuser имеет тип timestamp without time zone.
В данном случае extract(EPOCH FROM date0) используются для того чтобы получить значение date0 в формате unix timestamp, далее где нибудь в шаблоне date('d.m.y', $datet).
Конечно можно сделать TO_CHAR(d.date0, 'DD.MM.YYYY'), но тогда получится отображение даты мы определяем не в шаблоне, а в модели, хотя в моей системе используется и не совсем MVC, но все равно формат вывода даты и времени нужно устанавливать в шаблоне, а не в запросах, конечно это мое мнение.
 
Сверху