C # Strategic pattern for every user

I have a very simple scenario. My site user can be either a monthly membership or an annual membership

public class User
{
    public string UserName { get; set; }
    public MembershipType MembershipType { get; set; }
}

public enum MembershipType
{
    MONTHLY,
    ANNUALLY
}

      

and then depending on the membership, I apply a different billing strategy:

public interface IBillingStrategy
{
    void Bill(User user);
}

if (user.MembershipType == MembershipType.ANNUALLY)
{
     _billingStrategy = new AnnualBillingStrategy();
}
else if (user.MembershipType == MembershipType.MONTHLY)
{
      _billingStrategy = new MonthlyBillingStrategy();
}

      

It's very straightforward and simple. Now the business comes in and says, "I want to court my friend Bob, I want you to calculate his bill a little differently for everyone else!"

So, if I continue with the pattern, I can create BobBillingStrategy. then I can add some additional logic, now I have 2 ways to identify Bob

if (user.UserName.Equals("bob"))
{
     _billingStrategy = new BobBillingStrategy();
}

      

This seems messy as I am hardcoding the username and only my luck bob creates a new user. So I can add a boolean property for my user called IsBob

if (user.IsBob)
{
     _billingStrategy = new BobBillingStrategy();
}

      

Both just seem funny to me. And I see what's going to happen, and eventually I'm going to start testing for Fred and Ted. My code above will work, but I'm sure there should be a cleaner solution.

thank

+3


source to share


4 answers


I would have membership as a class that did the default billing, etc. it would be toner that heap if:

public class Membership
{

    public String Name { get; private set; }
    public BillingStrategy DefaultBillingStrategy {get; private set; }
    //Other properties

        public Membership(string name, BillingStrategy defaultBillingStrategy)
        {

            Name = name;
            DefaultBillingStrategy = defaultBillingStrategy;

        }

}

      

then you do something like this with your user:



public class User
{

    //same as before

    public BillingStrategy BillingStrategy {get; set; }

    public User(string Name, Membership membership, BillingStrategy billingStrategy = null)
    {

        name = Name;
        MemberShip = memberShip;
        BillingStrategy = billingStrategy ? membership.DefaultBillingStrategy;

    }

}
enter code here

      

also; since the user doesn't want to pay for jan thorugh jun if they join jul you probably want to keep some information about when the user's membership expires and let the membership set that value after / after billing

+2


source


make another version of the billing procedure:

public enum MembershipType
{
    MONTHLY,
    ANNUALLY,
    SPECIAL1
}

      



This way you can at least assign the same procedure to some other "friends"

+1


source


add some kind of coupon code mechanism so that if you need to calculate differently for other users then its flexible enough to do the same.

+1


source


What exactly does your IBillingStrategy do?

Is he responsible for actually billing the user as well as calculating what they should be billed for?

If so, I would separate those responsibilities by introducing the concept Invoice

and then allowing a custom one Discount

for the generated one Invoice

before the counter is actually set User

.

I would probably match the concepts Membership

and BillingStrategy

(therefore Membership

generate Invoices

), use BillingAction

to encapsulate HOW the user is invoiced (credit card, postal invoice, portfolio of unmarked Bills) introduce a concept Discounts

(everyone User

can have many Discounts

) to address the new requirement and wrap it all up in BillingService

.

When moistening a user from whatever repository you have, I would give them the appropriate one Membership

(which in turn would be initialized with a set Discounts

and other information like membership dates and whatnot) and appropriate BillingAction

.

Then, as part of your billing process (probably an overnight thing) you get Users

, push them through BillingService

, and underneath, generate Invoices

and execute their actions with Users

BillingAction

.

0


source







All Articles