Create an API fro University to create a Class
https://softwareengineering.stackexchange.com/questions/359296
-
21-01-2021 - |
문제
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).