3

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

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();
}

对我来说,两者都闻起来很有趣。我可以看到会发生什么,最终我将开始为 Fred 和 Ted 进行测试。我上面的代码可以工作,但我确信必须有一个更清洁的解决方案。

谢谢

4

4 回答 4

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 支付费用,如果他们在 7 月加入,您可能希望保存一些有关用户会员资格何时到期的信息,并让会员资格在计费时/之后设置此值

于 2014-08-26T08:18:46.427 回答
1

对计费程序进行另一种变化:

public enum MembershipType
{
    MONTHLY,
    ANNUALLY,
    SPECIAL1
}

这样,您至少可以将相同的程序分配给其他一些“朋友”

于 2014-08-26T08:17:11.767 回答
1

添加某种优惠券代码机制,这样如果您需要为其他用户进行不同的计算,那么它就足够灵活了。

于 2014-08-26T08:40:20.397 回答
0

您的 IBillingStrategy 究竟是做什么的?

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

如果是这样,我会将这些职责分开,引入 an 的概念,Invoice然后允许在实际计费之前将特定用户Discount应用于生成的。InvoiceUser

我可能会结合Membershipand的概念BillingStrategy(所以Membershipgenerate Invoices),使用 aBillingAction来封装用户的计费方式(Credit Card、Mailed Invoice、Briefcase of Unmarked Bills)引入Discounts(每个User可以有很多Discounts)的概念来处理新的需求并将整个事情包裹在一个BillingService.

当从您拥有的任何商店为用户补充水分时,我会给他们一个适当的Membership(反过来将使用一组Discounts和其他信息进行初始化,例如会员日期等等)和一个适当的BillingAction.

然后,作为计费流程的一部分(可能是每晚的事情),您将获得Users,将它们推送到BillingService,然后在它下面生成Invoices并使用Users BillingAction.

于 2014-08-26T09:14:42.657 回答