Глобальные объекты и архитектура

Темы, не касающиеся фреймворка, но относящиеся к программированию в целом.
Ответить
Dr0ID
Сообщения: 27
Зарегистрирован: 2010.04.04, 20:02
Откуда: Новосибирск
Контактная информация:

Глобальные объекты и архитектура

Сообщение Dr0ID »

Голова уже кругом идет, не могу сообразить как лучше сделать архитектуру.
Вообщем есть 2 модели companyModel и employeeModel которые должны быть доступны во всех моделях. Сейчас они инициализируются в WebUser::init, т.к. они базируются на данных юзера. Ну и соответственно в моделях я их получаю Yii::app()->user->getEmployee() и Yii::app()->user->getCompany().
Но проблема возникла, когда начал покрывать код юнит-тестами. Да и по-моему это как-то не правильно :cry:

Так где их лучше хранить? Сделать что-то типа Registry и инициализировать их там?
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Глобальные объекты и архитектура

Сообщение slavcodev »

а приатачить компонент к приложению нет?
Yii::app()->company, Yii::app()->employee
Жду Yii 3!
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: Глобальные объекты и архитектура

Сообщение pirrat »

я думаю что атачить к приложению не совсем правильно - объекты, как я понимаю, зависят от состояния модели User, а не приложения, там они и должны находится.

только я не совсем понял зачем вы их к WebUser приатачили.

У вас скорее всего есть объект конкретного пользователя User, к нему и надо атачить (через отношения например) эти модели, а не к объекту "Посетитель" (WebUser).

Тестировать эти модели как и любые другие.

получать чуть сложнее, чем вы описали:
Yii::app()->getUser()->model()->getCompany();
где model() возвращает объект конкретного пользователя, ну или исключение, если он не авторизирован.

если для вас слишком длинная такая запись, то можно хелпер написать:
что-то типа UserHelper::getCompany();
Dr0ID
Сообщения: 27
Зарегистрирован: 2010.04.04, 20:02
Откуда: Новосибирск
Контактная информация:

Re: Глобальные объекты и архитектура

Сообщение Dr0ID »

Текущий юзер === посетитель, поэтому я так и сделал. От этого зависит как будут вести себя другие модели. В них активно используются эти объекты.
Наверное сделаю компонент Registry на основе CMap в котором буду хранить эти глобальные объекты.
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: Глобальные объекты и архитектура

Сообщение pirrat »

Registry - зло, тем более в этом контексте.
Я не знаю как у вас построена архитектура, но предположу что она не сильно отличается от обще-принятых практик.

Как я вижу правильно спроектированное приложение:

employee(сотрудник) - объект, представляет конкретного сотрудника (в нашем случае, это будет объект ActiveRecords).
company (компания) - объект компании (ActiveRecords).

между employee и company отношение один ко многим, т.е. каждый конкретный сотрудник, относится к какой либо компании.

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

WebUser может менять свое состояние, например при авторизации пользователя, у объекта WebUser меняется роль, устанавливается id конкретного сотрудника и тд.
При условии что пользователь авторизовался и объект WebUser принял нужное состояние мы можем из него получить объект конкретного сотрудника (employee).

Код: Выделить всё

Yii::app()->user->getEmployee(); 
//или 
Employee::model()->findByPk(Yii::app()->user->getId()); 
в случае если WebUser имеет состояние не авторизированого пользователя, то мы не можем получить из него объекты сотрудника и компании.
поскольку в компании может быть только конкретный сотрудник, то и получить компанию сотрудника мы можем только через модель 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()); 
работать в модели Finance напрямую с текущем пользователем, как я уже сказал, в корне не верно, а правильнее передеавать ей нужный объект.
Dr0ID
Сообщения: 27
Зарегистрирован: 2010.04.04, 20:02
Откуда: Новосибирск
Контактная информация:

Re: Глобальные объекты и архитектура

Сообщение Dr0ID »

Спасибо, кажется понял :)
Ох, сколько же будет рефакторинга :shock:
Ответить