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
source to share
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
source to share
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
.
source to share