c#每个用户的策略模式

时间:2014-08-26 08:11:20

标签: c# design-patterns strategy-pattern code-structure

我有一个非常简单的场景。 我的网站用户可以是月度会员或年度会员

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

public enum MembershipType
{
    MONTHLY,
    ANNUALLY
}

然后根据会员资格,我采用不同的结算策略:

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

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

这非常简单直接。现在生意出现了,并说'我想要照顾我的朋友鲍勃,我希望你的计算方法与其他人略有不同!"

所以如果我继续这个模式,我可以制作一个BobBillingStrategy。然后我可以添加一些额外的逻辑,现在我有两种方法可以识别Bob

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

这很脏,因为我很难编写用户名,只是我的运气bob创建了一个新用户。所以我可以为我的用户添加一个名为IsBob

的布尔属性
if (user.IsBob)
{
     _billingStrategy = new BobBillingStrategy();
}

两者似乎对我来说都很有趣。而且我可以看到将要发生的事情,最终我将开始测试弗雷德和泰德。我上面的代码可行,但我确信必须有一个更清洁的解决方案。

由于

4 个答案:

答案 0 :(得分:2)

我会将会员资格作为一个持有默认账单的类别等等。这将是一堆更清洁的一堆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;

        }

}

然后,你和你的用户做了类似的事情:

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

也;由于用户不想为jan thorugh jun支付费用,如果他们加入jul,您可能希望保存一些关于会员资格何时到期的信息,并让会员在结算时/之后设置此值

答案 1 :(得分:1)

进行结算程序的另一种变体:

public enum MembershipType
{
    MONTHLY,
    ANNUALLY,
    SPECIAL1
}

这样你至少可以为其他“朋友”分配相同的程序

答案 2 :(得分:1)

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

答案 3 :(得分:0)

您的IBillingStrategy究竟做了什么?

是否负责实际向用户收费以及计算他们应该收取的费用?

如果是这样,我将这些责任分开,引入Invoice的概念,然后允许用户特定Discount应用于{{1}之前生成的Invoice实际上是收费的。

我可能会将UserMembership的概念结合起来(所以BillingStrategy生成Membership),使用Invoices来封装用户收费标准(信用卡,邮寄发票,无标记票据公文包)介绍BillingAction的概念(每个Discounts可以有许多User)来处理新要求并将整个事项包起来Discounts

当从你拥有的任何商店给用户保湿时,我会给他们一个合适的BillingService(反过来会用一组Membership初始化,以及其他信息,比如会员日期等等。和适当的Discounts

然后,作为结算过程的一部分(可能是夜间活动),您将获得BillingAction,将其推送到Users,然后在其下方生成BillingService并使用{ {1}} Invoices