execv
execv

Reputation: 859

PHP OOP: How Many Classes To Create

Currently, I've created 2 classes: Students and Courses. All we're going to focus on here are the proficiencies. So, each course_type has their own set of proficiencies (saved in course_proficiencies - and each course has a course type). Once a student signs up for a course, I want to be able to track how many proficiencies they have completed (once a student completes a proficiency, a row is added to student_proficiencies).

a schema http://slickrocksolutions.com/test/schema.png

Now.. In order to get proficiencies(and completed proficiencies), should I create a new class called StudentProficiencies with getCourseProficiencies() and getCompletedProficienciesByStudent($studentID), or, should I do something:

$course->getCourseProficiencies();
$student->getCompletedProficiencies($courseId);

And, how would you recommend me adding a proficiency? If I don't create a new class, it could be:

$student->completeProficiency($proficiencyId, $courseId);

Any thoughts?

Upvotes: 0

Views: 489

Answers (4)

Devendra D. Chavan
Devendra D. Chavan

Reputation: 9021

You have correctly identified the 2 data entities in your use case, viz. Student and Course. All other tables in your relationship are normalized forms of these 2 entities. Note that the syntax is in C#, please translate accordingly.

class Student
{
    // To uniquely identify each student. This is not the same as the id
    // that you use in your Student table. 
    public string RegistrationId {get; set;}
    public string FirstName {get; set;}
    public string LastName {get; set;}
    public Course Course {get; set;}
    public Proficiency {get; set;}

    // Get the list of courses completed by this student
    public IEnumerable<Course> GetCompletedProficiencies()
    {
        // ...
    }

    // Add a completed course
    public bool AddCompletedProficiency(Course completedCourse)
    {
        // ...
    }
}

class Course
{
    public string Id {get; set;}
    public string Name {get; set;}
    public string Location {get; set;}
    public string Type {get; set;}
}

Some changes are required in the database though. In the Student table, each student should be referred by an unique identifier that is decipherable to humans (hence the RegistrationId), this is not the same as the id that you use for maintaining the primary key of your Student table.

The ids that are used as primary keys are usually integers and are to be known only to the database system (and is usually an AUTOINCREMENT Integer field). The RegistrationId should be something that can include the University Name, School Name, Year of Admission, Alphabetical Order of Student's name, etc.

Same identification Id will also apply to the Course class.

The methods GetCompletedProficiencies() and AddCompletedProficiency() encapsulate the operations on the database.

A suggestion for OOP would be to be first to identify the classes in your use case or requirement, before going in for the database design part.

More information

Upvotes: 0

samtresler
samtresler

Reputation: 683

Three classes:

Student, Course, Proficiency

Course_type is a property of Course.

hash tables as follows: course_type_to_proficiency, course_to_student, course_to_course_type

I think that should allow you to do a Student method to look up proficiencies with a query similar to this:

Student->get_proficiencies( // connec to DB etc, 'SELECT cttp.proficiencies FROM course_type_to_proficiency cttp INNER JOIN course_to_course_type ctct ON cttp.course_type_id = ctct.course_type_id INNER JOIN course_to_student cts ON ctct.course_id = cts.course_id WHERE student_id = ###'

No need to make course type it's own class unless it doesn more than just join courses, students, and proficiencies. If you need to track a completed field per course, or course_type create another hash table with for that.

Upvotes: 1

Luc Laverdure
Luc Laverdure

Reputation: 1480

This is a matter of preferences, I prefer to use a class per general entity, going with Student and Courses was a good start.

If you find yourself having a method that does not relate to the object, creating a static object as a "toolbox" isn't a bad idea either to fetch students for example.

To get proficiencies(and completed proficiencies), I'd create methods for each class to obtain proficiencies that fetches from student_proficiencies and couse_proficiencies accordingly.

student_proficiencies and couse_proficiencies should however have a foreign key to a proficiencies table to avoid duplications if they are of same values.

Hope this helps.

Upvotes: 0

Uladzimir Pasvistselik
Uladzimir Pasvistselik

Reputation: 3921

I think you need such classes:

  1. Student
  2. Course
  3. CourseType
  4. CourseProfiency
  5. StudentProfiency

As for methods... Try write simple use-case for your model - it help you to see what interfaces (methods) your classes really need.


As for StudentProfiency. It can be implementation of Repository pattern, which helps you retrieve some class instances (concrete objects) by some concrete parameters.

Upvotes: 0

Related Questions