简体   繁体   English

c#每个用户的策略模式

[英]c# Strategy Pattern per user

I have a very simple scenario. 我有一个非常简单的场景。 My site's 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();
}

This is very straight forward and simple. 这非常简单直接。 Now business comes along and says "I want to look after my friend Bob, I want you to calculate his bill slightly differently to everyone else!" 现在业务出现并说:“我想照顾我的朋友鲍勃,我希望你能像其他人一样略微计算他的账单!”

So If I continue the pattern I can make a BobBillingStrategy. 所以如果我继续这个模式,我可以制作一个BobBillingStrategy。 then I can add some extra logic, now I have 2 ways I can identify Bob 然后我可以添加一些额外的逻辑,现在我有两种方法可以识别Bob

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

This feels dirty as I am hard coding a username, and just my luck bob creates a new user. 这很脏,因为我很难编写用户名,只是我的运气bob创建了一个新用户。 So I can add a boolean property to my user called IsBob 所以我可以为我的用户添加一个名为IsBob的布尔属性

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

Both just seem to smell funny to me. 这两件事对我来说似乎都很有趣。 And I can see what is going to happen, eventually I am going to start testing for Fred, and Ted also. 而且我可以看到将要发生的事情,最终我将开始测试弗雷德和泰德。 My code above will work, but I am certain there must be a cleaner solution. 我上面的代码可行,但我确信必须有一个更清洁的解决方案。

Thanks 谢谢

I would have Membership as a class that held default billing, etc. it would be a ton cleaner that a bunch of if's: 我会将会员资格作为一个持有默认账单的类,等等。如果是一堆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 a user does not want to pay for jan thorugh jun if they join in jul, you probably want to save some information about when membership expires on the user, and let the membership set this value on/after billing 由于用户不想为jan thorugh jun支付费用,如果他们加入jul,您可能希望保存一些有关用户何时到期的信息,并让会员在结算时/结账后设置此值

make another variation of the billing procedure: 进行结算程序的另一种变化:

public enum MembershipType
{
    MONTHLY,
    ANNUALLY,
    SPECIAL1
}

That way you can at least assign the same procedure to some other "Friends" 这样你至少可以为其他“朋友”分配相同的程序

添加某种优惠券代码机制,这样如果你需要为其他用户进行不同的计算,那么它的灵活性足以做到这一点。

What exactly does your IBillingStrategy do? 您的IBillingStrategy究竟做了什么?

Is it responsible for actually billing the user as well as calculating what they should be billed? 它是否负责实际向用户收费以及计算他们应该收取的费用?

If so I'd separate those responsibilities, introducing the concept of an Invoice and then allow user specific Discount to be applied to the generated Invoice before the User is actually billed. 如果是这样,我将这些责任分开,引入Invoice的概念,然后允许用户特定的DiscountUser实际开Invoice之前应用于生成的Invoice

I would probably combine the concepts of Membership and BillingStrategy (so Membership generate Invoices ), use a BillingAction to encapsulate HOW the user is billed (Credit Card, Mailed Invoice, Briefcase of Unmarked Bills) introduce the concept of Discounts (each User can have many Discounts ) to deal with the new requirement and wrap the whole thing up in a BillingService . 我可能会将MembershipBillingStrategy的概念结合起来(因此Membership生成Invoices ),使用BillingAction来封装用户如何收费(信用卡,邮寄发票,未标记票据的公文包)介绍Discounts的概念(每个User可以有很多Discounts )处理新的要求并将整个事情包装在BillingService

When hydrating a user from whatever store you have, I would give them an appropriate Membership (which in turn would be initialised with a set of Discounts and other information, like membership dates and whatnot) and an appropriate BillingAction . 当用户从您拥有的任何商店保湿时,我会给他们一个适当的Membership (反过来会使用一组Discounts和其他信息,如会员日期和诸如此类的信息进行初始化)和适当的BillingAction

Then as part of your billing process (maybe a nightly thing) you get the Users , push them through the BillingService , and underneath it generates Invoices and actions them using the Users BillingAction . 然后,作为结算过程的一部分(可能是夜间BillingService ),您将获得Users ,推送他们完成BillingService ,并在其下方生成Invoices并使用Users BillingAction对其进行操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM