1

I am trying to learn the Rules Design Pattern as described here: http://www.michael-whelan.net/rules-design-pattern/ (towards the bottom of the webpage). I have written a class like this:

public class OfferCalculator : IOfferCalculator
    {
        public List<IOfferRule> _rules;

        public RulesOfferCalculator(List<IOfferRule> rules)
        {
            _rules = rules;
            _rules.Add(new AgeRule());
        }

        public virtual List<string> CalculateOffers(Application application)
        {
            List<string> offers = new List<string>();
            foreach (var rule in _rules)
            {
                offers.Add(rule.getOffer(application));
            }
            return offers;
        }
    }

and a class like this:

public interface IOfferRule 
    {
        string getOffer(Application application); 
    }

and a class like this:

public class AgeRule : IOfferRule
    {
        public String getOffer(Application application)
        {
            if (application.Age >= 50)
            {
                return "PremierCard";
            }
            else
            {
                return "NormalCard";
            }
        }
    }

If the applicants age is 50 or greater then they are offered a Premier Card and if it is less than 50 then they are offered a normal card.

I need to record what offer they are entitled to in the database, which looks like this:

CREATE TABLE Card (id int identity not null, name varchar(100))
insert into card (name) values ('PremierCard');
insert into card (name) values ('NormalCard');

CREATE TABLE CardPerson (PersonID int not null, FOREIGN KEY (PersonID) REFERENCES Person(ID) cardid,FOREIGN KEY (CardID) REFERENCES Card(ID) int not null, primary key (personid,cardid))
CREATE TABLE Person (id int identity not null, name varchar(100))

I believe AgeRule should return a card entity rather than a string? How do I create a card object in the Business Layer? Do I just inject a repository into AgeRule and run the following SQL statement (to populate the object):

select * from card where name = 'Premiercard'

This does not look "correct" to me. How do I get a Card object in the domain layer? Is there a "better" pattern for this?

1
  • I believe AgeRule should return a card entity rather than a string? I would expect the method GetOffer() to return an Offer object.
    – radarbob
    Jul 12, 2017 at 5:59

1 Answer 1

1

If you modeled cards with an ID and a name, where ID is the primary key and name a secondary key, the latter can be used for selecting the right object as well as the ID. In your example, name is probably the only sensible criterion from which you can determine which of the two possible card entities is the correct one. So there is nothing inherently wrong with getting a card object by using a statement like select * from card where name = 'Premiercard'.

However, if the card table is prepopulated with all available card entities, and the cards do not change during the lifetime of your application, an alternative might be to select all available card entities from the database once the program starts, store them in a list somewhere, and reuse these objects whenever AgeRule.getOffer is called. So no extra database call is triggered in AgeRule.getOffer, just as now where it returns strings.

12
  • Thanks. Is there a "better" pattern for approaching this?
    – w0051977
    Jul 10, 2017 at 13:49
  • 2
    @w0051977: define "better".
    – Doc Brown
    Jul 10, 2017 at 13:52
  • a more common way of approaching a problem like this.
    – w0051977
    Jul 10, 2017 at 13:55
  • 4
    Stop looking for "common" and start looking for "that way that most effectively meets your specific requirements." Jul 10, 2017 at 13:59
  • 1
    If you're going to be tying the cards identity to it's name maybe at least make the name column unique. And at least be aware of the case sensitive issue. If there is a possibility of the marketing department going card crazy consider making it indexed as well. Oh and never ever let the marketing department change the name of the card. So have another field represent the presented name. Say, why do we hate numeric id's again? Jul 10, 2017 at 14:05

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.