0

So I've been learning DDD and am attempting to refactor an old project using this approach. It is a fairly small app to register employees for events. These employees are initially populated from the DB, registered, and saved.

One business rule says that if an employee is marked as CannotAttend = true and they show up, then they are registered normally and CannotAttend is set to false.

My question involves the concern of the UI. A message, ReceivedMsg, is displayed based on the state the object is in when they are registering/attempting to register. The state would be initially set when the object is populated from the DB, and then when they register a different message is displayed based on if they had been marked as CannotAttend or not. This message is not stored in the DB.

Is this a problem the domain should be concerned about, or should I track these changes elsewhere?

Some example messages are:

Known when populated from DB - Not Currenty Registered, Already Registered

After registering - Registered, Registered and set to attend event

The UI displays this message and a color based on the initial state from the DB and then changed once the properties Registered and/or CannotAttend have changed.

public class Employee
{
    //DB properties
    public int EmployeeId { get; private set; }
    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public int BadgeId { get; private set; }
    public bool Registered { get; private set; }
    public int Swipes { get; private set; }
    public bool CannotAttend { get; private set; }

    //Not persisted
    public string ReceivedMsg { get; set; }
    public RegistrationType RegistrationType { get; private set;}


    public void Register(RegistrationType registrationType)
    {            
        if (!Registered)
        {
            Registered = true;
            Swipes = 0;                
        }

        if(CannotAttend)
        {
            CannotAttend = false;               
        }

        if (registrationType == RegistrationType.Badge) Swipes++;

    }      
}
5
  • To what are they registering? A single event? Where is that screen displayed, how is it accessible? What happens if they cannot attend after registering? What happens if they register after they indicated they could not attend? Why do you track multiple swipes per employees, but only count swipes if the employee is registered? If I register, unregister and then register again you lose swipes count, is that what you want? Why do you have a first name and last name in there? Perhaps you should only have a registration bounded context or event attendance context and craft an explicit model for it
    – plalx
    Nov 16, 2016 at 21:51
  • Also, how employees identifies themselves without a card? Do they have credentials? Can I just register on behalf of any other employee? Do the system have internet connectivity? Are you collecting data locally or are you sending data remotely? Does the system have to work during network partitions?
    – plalx
    Nov 16, 2016 at 21:54
  • It's only ever a single event. There is no concern if they register and don't attend. There is no ability/need to unregister. Yes you could technically register someone else, but it's also not a concern. Swipes are just incremented every time they register/attempt to register again.
    – MickB
    Nov 16, 2016 at 22:39
  • I'm having a bit of trouble to understand the rationale behind the way statistics are captured. It doesn't seem to be clear what they are trying to know. When things aren't clear you better track more than less. Have you thought of using event sourcing or at least also track domain events? You could compile all your stats from a giant stream of EmployeeRegistered { employeeId, registrationType, occurredOn }, EmployeeCannotAttend { employeeId, occurredOn } events.
    – plalx
    Nov 17, 2016 at 2:18
  • Since there are no invariants (no business rules to check as far as I can tell) you could almost just publish the events without materializing any state in the aggregate.
    – plalx
    Nov 17, 2016 at 2:21

1 Answer 1

1

Your Employee class contains logic that it is not concerned with. The Register method should not be part of the Employee object. Employees do not register themselves, they are submitted for Registration via an abstracted function.

What you are saying is the same as a McDonalds customer creating their own BigMac meal when actually the Kitchen does that for them.

You need to separate the Registration functions away, say into a Registration class that can be adapted to handle all sorts of Registrations.

Once this is done, your UI problem will go away.

Edit: Additionally, your Registration class would keep track of registered Employees, your employee does not need to do that.

6
  • When you say that the registration class would keep track of registered employees, are you saying that the employee class doesn't need the registered property? I'm not picturing exactly what you mean. I feel like I'm struggling with conceptualizing what the application needs vs what the database structure already is.
    – MickB
    Nov 16, 2016 at 16:44
  • The Employee can have a registered property if it wants but I does no need a Register method, however having a Registered property puts the responsibility of keeping track of registration in two different locations, the Registration class and the Employee. So the two can easily get out of sync. It's better to ask the Registration class if the given Employee is registered or not. It's all down to SRP, Single Responsibility Principle. Your classes and methods should do the thing they responsible for and nothing else.
    – Ross Miller
    Nov 16, 2016 at 16:52
  • 1
    Can you provide an example? It sounds like all I'd be doing is have a registration class with property employeeid, rigistered, swipes. How would that be any different than the employee class having those properties itself?
    – MickB
    Nov 16, 2016 at 16:59
  • @MickB What are the business invariants (rules) that have to be enforced in that registration process? Do you need to care about other employee registrations when registering (e.g. is there a maximum)? To what are they registered? It seems like there is only a single event in your system as the registered flag doesn't seem to be segregated by event? It is there questions that will allow you to validate your current design and aggregate choices.
    – plalx
    Nov 16, 2016 at 19:49
  • @MickB On the other hand, the domain should not be responsible for messages and internationalization. You shouldn't be using the domain object directly from the view. Use an intermediary ViewModel. This view model can hold UI-related properties such as displayed messages. Also, why is the registration type not persisted? Isin't that an important aspect of the registration you want to track?
    – plalx
    Nov 16, 2016 at 19:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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