Голова уже кругом идет, не могу сообразить как лучше сделать архитектуру.
Вообщем есть 2 модели companyModel и employeeModel которые должны быть доступны во всех моделях. Сейчас они инициализируются в WebUser::init, т.к. они базируются на данных юзера. Ну и соответственно в моделях я их получаю Yii::app()->user->getEmployee() и Yii::app()->user->getCompany().
Но проблема возникла, когда начал покрывать код юнит-тестами. Да и по-моему это как-то не правильно
Так где их лучше хранить? Сделать что-то типа Registry и инициализировать их там?
Глобальные объекты и архитектура
- slavcodev
- Сообщения: 3134
- Зарегистрирован: 2009.04.02, 21:42
- Откуда: Valencia
- Контактная информация:
Re: Глобальные объекты и архитектура
а приатачить компонент к приложению нет?
Yii::app()->company, Yii::app()->employee
Yii::app()->company, Yii::app()->employee
Жду Yii 3!
Re: Глобальные объекты и архитектура
я думаю что атачить к приложению не совсем правильно - объекты, как я понимаю, зависят от состояния модели User, а не приложения, там они и должны находится.
только я не совсем понял зачем вы их к WebUser приатачили.
У вас скорее всего есть объект конкретного пользователя User, к нему и надо атачить (через отношения например) эти модели, а не к объекту "Посетитель" (WebUser).
Тестировать эти модели как и любые другие.
получать чуть сложнее, чем вы описали:
Yii::app()->getUser()->model()->getCompany();
где model() возвращает объект конкретного пользователя, ну или исключение, если он не авторизирован.
если для вас слишком длинная такая запись, то можно хелпер написать:
что-то типа UserHelper::getCompany();
только я не совсем понял зачем вы их к WebUser приатачили.
У вас скорее всего есть объект конкретного пользователя User, к нему и надо атачить (через отношения например) эти модели, а не к объекту "Посетитель" (WebUser).
Тестировать эти модели как и любые другие.
получать чуть сложнее, чем вы описали:
Yii::app()->getUser()->model()->getCompany();
где model() возвращает объект конкретного пользователя, ну или исключение, если он не авторизирован.
если для вас слишком длинная такая запись, то можно хелпер написать:
что-то типа UserHelper::getCompany();
Re: Глобальные объекты и архитектура
Текущий юзер === посетитель, поэтому я так и сделал. От этого зависит как будут вести себя другие модели. В них активно используются эти объекты.
Наверное сделаю компонент Registry на основе CMap в котором буду хранить эти глобальные объекты.
Наверное сделаю компонент Registry на основе CMap в котором буду хранить эти глобальные объекты.
Re: Глобальные объекты и архитектура
Registry - зло, тем более в этом контексте.
Я не знаю как у вас построена архитектура, но предположу что она не сильно отличается от обще-принятых практик.
Как я вижу правильно спроектированное приложение:
employee(сотрудник) - объект, представляет конкретного сотрудника (в нашем случае, это будет объект ActiveRecords).
company (компания) - объект компании (ActiveRecords).
между employee и company отношение один ко многим, т.е. каждый конкретный сотрудник, относится к какой либо компании.
WebUser - представляет состояние текущего пользователя, это может быть как авторизованный пользователь, гость, поисковый бот и тп.
WebUser может менять свое состояние, например при авторизации пользователя, у объекта WebUser меняется роль, устанавливается id конкретного сотрудника и тд.
При условии что пользователь авторизовался и объект WebUser принял нужное состояние мы можем из него получить объект конкретного сотрудника (employee).
в случае если WebUser имеет состояние не авторизированого пользователя, то мы не можем получить из него объекты сотрудника и компании.
поскольку в компании может быть только конкретный сотрудник, то и получить компанию сотрудника мы можем только через модель Employee, а у WebUser нет ни какой компании.
т.е. компанию сотрудника мы можем получить так:
далее вы пишите: другие модели работают с компанией и объектом сотрудника текущего пользователя.
так вот работать в моделях c объектом WebUser неверно, так как этого объекта может вообще не существовать (консольное приложение).
правильнее сказать что эти модели взаимодействуют (имеют отношения) с моделями компании и сотрудника.
допустим есть объект (модель) Finance(финансы).
эта модель может работать с моделью сотрудника.
допустим нам из нее надо получить зп текущего сотрудника:
работать в модели Finance напрямую с текущем пользователем, как я уже сказал, в корне не верно, а правильнее передеавать ей нужный объект.
Я не знаю как у вас построена архитектура, но предположу что она не сильно отличается от обще-принятых практик.
Как я вижу правильно спроектированное приложение:
employee(сотрудник) - объект, представляет конкретного сотрудника (в нашем случае, это будет объект ActiveRecords).
company (компания) - объект компании (ActiveRecords).
между employee и company отношение один ко многим, т.е. каждый конкретный сотрудник, относится к какой либо компании.
WebUser - представляет состояние текущего пользователя, это может быть как авторизованный пользователь, гость, поисковый бот и тп.
WebUser может менять свое состояние, например при авторизации пользователя, у объекта WebUser меняется роль, устанавливается id конкретного сотрудника и тд.
При условии что пользователь авторизовался и объект WebUser принял нужное состояние мы можем из него получить объект конкретного сотрудника (employee).
Код: Выделить всё
Yii::app()->user->getEmployee();
//или
Employee::model()->findByPk(Yii::app()->user->getId());
поскольку в компании может быть только конкретный сотрудник, то и получить компанию сотрудника мы можем только через модель Employee, а у WebUser нет ни какой компании.
т.е. компанию сотрудника мы можем получить так:
Код: Выделить всё
Yii::app()->user->getEmployee()->getCompany();
//или
Company::model()->findByEmployee(Yii::app()->user->getEmployee());
так вот работать в моделях c объектом WebUser неверно, так как этого объекта может вообще не существовать (консольное приложение).
правильнее сказать что эти модели взаимодействуют (имеют отношения) с моделями компании и сотрудника.
допустим есть объект (модель) Finance(финансы).
эта модель может работать с моделью сотрудника.
допустим нам из нее надо получить зп текущего сотрудника:
Код: Выделить всё
//$company->getFinance() - возвращает объект финансов конкретной компании
$company->getFinance()->calcSalaryForEmployee(Yii::app()->user->getEmployee());
Re: Глобальные объекты и архитектура
Спасибо, кажется понял
Ох, сколько же будет рефакторинга
Ох, сколько же будет рефакторинга