4

I've got one requirement that is:

When one employee starts working on a project and when he finishes working on it he must inform the system so that it can generate a report afterwards of how much hours a certain project required.

The requirement itself is simple, I just want to see if I'm thinking right about it. My initial idea was an event based approach: when the employee starts working on it one event is raised informing that, and when the employee finishes working an event is raised informing that.

On the end of the day, to count the hours needed for a given project we just need to retrieve the relevant events and compute time spans and sum them up.

There are some loose ends still, however. For instance, finding a way to connect two such events so that we know that one refers to work started and the other referes to the ending of that started work. My idea was to make one event hold a reference to the other, but I don't know if this is usually done.

By the way, the other approach I thought seemed to bloat the employee class. It was basically to make the employee class hold a reference to the project the employee is currently working on, and a property refering to the work start time. When it is finished, just one entry for the timespan is recorded on the project.

The second approach is much simpler but it seems to add responsibilites to the employee class, I'm unsure though.

Is the event approach really the most natural and simpler approach here, or going to one event approach is overengineering and just making the employee class responsible for managing this the simpler approach?

  • 1
    The requirement implies that each project has ONLY one employee. It sounds more like a Task rather than a Project. Can you clarify? – John Kouraklis Jul 1 '17 at 22:40
  • 3
    There's nowhere near enough information in the requirements to make any recommendation of anything. It looks like you need to spend $5 on a cheap stopwatch and don't need any software at all. – Brendan Jul 2 '17 at 4:43
  • First get more detailed requirements on the result. Report the hours between start and end (what about multiple days), just the working hours of that period, or anything else like a total of all periods worked on? How that is recorded in the system is not relevant for the requirement, that is part of the solution you should come up with. – Kwebble Jul 2 '17 at 22:06
6

Reading your question and the other answers, I am under the impression there is some confusion caused by the fact the term "event based system" often is used differently from the way it is used in your question. I am pretty sure the requirement

he must inform the system so that it can generate a report afterwards of how much hours a certain project required.

does not mean your system needs to generate such a report immediately when an employer informs the system he stops working on a certain project. That is what the term event based system would make sense for, to trigger sequences of dependend actions to another, independent part of the system, avoiding time lags and polling. In your case, however, the Report generation is probably triggered later by a person (for example the project manager), and not by the fact an employee ends his work on a certain day.

Here, just logging tuples (employee, project, time, [start|stop]) somewhere will be sufficient. When you have your employees and your projects in a relational database, with tables Employee and Project (and corresponding classes), this will mean you add a table/class with four columns/attributes EmployerID, ProjectID, Time, StartStop to the system. One could call this table/class Event, indeed, but to avoid any confusion, I recommend you pick a more specific name, maybe WorkLog. Then, when it comes to report generation, one can evaluate this table and easily

retrieve the relevant events work log entries and compute time spans and sum them up.

This should already solve your "loose ends". For example,

finding a way to connect two such events so that we know that one refers to work started and the other referes to the ending of that started work.

is easy - there should be always pairs of WorkLog entries in the table for the same combination (EmployeeID,ProjectID), one with the state "Start" and one some hours later with the state "Stop", both on the same day. Of course, you need to make sure you have a strategy in your system to deal with situations if one employee forgets to record his begin or end of work on a certain day, but that is not a technical problem, you will have to solve this problem indepently from the solution you pick.

the other approach I thought seemed to bloat the employee class [by...] make the employee class hold a reference to the project the employee is currently working on

Obviously not. The solution above does neither add something to Employee class nor to the Project class.

  • 1
    That is what the term event based system would make sense for, to trigger sequences of dependend actions to another, independent parts of the system, avoiding time lags and polling this. This paragraph summarise why there's no need of EDD. IMO. – Laiv Jul 2 '17 at 17:37
  • @DocBrown, perhaps there's indeed a confusion. I'm thinking about events as in domain events from DDD, which AFAIK is a way to record that relevant business happenings have occured. The report will certainly not be immediately generated. What the customer wants is that employees inform when they start working on a project on a day and when they finish it, to have this information. He says it's like when the employee clocks in when he arrives and clocks out when he leaves. Perhaps I misunderstood domain events. – user1620696 Jul 2 '17 at 17:59
  • I think by "event-based system", OP is talking about event sourcing. Unfortunately the confusing terminology may have mucked the question up a bit since now it has answers like this one that are partially based on it, and that innappropriate "event-programming" tag. – Ben Aaronson Jul 3 '17 at 12:17
  • @BenAaronson: I think one can interpret the question as: is "event sourcing" or "event programming" is the right tool for handling this kind of "events" (=logging of working hours)? My answer: it is not necessary, it probably overcomplicates things, and by designing the logging table correctly, the problems described by the OP can all be solved. – Doc Brown Jul 3 '17 at 13:27
  • 1
    @DocBrown Fair enough. I think your tuples suggestion is actually very similar to what the OP was describing, but you're right to emphasise it can be as simple as that without a full-blown, heavyweight event sourcing architecture – Ben Aaronson Jul 3 '17 at 17:15
3

I would say that you are better off having employees log hours against a project rather than start and stop events

Start and stop events can be come problematic when someone forgets to fill them in. Or when someone is working on more than one thing at a time. Or if they have to account for breaks.

eg. say I start work on project X at 9am this morning and finish at 5pm 4 days later.

  • Is it 4*8 hours or did I work 24h a day on it?
  • What if those days are friday to monday? Did I work over the weekend?
  • What about lunch breaks?
  • What about bathroom breaks?
  • What about the meeting for project Y?
  • What about that emergency bug fix for project Z?
  • 2
    I would say the OP needs a way "having employees log hours against a project" independently from the decision for or against events. – Doc Brown Jul 2 '17 at 7:23
  • well if you log X hours and provide a start date, then you have techincaly provided start and end events. However, I would concentrate on the "So that.." part of the requirement. Can the chosen method produce those reports? if not you have to go back to the business – Ewan Jul 2 '17 at 7:35
  • 1
    Ewan, you 100% right, the logged start and stop times may be interpreted as events itself, which just supports my point: the OP first needs to focus on logging the tuples (employer, project, time, [start|stop]), indepently from the idea of using events, or if these tiples are already the events, or if "event" is just a buzzword they don't need. – Doc Brown Jul 2 '17 at 7:55
  • Technically, when you log your first date/time you start the work on this project unless one can "start" working on the project but "put real work" later. This is not clear from the requirement. – John Kouraklis Jul 2 '17 at 11:15
  • Ewan, I think the reporting itself has to be a separate entity (class or classes) in order to honor separation of concerns and SOLID principals. The project/time logger entities should not deal with reporting – John Kouraklis Jul 2 '17 at 11:18
2

I like the event approach.

Events fits with event sourcing approaches that people talk about, and sometimes in conjunction with Domain Driven Design (DDD) and/or Command Query Responsibility Separation (CQRS).

If you reduce events to calculation of the hours worked as you are able to correlate the start/stop events — and throw away the underlying events as soon as you are able to do so — this looses potentially useful business information that is contained in the events.

For example, by replaying (or otherwise analyzing) the event log, you can determine how many people were on the project at the maximum, or, say, on average or at some point in time. Lots of other thing can also be computed from the events. Who was working together on the team, for example. (A few more different kind of events and you'd really have some data to analyze.)

It is fairly straightforward to replay the event log to compute some information, like hours worked. Making some other party, like the employee themselves, or the employee class, compute some intermediate answer seems counterproductive and premature data analysis.

I would suggest capturing something along the lines of the following business events (as per your specific requirements):

  1. start, stop, suspend, resume, and complete project
  2. assign person to project
  3. suspend person from project (e.g. vacation);
  4. resume person on project (e.g. back from vacation)
  5. taken person off project (e.g. reassigned to another project)

(With these events you can assume that a person that is assigned to a project works the project daily on regular work days until another event changes that. Holidays would not be normally be counted unless perhaps you had special events for working overtime. Yes, there's room for error if events are not captured; ideally that is automated.)

In summary, there is an approach called event sourcing that advocates that business events are captured in an append-only log. This approach separates concerns and reduces coupling of those wanting calculations/results-analysis from those who are (closer to) collecting the results.

Without this separation, the collectors have to know exactly what results to compute and keep for other entities to use, which conflates responsibilities and tightens coupling. For example, in your second approach, a timespan would be computed and saved for later use as the original problem identifies this as the requirement, whereas the events used in deriving the timespan are discarded.

The event sourcing approach also offers business value in the sense of supporting analytics (especially in postmortem).


Edit: reworded events as active business operations as per @Ewan's comment.

  • In the case, considering the customer asked explicitly that he wants the software to allow the employees to inform the system when they started and ended working on a project, the event approach seems natural right? By you answer I also see the opportunity to start simple and then add more functionality as required. By the way, to correlate the start/stop events, I imagined making the stop event holding a reference to the start event, to be able to match them. Is it a good idea to have one event point to another like that? This is the first time I implement domain events, so I'm unsure. – user1620696 Jul 2 '17 at 3:52
  • My thought is not try to correlate during event collection and logging, but do that after with some analysis component. However, collect sufficiently rich information about each event to do the meaningful correlation you need and other analysis later, which includes the when, who, what, etc... So, as rich an event as you can, as in: at this particular time, this particular person is added to this particular project. I would think that would suffice for correlation (except in the case of errors of failure to log events, which would mess with any approach). – Erik Eidt Jul 2 '17 at 5:56
  • 1
    @user1620696: "start simple and add more functionality as required" is a really good idea. However, this answer just looks to me like the opposite: it took some buzzwords from your question and imagined lots of potentially requirements you currently do not have, making a very overengineered design "just in case". What you need is a way to log the times when people start and stop working - design that first. An event based approach can be made on top of that, if required, and it is only needed if the event sender (employer) does not know which part of the system will receive the event. – Doc Brown Jul 2 '17 at 7:17
  • event sourcing works when your events change the state of an object. But here the events are stand alone immutables. I dont think event sourcing fits. – Ewan Jul 2 '17 at 7:33
  • @DocBrown, CQRS is indeed complex. Perhaps I should not have mentioned it. To be clear for the OP, I'm advocating event sourcing without CQRS. An append-only log recording business activities is a straightforward and clean concept. Naturally the OP should design events to their specific needs rather than overbuilding. – Erik Eidt Jul 2 '17 at 14:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.