What is the best solution for situation:
class Person
...
class Student extends Person
...
class Employee extends Person
...
class Visitor extends Person
...
And some person is employee and student, for example.
Classical approach of inheritance isn't good solution.
I can use delegation pattern:
User {
Person p.
Collection<Role> roles;
}
And All classes : Student, Employee, Visitor - will implement Role interface or class.
Is it a good solution?
Thank you!
Usually, the delegation pattern you suggest is a good idea. It has a lot of advantages over multiple inheritance:
It is supported by every language; multiple inheritance support differs from language to language and your language of choice might even have none at all.
The roles of a person do not have to be known at compile time.
You can adjust the roles at run time! A person may quit being a student or enrole as a student. Easy case with delegation, impossible with multiple inheritance
No combinatorical explosion: Consider you have ten roles. If any combination of roles was possible, you would need 2^10 = 1024 classes. Have fun with that.
So, stick to the delegation! Delegation is a wonderful thing and the answer to many questions in OOP :).
Related
I have seen many class diagrams on popular websites and design courses defining the relationships using composition like:
Admin has a person instance
Umpire has a person instance
As per me, shouldn't it be the case of inheritance as admin 'is-a' person, umpire 'is-a' person.
Admin extends Person
Umpire extends Person
Can you please help me understand why we are preferring composition here?
Generally speaking, Composition is always favored over Inheritence. Except for the times you want to override methods of the superclass.
I believe there are two reasons for that.
You can use only one class for extending so you will have more options for later on when using the composition.
The principle for encapsulating. What you want is to encapsulate data as much as you can. You don't want to make the Umpire class inherit from Person just for the sake of accessing Person's attributes. Inheritance usually implies that you want to override a method to use polymorphism and different behaviors for different subclasses. If you want to access a class's data you'll usually do it with an association or in case you want persistent data you'll use composition.
That's why you use composition when talking about Umpire and Admin classes since they don't change the behaviors of the Person class even though there's a noticeable 'is-a' relationship.
I need some help.
I'm writing class diagrams for my engineering software course and I have some doubt.
With few words, this app will send a trouble ticket about a gas loss e.g.
I have a class called "ManageTroublTicket" and I need some methods to delete or modify the ticket for example.
I already have a ticket class, so ManageTroubleTicket will have a ticket object as attribute, but for the rest?
Should I create a class for "DeleteTicket" and extends with ManageTroubleTIcket?
Like
Class DeleteTicket extends ManageTroubleTicket?
Or something like
Class ManageTroubleTicket implements DeleteTicket?
What kind of strategy should I use?
Thanks for answering and sorry for my bad english
This is an opinion-based question, so chances are it will be deleted.
Let's say I have class Teacher and class Course. I want to create method GetCourseId(TeacherId) that will receive as input parameter a TeacherId and will return a CourseId.
Should this method be in class Teacher or class Course?
I guess my question is that if there's a method that can fall under any number of classes, where should it finally go? Is there some unspoken rule for that?
Thanks.
I've often seen a third class created to handle something like this, where a method requires knowing about 2 classes and it doesn't quite fit in either.
In this case, it'd be the creation of a CourseManager that could contain methods like GetCourseId, GetCourseByTeachers, AddCourse, and other 'admin' tasks.
Many of these would serve as a wrapper of sorts -- CourseManager.AddCourse would likely pass a lot of work off on the Course constructor.
Normally i define classes like Teacher, Course as java beans which just hold fields, getters/setters and some very basic methods which directly use the fields and don't include any business logic.
Based on the supported functionalities/features in my application, i create business/manager classes which implement my business through communicating with the other java beans.
So if i'm creating a simple course registration application for a university, I would define 3 java beans: Teacher, Course, Student in addition to some manager classes based on the features that i want to support in my application i.e. in our case RegistrationManager which would hold methods like: registerStudentInCourse(), getStudentCourses(), addCourseTeacher() ..
Please note that I'm just sharing my way of coding, people may or may not agree with it.
The simplest solution will be having a property like
private Course course
or
private Set<Course> courses
based on cardinality (OneToOne or OneToMany) in Teacher class. It could be ManyToMany as well depends on the requirement and data modeling. You can get or set course/s assigned to the teacher using getter/setter method.
Apart from this if the relation is bidirectional than you can have similar property in Course class. In case of bidirectional mapping you can have utility method like registerCourse in the Teacher class which will set proper relations between entities.
public boolean registerCourse(Course course){
this.course = course;
course.setTeacher(this);
}
You can have this kind of utility method in Course class as well.
In the book C++ Primer, the author wrote: "The key idea behind OOP is polymorphism". I am not sure I understand what the author meant. What about other important stuff: Abstract, Inheritance, etc.
Can anyone elaborate on that, please?
Edit:
I do not ask "What is polymorphism". I am asking "Why polymorphism is the key behind OOP"? Why not inheritance is the key?
I'm not sure that it's the key to OOP. That's just someone's opinion.
I think there are four keys: abstract data types, encapsulation, inheritance, and polymorphism. They belong together.
Each idea depends on the previous ones. ADT is the only one that stands on its own. Encapsulation needs ADT. Polymorphism requires inheritance.
Polymorphism helps to eliminate if, switch, and case statements. You don't have to write code to figure out what to do based on object type; the virtual table simply calls the right method for you behind the scenes.
The Author may be saying this because :
When class B inherits from A then class B can be typecasted to A ----> Which is also called as polymorohism. So Inheritance directly allows polymorphism.
When A implements interface I*something* then A can rome around as I*something* which is also called as polymorphism. So Interfaces makes polymorphism come true.
Abstract : Abstract class is just another class which cannt be instantiated and act as base class (generally). Non abstract Child classes can be type casted to Abstract class and hence polymorphism.
So infact its seen that most concept of OOP can be seen as polymorphism and due to this Author might have said that.
Generally it's the idea of creating objects (with their fields, methods, etc) which can have more than one form - derived (abstract) classes, implemented interfaces and so on.
And you would have had your answer in few seconds only, if you would've had asked google, wikipedia and so on, first ;)
Q1.
In my university studies of object-oriented modelling and design they recommend thinking about what an object can do for its method, and what its responsibilities are for its attributes. All attempts at clarification have resulted in further confusion.
This tends to generate a class diagram with actors who have all the actions, and inner classes which only hold data.
This doesn't seem correct. Is there another way of thinking about how to model the objects?
Q2. Also, the course seems to emphasize modelling the objects after their real-world counterparts but it doesn't necessarily make sense in the domain model. IE. In a medical practice, they have Patient: CreateAppointment(), CancelAppointment() but that is not how it would be implemented (you would modify a the appointment collection instead). Is there another way of thinking about this?
Example Q1
Secretary: RecordAppointment(), RecordAppointmentCancellation()
Appointment: time, date,... (no methods)
Example Q2
Doctor: SeePatient()
While SeePatient is a use-case, it does not make sense for a method on the actual class. How do you think about this?
Unfortunately, the roadblock you've hit is all too typical in academia. Academic projects tend to start with video rental stores, libraries or student registration systems (yours is a variance of this with a doctor's office) and then inheritance is taught with animals. The guideline you've provided is also very typical
they recommend thinking about what an object can do for its method, and what its responsibilities are for its attributes
In fact when beginners ask I usually explain an object's property's are the things it knows about itself and its methods are the things it knows how to do. Which is really just another way of saying exactly what you have there. As you've discovered this way of thinking quickly breaks down when you start discussing more tangible systems and not just examples.
For instance the guideline works pretty well with this object:
public class Tree
{
public int Height { get; set; }
public void Grow(int byHowMuch)
{
Height += byHowMuch;
}
}
While this certainly fits the bill your right to think that it doesn't "feel" right:
public class Secretary
{
public void MakeAppoinment(Patient patient)
{
//make the appointment
}
}
So what's the solution? It's a matter of taking what you are being taught and applying it. Learning and understanding design patterns will help a lot with developing systems which are more functional than a tree that knows how to grow.
Recommended reading:
Design Patterns: Elements of Reusable Object-Oriented Software (also known as the Gang of Four or GoF)
Head First Design Patterns
Head First Object-Oriented Analysis and Design
To solve the issue you're been presented I would probably use a combination of inherited person classes and interfaces, which would perform their actions through a series of service classes. Essentially a secretary, doctor, and patient would all inherit from person and each of these classes could be passed to accompanying service classes. The service classes may or may not do things like SeePatient(). Please don't take this example to mean that person classes wouldn't have methods.
Stack Overflow has more than a few related questions which may be of use:
Is Single Responsibility Principle a rule of OOP?
Are there any rules for OOP?
why is OOP hard for me?
Additionally, it would be good to check out:
Single responsibility principle
Don't repeat yourself
PrinciplesOfOod
Finally, there isn't a single definition of what makes an application object oriented. How you apply patterns, principles etc. will define your program. The fact that you are asking yourself these questions shows that you are on the right track.
Q1
Is it possible responsibilities of your objects should be interpreted as authorization or contract requirements, as in what actions they should take? So, to take a medical example from your Q2, an object with a Scheduler role (think C#/Java interface, or Obj-C protocol) has attributes around CanEditAppointments or EditsAppointments.
Q2
From a use case perspective, a patient may be able to create an appointment, and so you might implement a Patient in your object model with a method to CreateAppointment(). But, in terms of encapsulation, you would likely instantiate an Appointment object in CreateAppointment(), and then call methods or set properties on the Appointment object to set its time, date, patient, physician, etc.
And because the Appointment collection is likely to be permanent storage like a database, it would likely be the Appointment object's responsibility to add itself to the collection (Appointment.Schedule() goes through your data access layer to save itself to the database).
That also ties back to your Q1, in that the Appointment object's responsibility is to save itself, so it might implement an ISaveAppointment interface that requires fields and methods to carry it out. It also is the Appointment's responsibility to have a date, and time, and patient, etc., before being saved, and so the ISaveAppointment interface should require they exist, and Appointment.Schedule() should validate the values are correct or have been previously validated.
You are right that in many cases there are higher order things which more naturally contain behaviour, like the system, or the user.
You can model this behaviour in classes as static methods which operate on the data model. It isn't OO, but it's fine. You can group related methods together into such classes, and soon you have the notion of "services", as in service oriented programming.
In Java there are specifications and standards for creating such classes, namely the stateless session bean in EJB. The Spring Framework has similar notions with the stereotype "Service" which can be applied to classes to tag them as being facades for business logic.
A service is then a component which encapsulates a certain functionality or behaviour in the system. It operates on a given object model (either its own internal one, or the more general business object model from the system). If you take your use cases and create services which relate directly to them, you can write very maintainable software.
The DCI Architecture is a formalisation of this and an attempt to do the same, but at the same time trying to stay true to object orientation, by adding behaviour to objects as they need it.
I still experience the confusion: "am I telling you to do something else" or "am I doing something someone else asked of me"?
Perhaps all you have to do is play Barbie's, or G.I. Joe's to understand object interaction and where responsibilities go. G.I. Joe got wounded (or Barbie broke a nail) so he calls the Dr's office. "Hey doc, this is Joe, I need an appointment." So you, the kid, tell Barbie to go to the doctor, who needs to know the doc to call and how to call - a reference and public MakeAppointment() method. The Dr. office needs to put the appointment on the books - it's own BookAppointment() method that is the office's procedure for handling appointment requests.
public abstract GenderAppropriateDolly {
protected DrOffice Drkilldare;
public override MakeAppointment() {throw new NotImplementedException();}
}
public class GIJoe : GenderAppropriateDolly {
DrKilldare = new DrOffice();
List<Appointment> myAppointments = new List<Appointment>;
public void MakeAppointment () {
myAppointments.Add(DrKilldare.BookAppointment(this));
}
}
public class DrOffice {
List<Appointment> officeAppointments = new List<Appointments>;
public Appointment BookAppointment(GenderAppropriateDolly forWhom) {
Appointment newappt = new Appointment(formWhom);
this.Appointments.Add(newappt);
return newappt;
}
}
public class Kid {
GenderAppropriateDolly myRoleModel = new GIJoe();
// Joe got wounded so ...
myRoleModel.MakeAppointment();
}