I've got faced with this very basic thing multiple times now, but I never knew how to solve it in the most efficient way.
I have a class 'Student' and a class 'Course'. The student should know all of his courses he visits by a list of courses, and the course should know all the students wich are visiting it by a list of students.
Now let's say I want a student to visit a new course, so I create an 'addCourse(Course course)' method to add a new course to the student's list of courses - no problem. But I also want the course to know about the student is visiting it now. So I create a 'addStudent(Student student)' method for the course class and call it in the student's 'addCourse' method.
The problem is: I want to make those data updates possible from both sides - the students and the courses, but if I would add the respective other method into the own method, I would end up in a stack overflow of course. So how can I prevent this most efficiently?
Also if I store this data in objects of both classes, I guess I would flood my memory with more data than I need. Is there a way to prevent this too without losing access to data?
You have a Student class that has an AddCourse method, which updates the list of courses that the student visits.
You have a Course class that has an AddStudent method, which updates the list of students who are visiting the course.
Somewhere else in your program, you decide that the student is going to visit a course. For example, there might be a user interface that the student interacts with if he wants to join a course. That user's action should trigger a call to some business logic that does everything required to add the student to the course. For example:
function AddStudentToCourse(studentId, courseId)
{
student = GetStudentById(studentId);
student.AddCourse(courseId);
course = GetCourseById(courseId);
course.AddStudent(studentId);
}
The point here is that as far as the Student is concerned, it just maintains a list of course Id numbers. The Student class doesn't actually do anything with the courses; it just maintains the list so that some other piece of code can refer to it later.
Same for the Course; it just maintains a list of student Id numbers.
The beauty of this design is that Student and Course are independent of each other, except for those lists of ids; and those are really just numbers.
I won't say that this is "the most efficient" way to do it. It does work well, though.
Related
After working with MVC for a long time, I decided to go with MVVM. I understood the basics of the pattern and got through multiple articles that explain that MVVM is waaay better then MVC any day. And I am okay with that.
I decided to make my own app in order to set my mind correctly for logic behind MVVM. So I created basic app that does follow MVVM principles and after a while I found the problem that you see in the title.
So, basically, this is the problem. Let's say that I have one object, call it Person. Person have name and surname. But when I want to show details about that person, I will have address, phone numer etc. Because one person can have many phone numbers I will have something from API that link to the user ID.
So we came to my question. If I have some basic information about some model, and want to have detail information about that same model, where do I keep ID (or link) for that detail information? Do I have to keep it inside view controller, which would be just wrong? Or do I keep it inside view model, even if I don't use it really on user interface?
The ID also belongs to the model class. ie If you have an object Person then simply create a data class Person, which will obviously include all the members say ID, Name, Address, Number and so on. You can identify each person using the same ID as well.
The View Model need not always know about the ID. If you have a list of Person objects in view model, then you could easily map each item using the ID. Additionally if you want to have currently selected item or something, you could map it to viewmodel property of that object type ie Person. So you need not keep a PersonID field in ViewModel unless it is absolutely required for some rare cases.
Sorry, but I did not understand this : So basically in prepareForSegue method I could say something like give me from current VM object at particular index and create VM for new view that I will actually send ?
As far as simple applications are concerned, the above approach is more than enough. But in some rare cases, you may need to keep the current selected item's ID in the view model. So if you're using a list and keeping a property for selected item, it may not be the type of that list ie Person. Instead it could be the ID alone.
Hope you got the point.
I have two questions on how the MVC works. I'm pretty sure I should add several resources, but I'm just coming to this conclusion and wanted to ask first to get a better understanding.
First question:
I have two models, user and subject. Users can enter subjects into the database. For each subject there are 5 data entry forms (Baseline, 3month, 6month,...) that are about 100-200 questions each (The relationship would be each subject has 1 of each data entry form). Should each data entry form be a new resource?
Second Question:
Lets say I want to randomize a few subjects into a group:
From the view, the user enters the amount of subjects to be randomized into a group, as well as the group name to be assigned. The form tag specifies an action I created, just for this function, called randomize.
From the controller, randomize uses the params sent from the view to query the database, and then to update each record to reflect the group. Instead of creating a new action for the randomize function, should I create a new resource for it? And as a side note, should any of these calculations be done in the model (other than defining the variables)?
Thank you for your time. Any help would be greatly appreciated. I am officially over-whelmed by all of the information I'm learning about this...but I feel that I'm really close to actually understanding the MVC.
I'll answer your second question first.
You should be creating controllers to handle CRUD tasks for resources. In this question you ask about creating a "Group". Regardless of whether this is an actual resource, or just a modification to a collection of other resources, you have the concept of creating a "Group", probably reading/updating a "group" and certainly deleting one.
Based on this, I would rather have a RandomGroup controller which I can call using a standard REST interface, rather than some #randomize action stuffed in the side of another controller.
As for your first question ... maybe, maybe not.
It really depends on whether an data entry form has any business logic of its own. If it doesn't then there's no harm it being part of a large object. But if your tests and code start to become too complex within the Subject model you may want to split it out into multiple models or at least multiple modules included into that model.
Perhaps you could consider that "Baseline", "3month", "6month" are all the same ... aside from their lead time. Perhaps that is a model in itself, and Subject could has_many :forms ??
Food for thought.
I am having a confusion regarding object modeling, which I will illustrate using a simple lending library project.
The library has books (one copy for each book to keep things simple) and patrons. Patrons can loan a book, if that book is not loaned to another patron.
This will need 3 classes, Book, Patron and Loan.
Book will have an id and a name. Patron will have an id and name. Loan will have an id, book_id, patron_id and loan date.
Where will the loan and return method be defined? Is this a method of book, patron or loan object?
Book is the one getting lended, patron is the one who lends the book and loan is the one who keeps all details about the particular lending operation.
Why is Loan class really needed? Of course the DB table is needed with the fields mentioned above, but from an MVC framework perspective (eg: Symfony or Rails) should this be defined as a model?
I know this is a simple and solved problem, but after being out of touch with oop design for long, I am not quote able to "view" this problem correctly!
Make a class that is responsible for creating a Loan object. You could call this LoanCreator or if it is helpful for you to think of it in the following way you could call it Librarian. You would pass this new class a Book and a Patron object and it would create the Loan for you. Generally if you find yourself unsure if a method should belong to a particular class then perhaps it is time to consider creating a new class.
In my point of view you need 2 classes
Book
Patron
and
loan and return methods should go into Book class as those operations are happening to books. But as you said there should be a different loan table to keep these records.
When coming back to MVC, they should be implemented as models.
I'm finding a good way to modeling User different types in the system. For registration, he/she can select to be a student, a mentor, or both. Being a student or a mentor has different set of properties. Student and mentor will have different profile template layout as well.
How would you design your controllers and models for this kind of problem?
I would create a User which can hold a Mentor class and/or a Student class. This way your different properties are seperated from each other while the same properties still remain in the User class.
In the Controller you can render a template (or partial), depending on the instance the User holds. One for students, one for mentors and one for both.
You could also use Inheritance (User as parent with Mentor, Student and Both as childs). The key word you want to look into here is Single Table Inheritance.
Imho the problem is the both option. That's why I would prefer the 1st solution.
Lets say there is a activerecord class called user, which is representative of user table of database.
But I have different type of users which have
special functions
special variables
custom relations (Employer has_many companies, Employee belongs_to company :)
But also these users have a lot of functionality in common. So what I want to do is create classes for each different type of user then inherit them from user class.
User < ActiveRecord::Base
Employer < User
Employee < User
Customer < User
What is the best way of doing something like that?
Thanks
A lot of applications start out with a User model of some sort. Over time, as different kinds of users emerge, it might make sense to make a greater distinction between them. Admin and Guest classes are introduced, as subclasses of User. Now, the shared behavior can reside in User, and subtype behavior can be pushed down to subclasses. However, all user data can still reside in the users table.
All you need to do is add a type column to the users table that will hold the name of the class to be instantiated for a given row. Active Record takes care of instantiating the kind of object when it loads it from the database.
This technique is called Single Table Inheritance or STI (for short).
A very good recent article about STI is here: http://code.alexreisner.com/articles/single-table-inheritance-in-rails.html
Have a look to this thread on models subclassing:
Subclassing models in Rails