tags:

views:

153

answers:

5

This should be a simple one.

Let's say I'm designing a very simple timeclock application. The user enters his ID, and the application shows him his hours for the week, hours for the day, and then allows him to punch in our out. It is smart enough to know whether an employee is currently punched in. No breaks or lunch or shifts or anything.

So I've got an Employee. I've got a Timecard which has multiple EventRecords. I've got a Timeclock which of course maintains the time, but is also sort of the front end to the whole model (perhaps).

Should the Employee have a Timecard, or should the Timecard reference an Employee?

Should the Timecard be responsible for calculating hours for the day, etc?

Should the Timeclock be responsible for instantiating Employees and Timecards and relating them?

Should the Timeclock do punchIn and punchOut, or should the Employee?

+2  A: 

Just answer your self these questions, in a end-user perspective, not from a programmer point of view.

Should the Employee have a Timecard, or should the Timecard reference an Employee?

Who owns the timecard?

*Should the Timecard be responsible for calculating hours for the day, etc?**

Should it?

Should the Timeclock be responsible for instantiating Employees and Timecards and relating them?

Does time clocks instantiate employees?

Should the Timeclock do punchIn and punchOut, or should the Employee?

same...

First, you have to analyze the problem. Then design the solution and only after that code it.

So, you should separate each process from another. Here it seems you're analyzing with implementation in mind and then designing etc.

See this answer from Steve A. Lowe

Once you have clear in your mind what object is responsible of what, and during implementation, you may tweak a little bit your design and adapt it if it makes sense.

The three process may happen really, really fast in your head, once you have more experience. But, you have to be patient.

OscarRyz
+2  A: 

This is a decent example of when your OO model should, basically, mirror the real world.

Should the Employee have a Timecard, or should the Timecard reference an Employee?

The employee should have a time card. If it was a real time card, you would be carrying it. You would not be in the time card's pocket.

Should the Timecard be responsible for calculating hours for the day, etc?

I'm not sure what you mean. Do you mean calculating the number of hours from check out minus check in? This is probably something your timecard can do.

Should the Timeclock be responsible for instantiating Employees and Timecards and relating them?

Probably. What exactly is "Timeclock"? When I think of creating and associating employees with timecards, I think more along the lines of "Office." I'm not sure what the full scope of your model is, though.

Should the Timeclock do punchIn and punchOut, or should the Employee?

Have you ever seen a time card punch itself in and out? I think it's safe to say that's an action of the employee.

Edit: As TheTXI pointed out, the Employee would call punchIn and punchOut methods on the Timecard. But the Timecard itself is not responsible for knowing when to punch in or out.

Matt Olenik
hmm, not sure about the last one. An Employee causes the action PunchIn, but its the responsibility of the time clock to actually know how to perform the action.
Mitch Wheat
An employee would probably call the timecard's punch-in function. It is up to the time card to determine the process of a punch-in
TheTXI
oops I meant TimeCard
Mitch Wheat
While an employee has a timecard in the real world, the timecard also has the employee's info written on it. The employee punches a timecard, yes but eventually payroll processes it without the physical employee around. Nuances like these are what caused me to ponder this one. Thanks!
Boden
+2  A: 

Note: as with most modelling there is not always a single way to do it.

Should the Employee have a Timecard, or should the Timecard reference an Employee?

The Domain would suggest that an Employee has a Timecard (and as pointed out, more than timecards over time).

Should the Timecard be responsible for calculating hours for the day, etc?

I would make that the resposnibility of a TimeCardCalculator.

Should the Timeclock be responsible for instantiating Employees and Timecards and relating them?

I think the instantiations should be done at a higher level, by your application perhaps.

Should the Timeclock do punchIn and punchOut, or should the Employee?

The TimeClock. The employee calls PunchIn/PunchOut on the TimeClock.

Mitch Wheat
The Employee will (presumably) eventually have more than one Timecard - it might get awkward having a number of Timecards with backwards-references to Employees.
Andy Mikula
good point, I was thinking of a time card as a perpetual timecard, which is wrong. I will edit my answer. Thanks.
Mitch Wheat
+2  A: 

Yeah, this sort of thing is pretty classic. The easiest thing is to apply another rule. my favorite is Parnas' Law: every object "hides" something that can change in the requirements behind its interface.

Okay, so it's pretty clear an Employee has a TimeCard which is a time ordered list of start and stop times.

When you "clock in" as far as the domain is concerned, all you're doing is making a "time-started" record. Sounds like "clock in" and "clock out" might be TimeCard methods, and if we think about it, that also hides the probably requirements changes (eg, is it a record in a data base, a line in a flat file, and are you storing local time, GMT, or UNIX time?)

The Employee is the representatin of an employee, and contains all that employee-specific information; name, address, etc.

So far, there's no obvious need for a TimeClock except as the "implementation" of clocking in and out in the outside world domain.

Now, as you build an application, but have to build up from the domain, and now you'll need some kind of UI, a way to authenticate (establishing which Employee you want) and from there get the Employee's TimeCard -- which suggests a method for Employee. Then you need a place to "clock in" and "clock out" in the UI. That makes it sound as if you timeClock may well be a View object in the implementation. It needs a couple buttons and whatever your login protocol is.

One more piece here is the "business process" or "log in first, then clock in. Later, clock out, then log out" or something similar. There's a controller; how you split that off is somewhat dependent on how you do the UI.

Charlie Martin
+2  A: 

I think that you are a bit too hoked up on physical objects here. The Employee is probably good to have as object as it has an identidy and is a player in the scenario, but I don't see either the Timecard or Timeclock as any good candidates to be objects. The Timecard would just be a list of EventRecords that belong to an employee, so you could just as well keep those in the Employee object or in a collective list. The Timeclock doesn't do anything at all but hand out DateTime.Now...

The EventRecord is good, or perhaps it could be a WorkTime object; a pair or punch-in and punch-out times. If there is no punch-out time in the last record, the employee is punched in.

Keeping the time records in the Employee object or keeping them in a separate list with a reference to each Employee is rather a matter of taste.

Well, as I scrapped the Timecard and Timeclock objects, most of your questions fall... ;)

Guffa
+1 :: I think simpler is better in this case.
garrow
Isn't it surprisning how often that is the case? ;)
Guffa
I'm happy you replied with this, because it was the first solution I found myself drifting toward. As this problem definition expands, however, I'd be tempted to keep dumping code into the Employee...and it sort of just becomes procedural, no?
Boden
No, as long as the methods really are capabilities for the employee object.
Guffa