Взаимодействие объектов

Wsc

Guest
Взаимодействие объектов

Опять же вопрос про взаимодействие объектов.
пример для онлайн-тестирования(упрощенно).
Допустим есть сущности: вопрос, ответ, тест, прогресс, протокол, пользователь.
Все они завязаны между собой, вариант как было написано в соседней ветке, типа:

$test=new Test($_GET['id']);
$user=new TestUser($_GET['uid']);
$progress=new Progress($test->getVar('tid'));
$progress->setVar('user_id',$user->getVar('user_id');
$progress->store();

мне не очень нравится.

Как я сделал.
написал малюсенький класс-фэктори, который либо инициализирует объект, либо возвращает экземпляр объекта в случае его существования.

т.е. примерно так:
class TestFactory{

function &getClass($name,$parameter=null){
static $instances;
if (!isset($instances[$name])) {
$class = ucfirst($name);
$instances[$name] = new $class($parameter);
}
return isset($instances[$name]) ? $instances[$name] : false;
}

Соотв. теперь иниц. объекты через фабрику, т.е.
$test=&TestFactory::getClass("Test",$_GET['id']);
$testuser=&TestFactory::getClass("TestUser",$_GET['uid']);
$progress=&TestFactory::getClass("Progress",$test->getVar('tid'));
$progress->store();

а в классе Progress я назначаю свойства объекта вида:

class Progress {
function Progress($id=null){
$this->test=&TestFactory::getClass("Test");
$this->user=&TestFactory::getClass("TestUser");
.....
}

и соотв. имею доступ ко всем свойствам и методам этих ранее объявленных и инициализированных классов внутри класса Progress.

Извиняюсь за длинное повествование, но хотелось бы услышать мнение завсегдатаев форума и остальных посетителей.
 

Serguitar

Новичок->продвинутый
Wsc
Ты хочешь услышать мнение правилен ли твой подход? Я бы сделал по другому.
 

wrapper

Guest
$test=new Test($_GET['id']);
$user=new TestUser($_GET['uid']);
$progress=new Progress($test->getVar('tid'));
$progress->setVar('user_id',$user->getVar('user_id');
$progress->store();

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

Wsc

Guest
Автор оригинала: wrapper
а чем не нравится, слишком просто?
Нет, не нравится тем, что при таком подходе происходит излишнее дублирование информации. объект должен представлять интерфейс для взаимодесвтия с другими объектами.
допустим, в классе Progress есть метод CheckAnswer, проверяющий правильность ответа, если следовать логике указанной выше, то перед вызовом этого метода мы должны назначить св-вам объекта Progress значения св-в соответсвующих объектов Test и Answer.
т.е.
$progress->setVar('required_right_answer',$test->getVar('required_right_answer'));
$progress->setVar('answer_right',$answer->getVar('answer_right'));

что порождет дублирование св-в в классах Progress и Test, а именно св-ва required_right_answer.
 

wrapper

Guest
Есть такой паттерн: работу выполняет тот класс который имеет больше всего знаний необходимых для этого. В данном случае нужно создать класс Answer который будет содержать вопрос, правильный ответ и метод для проверки правильного ответа. Так что ты сам создал проблему плохой архитектурой и теперь ее решаешь :)
 

Wsc

Guest
Будем исправлять последствия :)
Спсб.
Хотя вот такой еще аспект:
методы - ПолучениеКоличестваСданныхТестов, ПолучениеКоличестваСданныхТестовпоКатегории к какой сущности должны относиться?
ведь все данные о сданных тестах находятся в таблице protocols и вроде бы как по идее должны относиться к классу Protocol?
 

wrapper

Guest
ну да, по идее к нему :)
а вообще оптимальное распределение обязанностей приходит в процессе разработки
 

Wsc

Guest
Автор оригинала: wrapper
ну да, по идее к нему :)
а вообще оптимальное распределение обязанностей приходит в процессе разработки
Согласен, когда есть несколько путей ведущих к решению поставленной задачи это тоже неплохо.
Задача - выбрать самое оптимальное из них.
 
Сверху