0

Please see the code below, which is a factory method in a rich domain model (domain layer). There are two things I dislike about it:

public class SalesPersonOfferFactory (Applicant applicant)
    {
        if (applicant.Age > 30 && applicant.Employed = true)
        {
            return new PersonOffer (52, applicant.id)
        }
        else if (applicant.Age < 30 && applicant.Employed = true)
        {
            return new PersonOffer (164, applicant.id)
        }
        else if (applicant.Age > 30 && applicant.Employed = false)
        {
            return new PersonOffer (196, applicant.id)
        }
        else if (applicant.Age < 30 && applicant.Employed = false)
        {
            return new PersonOffer (242, applicant.id)
        }
    }

PersonOffer accepts an OfferID and ApplicantID (relevant to database).

The concern I have is that the domain layer has to know the ID numbers from the database i.e. it has to know that OfferID 52 is relevant if the applicant is over 30 and is employed and it has to know that offer 164 is relevant if the applicant is under 30 and is employed etc.

I realise I am thinking about this incorrectly. How can I create business objects in the domain layer that need mapping to the data layer? Is there a pattern for this?

Would it be normal to use natural keys that describe the offer e.g. 52 is: PremierCard so would say:

if (applicant.Age > 30 && applicant.Employed = true)
        {
            return new PersonOffer ('PremierCard', applicant.id)
        }

There has to be a better way of doing this.

2

With reference to this and your previous question, Create an entity object in the domain layer when the ID is unknown, you appear to be storing card types in the database, and hard-coding rules around those cards in code.

This means that if you want to add a new card, you need to both re-release the application and update the database. This makes both testing and releasing harder than it need be.

I'd therefore suggest you choose between either storing the business rules in the database too, or you hard code the card types in the application. That way, you need only update the database, or re-release the application when new card types are needed.

If this isn't "the DDD way", then don't do it the TDD way. Making life harder for yourself by blindly following someone else's idealised way of doing things is never a good idea.

  • Thanks. What would the DDD way be? I realise it is NOT always right. However, I am trying to incorporate it more into my working practices (without taking it too literally). – w0051977 Jul 11 '17 at 10:40
  • 1
    I've no idea what the DDD way would be here. Everything I read about DDD rubs me up the wrong way, so I've stopped paying attention to it. Also, whether storing everything in the database, or in code, is best for you is only something you can answer as it depends on your target audience and development, release and maintenance processes. – David Arno Jul 11 '17 at 11:08
0

Would it be normal to use natural keys that describe the offer e.g. 52 is: PremierCard

It really depends.

In the ubiquitous language of the domain, is the term "52" meaningful and used / understood by the people who make offers to Sales People? If "yes" then it's perfectly fine. If "no" then you should probably find a better way of representing these things - like calling it "PremierCard" that is very close - if not exact - in usage to how they are in their everyday usage.

Also, if this were a "rich domain model", then the code should probably read something like

if (applicant.IsOver30AndEmployed())
{
    return new PremierCardOffer(applicant);
}
if (applicant.IsAYoungAdultAndEmployed())
{
    return new NotSoPremierCardOffer(applicant);
}
//and so on

where PremierCardOffer and suchlike own the knowledge that this is Offer Type 52, or 164 or whatever:

class PremierCard: SalesPersonOffer
{ 
    public int OfferTypeId => 52;

    public PremierCard(Applicant applicant)
    {
     //whatever you need to do
    }
}

and so on. Right now I'm guessing you have in fact an Anemic Domain with the rich functionality scattered across services, factories, and managers. Not necessarily a bad design, but extremely limiting when trying to model a domain.

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.