views:

68

answers:

2

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?

+4  A: 

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:

To solve the issue you're been presented I would probably use a combination of inherited person classes 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:

Additionally, it would be good to check out:

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.

ahsteele
A: 

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.

nekno