c#每个用户的策略模式
我有一个非常简单的场景。 我的网站的用户可以是月度会员或年度会员c#每个用户的策略模式,c#,design-patterns,strategy-pattern,code-structure,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 IB
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();
}
这是非常直接和简单的。现在生意来了,说:“我想照顾我的朋友鲍勃,我想让你计算他的账单时和其他人略有不同!”
因此,如果我继续这种模式,我可以制定一个跳跃策略。然后我可以添加一些额外的逻辑,现在我有两种方法可以识别Bob
if (user.UserName.Equals("bob"))
{
_billingStrategy = new BobBillingStrategy();
}
这让我感觉很肮脏,因为我正在硬编码一个用户名,而我的运气就是bob创建了一个新用户。所以我可以向我的用户IsBob添加一个布尔属性
if (user.IsBob)
{
_billingStrategy = new BobBillingStrategy();
}
我觉得这两样东西都很好闻。我可以看到将会发生什么,最终我将开始测试弗雷德,还有泰德。我上面的代码可以工作,但我确信一定有更干净的解决方案
谢谢对计费程序进行另一种更改:
public enum MembershipType
{
MONTHLY,
ANNUALLY,
SPECIAL1
}
这样,您至少可以将相同的过程分配给其他一些“朋友”我将成为持有默认账单的类的成员,等等。如果有一堆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
还有,;由于如果用户在7月加入,则不想为jan thorugh jun付费,因此您可能希望在用户身上保存一些关于会员资格何时到期的信息,并让会员在计费时/计费后设置此值添加某种优惠券代码机制,因此,如果您需要为其他用户进行不同的计算,那么它足够灵活,可以执行相同的操作 你的IBillingStrategy到底是做什么的 它是否负责实际向用户计费以及计算用户应支付的费用 如果是这样,我会将这些责任分开,引入
发票
的概念,然后允许在实际向用户
计费之前,将特定于用户的折扣
应用到生成的发票
我可能会结合会员
和账单策略
(因此会员
生成发票
),使用账单操作
来封装用户的账单方式(信用卡、邮寄发票、未标记账单公文包)引入折扣的概念
(每个用户
可以有许多折扣
)来处理新的需求,并将整个过程打包成一个计费服务
当从您拥有的任何商店为用户补水时,我会给他们一个适当的会员资格
(这反过来会用一组折扣
和其他信息初始化,如会员日期等)和一个适当的账单操作
然后,作为计费过程的一部分(可能是每晚的事情),你得到
用户
,将他们推到计费服务
,然后在下面生成发票
,并使用用户
计费操作是的,就像这里回答的人一样,你只需要实现这些“好友策略”在代码中,但策略必须用于的确切用户应在数据库级别上进行配置。至少,这似乎是对我来说最不肮脏的解决方案。不建议使用枚举来存储成员资格类型。使成员资格成为动态的东西(请参阅我的答案)顺便说一句,有没有可能从另一个角度来看待这个问题?例如,不是为Bob添加新的IBillingStrategy
,而是添加新的业务对象,比如说,折扣
,可以为其他用户重复使用?这只是一个想法,我不知道你的确切问题。我对这个解决方案的问题是这么多年了在这条线上,未来的编码器将有更多的WTF/分钟时刻,因为“special1”是什么还不是很清楚。此外,它仍然失去了用户每月或每年一次的事实(这可能会影响其他地方的代码逻辑)只是一个输入错误:用户
不再是//与以前一样
,因为你必须持有账单策略
。在我看来,你似乎不必要地把会员资格方面的事情复杂化了,因为“//与以前一样”我指的是它的其他属性(名称和会员资格)。我不明白你怎么能说我不必要地使成员身份复杂化。我更愿意说,将不同类型的成员身份硬编码为一个枚举,然后使用一堆硬编码的if来检查该枚举,以更改一些与成员身份持续时间一样微不足道的内容,这会使事情更加复杂。对不起,我没有注意到BillingStrategy
属性,我完全不好。你将BillingStrategy
注入成员身份
,这意味着其他类必须控制该进程,或者你甚至需要一个新类来控制该进程。BillingStrategy
现在被注入到两个类中,需要更多的机制来支持它。我认为这是不必要的我很复杂。没问题。如果我看起来很暴躁,我很抱歉。太多咖啡+睡眠不足+饥饿=暴躁的程序员:PI编辑了我的评论。是的,硬编码很多ifs肯定比让成为一个类成员更糟糕,我非常同意你。