Вопрос

Lets say I am creating an API for class University to create a Class. (This Class has Class name, Teacher and students).

eg:

class Class{
       .. 

       private:
         std::string class_name_;
         Teacher teacher_;
         std::vector<Student> students_;
     };

    class University{
     public:   
       //API 1      
       void CreateClass(const std::string&, Teacher, std::vector<Student>);

       //API 2      
       void CreateClass(const std::string&, Teacher);

       //API 3      
       void CreateClass(const std::string&);      

         private:
        std::vector<Class> classes_;
        ..
    };

Think of Class just like normal Class that are in typical University.

Do you think it is rational to have API2 and API3? I asked this question because when I started creating class University, I started up with API1. Then during the middle of my project I realized I need API2 and API3 because, I was parsing class information from file (This file contains information on class) and I could not have all the information at one go during the parsing the file. So, I thought of creating an empty class with just a Class name first then add student and teacher latter to that specific class as I go parsing further through the file.

Another question: Is it against object oriented design principle to have Class with just name? I ask this because normally Class have teacher and students then only its called a Class.

Also in future, some one could misuse the API3 to create a class that is empty and never bother to populate the teacher and students, this leave the Class empty.

Это было полезно?

Решение

This really depends on the requirements that you have for the “Class” that you’re modelling.

If you expect a class to exist without having any students assigned to it, then it would make sense to have that parameter be optional in the constructor (API 2). Users of “Class” should be made aware that the member variable ‘students’ can be empty;

If you expect a class to exist that exist that may not have a teacher assigned for a period of time, then it would make sense to have that parameter also be optional (API 3). Users of “Class” should be made aware that ‘teacher_’ can be null (or have a value that represents null);

On the other hand, if you expect every member variable in “Class” to have a meaningful value at all times, then you should only implement a constructor that requires all of the variables to be set (API 1 in this case).

Since you say in your question “Also in future, some one could misuse the API3 to create a class that is empty and never bother to populate the teacher and students, this leave the Class empty.” This to me means that you want “Class” to ALWAYS contain meaningful data. You actually consider API3 to be abuse of the class.

Because of this, you should really only have API1. If you want, you could add default arguments to “Class” so that, while you can instantiate a new “class” with only one parameter, the rest will at the very least have an actual value at all times.

As far as file parsing goes, just hold the values you want in a separate variable until you're FULLY ready to instantiate the class

for example:

 std::string className = file.GetName();
 ...
 Teacher teacher = file2.GetTeacher();
 ...
 std::vector<Student> students = file3.GetStudents();
 //Now that we have all the data, we can properly instantiate the class
 Class newClass = Class(className, teacher, students);

Другие советы

It depends on how you want your system to function.

If you can have a Class with just a name, and no teacher or students, then the CreateClass(string) method is appropriate. That leaves the possibility, as you mention, for the Class never getting a Teacher or Students. If you need to have a Teacher for the class, then CreateClass(string, Teacher) is appropriate, but CreateClass(string) is not. If you require a name, Teacher, and at least 1 student, then only the first is appropriate.

Your University here is, in function, a ClassFactory (at least as written). The purpose of a factory class is to take valid input(s) and create a new object (in your case, a Class object). Only you know what those valid inputs are, though. You may want to read more about the factory pattern.

As written, you have not provided any way of setting the properties of the Class class, so it's hard to tell what your intentions are. Will a Teacher be assigned later? Or can the Teacher be changed from the initial one? Can Students enroll in the Class later, or must you know who will sign up for the Class before you create it (seems unlikely)? How will a user or developer create these Classes, and what information will you have from them? Once you answer those questions and others, the necessary method(s) should become much more clear.

There's nothing inherently wrong (OOP-wise) from having a Class with just a name, but no Teacher or Students. Those are constraints derived from your requirements. Lots of objects have empty or null properties, or lists / sets with no elements. Hell, some objects could even have empty string properties, and nothing is wrong OOP-wise.

The key to this is knowing what is a valid state for the Class object, and verifying that such an object is in a valid state before using it (e.g., making sure it has a Teacher and at least 5 Students, as well as a non-empty and unique name).

Лицензировано под: CC-BY-SA с атрибуция
scroll top