2012-01-04 2 views
3

У меня есть 3 таблицы:PHP OOP: создать новый класс?

users: 
id 
first_name 
last_name 

courses: 
id 
name 

student_courses: 
id 
student_id 
course_id 
paid 

пользователей отслеживает пользователей, курсы отслеживать курсы, и student_courses является таблица, которая показывает, что студенты подписались на какие курсы. В настоящее время у меня есть класс «пользователей» и класс «курсы». Мой вопрос: должен ли я создать класс StudentCourses для обработки взаимодействий для таблицы student_courses?

именно: мне нужно создать функцию, которая получает все курсы пользователь подписался на, помечать их как платные, и т.д.

Является ли это лучше всего сделать:

$student = new User($userId); 
$student->getCourses(); 
$student->markCourseAsPaid($courseId); 

ИЛИ

$student = new User($userId); 
$studentCourses = new StudentCourses($studentId); 
$studentCourses->markCourseAsPaid($courseId); 

т.д.

ответ

4

Если вы думаете о вашем student_courses и courses таблицы с точки зрения объектов, вы заметите, что student_courses - действительно интересная таблица, так как она содержит отдельные объекты для ученика. Это то, к чему вы хотите подключить свой объект Student. Что у вас есть в courses, теперь только non-changing part of a course , например, это имя и описание. Следовательно, ваши экземпляры StudentCourse могут просто агрегировать это. Вам нужно только один раз загрузить этот экземпляр, а затем поделиться им через StudentCourse случаи:

Student hasMany Courses hasOne CourseDescription

Для Cohesion, ваш метод markAsPaid должен быть на object with the most information required to fulfill it. Другими словами, это должно быть на Course. Тем не менее, вы можете добавить payForCourseproxy method на Студент, который затем называет markAsPaid по соответствующему Course. Возможно, вы захотите ввести класс Courses, который действует как Repository.

+0

Думаю, я понял, о чем вы говорите. Как бы вы рекомендовали подписать студента на курс со следующим: $ student = new Student ($ studentId); $ course = новый курс ($ courseId); – execv

0

Я бы не создать отдельный класс. Мой подход должен был бы использовать что-то вроде следующего:

$student = new User($userId); 
$course = new Course($courseId); 
$student->markCourseAsPaid($course); 

Как student_courses таблица просто просто отношения, не должно быть экстра класса. Дополнительный класс подразумевал бы, что это сущность, а это не так, это отношения.

Мой код отличается от вашего, так как я сначала извлекаю соответствующий экземпляр Course, а затем передаю этот экземпляр пользователю. По-моему, странно передавать только идентификатор курса, так как тогда объект User просто получает номер в качестве параметра, который вообще не имеет значения. Возможно, нам не нужен ID (первичный ключ) курса, а вторичный ключ. Тогда этот метод становится бесполезным, так как он ожидает ПК, а не какой-то СК. Поскольку я выбираю выбор объекта Course, у нас нет этой проблемы, так как объект курса знает, как получить правильный курс с помощью вторичного ключа.

Редактировать: Поскольку это объективированное отношение, может быть некоторый момент использования дополнительного класса. Но тогда я бы с другим подходом:

$studentCourse = new StudentCourse($studentId, $courseId); 
$studentCourse->markPaid(); 

Как и идентификатор студента и курса ID составляют для вторичного ключа таблицы, они оба должны быть указаны в конструкторе.

+0

Не выбрасывать строку 2 и '$ student-> markCourseAsPaid ($ courseId);' быть лучшим выбором ... не нужно загружать информацию о курсе (в комплекте с отключением базы данных) для этой команды, если только ' новый курс ($ courseId); 'использует ленивую загрузку (что фактически то же самое, что не создает ее) – Rudu

+0

@Rudu да, я работал над этим объяснением;) Я действительно ожидаю, что классы ORM будут достаточно умными, чтобы не загружать значения до тех пор, пока они действительно запрашиваются. – Joost

0

В этом случае это похоже, что либо может работать.

Обычно вы должны сделать каждую модель/таблицу классом (например, студентом, курсом, пользователем и т. Д.) В парадигме MVC (model-view-controller). Тогда в каждом классе у вас может быть переменная, чтобы связать их. Я не вижу необходимости в классе StudentCourses, даже если структура таблицы показывает отношения, в которых нет необходимости в другом классе. Первый пример выглядит более объектно ориентированным на меня. Снова вы можете сделать это в любом случае, но я всегда выбираю более объектно-ориентированный код.

3

Если вы собираетесь расширить приложение в будущем, я бы создал отдельный класс для StudentCourse. Теперь у него есть только один дополнительный атрибут, кроме атрибутов соединения (оплачивается), но когда вам нужно будет добавить другие атрибуты, вы все равно будете создавать этот класс.

0

Я бы создал третий класс для course_student, который полагался бы на table на вашу базу данных И view по следующей причине, разделяя проблемы.

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

Ваше мнение будет состоять из всех соответствующих полей обеих таблиц (с использованием 2 inner join) (студенты и курсы), основанные на отношениях в вашей course_student таблице

Строка будет выглядеть следующим образом:

student_id, student_first_name, student_last_name, courses_id, courses_name, is_paid 

Если вы хотите, чтобы все учащиеся проходили курс, вы можете получить метод с именем getStudentsByCourse(courseId).

Если вы хотите получить все курсы конкретного учащегося, у вас может быть метод с именем getStudentCourses(studentId).

Если вам необходимо зарегистрировать набор студентов на курс (или много), вы можете иметь метод, названный setStudentsCourses(studentId, courseId) (где оба параметра могут быть как целые или массив.

Смежные вопросы