Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I\'ve been struggling with a design so I figured I\'d ask here and see if anyone

ID: 643497 • Letter: I

Question

I've been struggling with a design so I figured I'd ask here and see if anyone's able to help :)

High level overview

I'm designing an app to gamify exercise by creating mini competitions (ex. Who can lose the most weight in 3 months or bike the most miles in a month).

Users can create competitions (calling them races for now) and they need to be able to specify constraints - participants have to be in a certain age range, over a certain weight, maximum number of participants in a race, etc.

My Objects

RaceParticipant - for brevity, the only pertinent property is int Age.

Race:

public class Race
{
    public virtual int RaceId { get; set; }
    public virtual string RaceName { get; set; }
    public virtual int RaceTypeId { get; set; }
    public virtual TrainingType RaceType { get; set; }
    public virtual IEnumerable<RaceParticipant> RaceParticipants { get; set; }
    public virtual IEnumerable<RaceConstraint> RaceConstraints { get; set; }
}
RaceConstraint abstract class:

public abstract class RaceConstraint
{
    public string DisplayText { get; set; }
    public string ValidationText { get; set; }
    public virtual bool PassesConstraint(Race race, RaceParticipant participant);
}
RaceConstraint implementation MaxNumberOfParticipants:

public class MaxNumberOfParticipants : RaceConstraint
{
    public int MaximumNumberOfParticipants { get; set; }

    public MaxNumberOfParticipants()
    {
        DisplayText = "Maximum number of racers";
        ValidationText = "This race has reached the maximum number of racers.";
    }

    public override bool PassesConstraint(Race race, RaceParticipant participant)
    {
        bool result = false;
        if (race.RaceParticipants.Count() <= MaximumNumberOfParticipants)
        {
            result = true;
        }
        return result;
    }
}
RaceConstraint implementation AgeRange:

public class AgeRange : RaceConstraint
{
    public int MinimumAge { get; set; }
    public int MaximumAge { get; set; }

    public AgeRange()
    {
        DisplayText = "Age range of racers";
        ValidationText = string.Format("Racers must be between the ages of {0} and {1}.", MinimumAge, MaximumAge);
    }

    public override bool PassesConstraint(Race race, RaceParticipant participant)
    {
        bool result = false;
        if (MinimumAge <= participant.Age && participant.Age <= MaximumAge)
        {
            result = true;
        }
        return result;
    }
}
The question

My question is where to store MinimumAge, MaximumAge, and MaximumNumberOfParticipants. I'm using Entity Framework code-first so I know I don't need to worry about the schema directly, but I do need to think about which properties to add to EF and which object they'll be connected to.

Currently EF would make a separate table for each implementation of RaceConstraint which seems like overkill and I definitely don't want DisplayText and ValidationText stored in the db for each instance.

I thought about moving MinimumAge, MaximumAge, and MaximumNumberOfParticipants to properties of Race because each race will have values for these, but that feels like Race and RaceConstraint would be too coupled. I'd like to be able to add a RaceConstraint in the future as requirements change without having to add a property to Race and therefor add a column to the Race db table.

I think I'm going to have to make a container object for RaceConstraint that holds a collection of all possible RaceConstraints. Would it make sense to put these properties in that object and then remove IEnumerable RaceConstraints from Race and instead add a property for the RaceConstraintContainer?

Or maybe I'm way over thinking this and there's a design pattern I can follow. I'm sure I'm not the first person to come across this scenario!

Thanks in advance.

Explanation / Answer

You are running into a limitation of Entity Framework that encourages what each type of object in your domain model to map directly to a single schema construct. Creating sub types of RaceConstraint sounds like a good idea from an OO perspective but then the Anemic Domain Model is a more encouraged pattern using this framework anyway.

RaceConstraint should be the entity type and all the different possible constraint properties should exist in this one entity. Display and Validation text are not well represented here, and may be more appropriate as references to an enum or a resource file as each individual constraint property in your RaceConstraint object may have a unique message.

To maintain the OO design however, you can translate your domain model to a view model that is not Anemic, however some would consider it bad practice to have business logic like PassesConstraint in your View Model or your Domain Model as well. These are the two schools of thought on this.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote