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.
-
3a class Class with a class_name "class"Ewan– Ewan10/17/2017 19:59:46Commented Oct 17, 2017 at 19:59
-
1She sells sea shells by the sea shore.Robert Harvey– Robert Harvey10/17/2017 20:35:51Commented Oct 17, 2017 at 20:35
-
lesson more or less learnedvanta mula– vanta mula10/18/2017 03:15:06Commented Oct 18, 2017 at 3:15
2 Answers 2
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);
-
I was worried about holding the values because I thought it would take extra memory. I guess that is the trade off we get from restricting the API.vanta mula– vanta mula10/18/2017 03:01:59Commented Oct 18, 2017 at 3:01
-
1@vantamula You are right that it will take extra memory, but for values like these, I wouldn't worry about it. You should have more than enough available to handle this case. Still though, you're right, it is a tradeoff. As with every tradeoff, you need to decide if a cleaner interface is worth the cost of extra memory. Personally, I think it is :)Ryan– Ryan10/18/2017 12:19:28Commented Oct 18, 2017 at 12:19
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).
-
Thank you for your response and comment on how to articulate the character of object. Just a side question so any user defined class that creates another user defined class is factory you mean?vanta mula– vanta mula10/18/2017 03:04:15Commented Oct 18, 2017 at 3:04
-
Also another hypothetical problem I could get is if the
class Class
is allowed to remove student. One can remove the student one by one until there is not student left in the class. To address this problem, I was thinking of throwing exception if the students are less then 2. So either the Class object or stop deleting student more then it is allowed to.vanta mula– vanta mula10/18/2017 03:34:49Commented Oct 18, 2017 at 3:34 -
* So either deleting the Class objectvanta mula– vanta mula10/18/2017 03:44:07Commented Oct 18, 2017 at 3:44
Explore related questions
See similar questions with these tags.